From 4a86987fc3dac6fe4d6ce5b34fe75ae659b96621 Mon Sep 17 00:00:00 2001 From: zhanghanduo Date: Thu, 3 Sep 2026 19:22:15 +0800 Subject: [PATCH] fix(release): name the repository for the GitHub Release job MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The publish-github job downloads artifacts and never checks out the repository, so `gh release` had no git remote to infer its target from and failed with "fatal: not a git repository". This is what happened on v0.3.0: PyPI published successfully and the GitHub Release had to be created by hand. The failure is not recoverable by rerunning the job. A rerun replays the workflow definition at the tag, so fixing main does not fix a tag already pushed — and the PyPI version number is consumed by then and can never be reused, so retagging is not an option either. Set GH_REPO explicitly rather than adding a checkout: the job needs the artifacts and nothing else from the repository. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/release.yml | 4 ++++ tests/test_release_automation.py | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2416466..c3d6f94 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -119,3 +119,7 @@ jobs: env: TAG: ${{ github.ref_name }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # This job downloads artifacts and never checks out the repository, so + # `gh` has no git remote to infer the target from and fails with + # "not a git repository". Name it explicitly. + GH_REPO: ${{ github.repository }} diff --git a/tests/test_release_automation.py b/tests/test_release_automation.py index f74a0b0..52966f5 100644 --- a/tests/test_release_automation.py +++ b/tests/test_release_automation.py @@ -163,3 +163,21 @@ def test_license_is_declared_as_an_spdx_expression() -> None: assert project["license"] == "Apache-2.0" assert project["license-files"] == ["LICENSE"] assert not [c for c in project["classifiers"] if c.startswith("License ::")] + + +def test_github_release_job_names_the_repository_explicitly() -> None: + """The GitHub Release job never checks out the repository. + + Without GH_REPO, `gh release` tries to infer the target from a git remote + and dies with "not a git repository". That failure is not recoverable by + rerunning: a rerun replays the workflow definition at the tag, and by then + PyPI has already published the version — which can never be reused. This + happened on v0.3.0; the release had to be created by hand. + """ + workflow = yaml.safe_load(_release_workflow()) + job = workflow["jobs"]["publish-github"] + + assert not any("checkout" in str(step.get("uses", "")) for step in job["steps"]) + + publish = next(s for s in job["steps"] if s.get("name") == "Publish GitHub Release") + assert publish["env"]["GH_REPO"] == "${{ github.repository }}"