From b43e2a0ecffb6473093ad0904967cd0da2f1e59e Mon Sep 17 00:00:00 2001 From: Michael Park Date: Fri, 14 Aug 2026 12:30:44 +1000 Subject: [PATCH] fix: release id parsing for external release targets --- .../opencode-release-project-review.yml | 20 +++++++++++++------ docs/configuration-reference.md | 2 +- ...test_run_agentic_release_project_review.py | 6 ++++++ 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/.github/workflows/opencode-release-project-review.yml b/.github/workflows/opencode-release-project-review.yml index 2ed0b18..c580283 100644 --- a/.github/workflows/opencode-release-project-review.yml +++ b/.github/workflows/opencode-release-project-review.yml @@ -18,10 +18,14 @@ on: # repository by the runtime expression below. default: '' release_id: - description: Positive GitHub release ID. Exactly one of release_id/release_tag is required. - type: number + description: Positive decimal GitHub release ID. Exactly one of release_id/release_tag is required. + # Workflow-job outputs, including IDs returned by `gh api`, are + # strings. Accept that transport representation so dispatch wrappers + # can forward a discovered ID; resolve_invocation.py validates it as a + # positive integer before the release is fetched. + type: string required: false - default: 0 + default: '' release_tag: description: Conservative release tag selector. Exactly one of release_id/release_tag is required. type: string @@ -68,10 +72,14 @@ on: # workflow input default. Callers must explicitly pass their target. required: true release_id: - description: Positive GitHub release ID. Exactly one of release_id/release_tag is required. - type: number + description: Positive decimal GitHub release ID. Exactly one of release_id/release_tag is required. + # Workflow-job outputs, including IDs returned by `gh api`, are + # strings. Accept that transport representation so dispatch wrappers + # can forward a discovered ID; resolve_invocation.py validates it as a + # positive integer before the release is fetched. + type: string required: false - default: 0 + default: '' release_tag: description: Conservative release tag selector. Exactly one of release_id/release_tag is required. type: string diff --git a/docs/configuration-reference.md b/docs/configuration-reference.md index 2f892ce..1298db7 100644 --- a/docs/configuration-reference.md +++ b/docs/configuration-reference.md @@ -31,7 +31,7 @@ Fields not applicable to the selected workflow are rejected. | `pull_number` | number | PR review | `0` | Optional positive PR number when no pull-request event provides the target, such as a wrapper invoked with `workflow_call`. | | `issue_number` | number | Issue feedback | `0` | Optional positive issue number when no issue event provides the target. | | `target_repository` | string | Release project review | `${{ github.repository }}` | Strict canonical `owner/repo` of the release to review. Rejects URLs, `owner/repo@ref`/`owner/repo:ref` syntax, paths, and expressions. | -| `release_id` | number | Release project review | `0` | Positive GitHub release ID. Exactly one of `release_id`/`release_tag` is required. | +| `release_id` | string | Release project review | Empty | Positive decimal GitHub release ID. The reusable workflow accepts a string because workflow-job outputs are strings; it validates the value as a positive integer. Exactly one of `release_id`/`release_tag` is required. | | `release_tag` | string | Release project review | Empty | Conservative tag selector (`[A-Za-z0-9._-]{1,128}`, no `..`). Resolved through the GitHub REST API; never used as a Git ref. Exactly one of `release_id`/`release_tag` is required. | | `release_target_token` | secret | Release project review | Optional | Target-scoped GitHub token (`contents: read`, `issues: write` on the target only) for cross-repository reviews. Falls back to `github.token` for same-repo runs. | diff --git a/tests/test_run_agentic_release_project_review.py b/tests/test_run_agentic_release_project_review.py index 5ee9191..3f46252 100644 --- a/tests/test_run_agentic_release_project_review.py +++ b/tests/test_run_agentic_release_project_review.py @@ -1598,6 +1598,12 @@ def test_release_workflow_yaml_parses_and_uses_pinned_actions(self) -> None: target_input = triggers["workflow_call"]["inputs"]["target_repository"] self.assertTrue(target_input["required"]) self.assertNotIn("default", target_input) + # Job outputs are strings, so reusable wrappers that discover a + # release through the API can forward the output without GitHub's + # number-input schema rejecting it during workflow evaluation. + release_id_input = triggers["workflow_call"]["inputs"]["release_id"] + self.assertEqual(release_id_input["type"], "string") + self.assertEqual(release_id_input["default"], "") # validate_only exits before resolve-only fetch and both checkouts. self.assertIn("steps.resolve.outputs.validate_only != 'true'", text) self.assertIn("steps.resolve.outputs.validate_only == 'true'", text)