fix(release): publish cannot run gh release create --verify-tag without a checkout - #152
Conversation
…hout a checkout The first release this workflow ever performed failed here. `authorize` and `build` both succeeded; publication died with failed to run git: fatal: not a git repository (or any of the parent directories): .git `--verify-tag` makes `gh` shell out to git to confirm the tag exists locally, and the publish job deliberately never checks out code. That separation is the point of splitting publish from build -- it holds the only `contents: write` authority -- so the flag was asking a question the job is designed to be unable to answer. Nothing is lost by removing it. The two lines above the call already fetch the live tag ref through the API and assert it equals the object SHA `authorize` produced after verifying the tag's SSH signature against the committed allowed-signers file. That is an identity check; `--verify-tag` is only an existence check, and it was being made against a repository that is not there. A regression test pins all three facts together: publish still creates the release, does not pass `--verify-tag`, and does not check out code -- so re-adding the flag and adding a checkout to satisfy it both fail, and the second is the one worth refusing. This defect was reachable only by running the workflow. It had never run.
…infer one from (#153) Removing `--verify-tag` in #152 was **necessary and not sufficient**. Run `34164224595` failed at exactly the same step, with exactly the same message, after that flag was already gone: ``` failed to run git: fatal: not a git repository (or any of the parent directories): .git ``` ### Why `gh` determines which repository to act on from the **git remote**. The publish job deliberately never checks out code — it holds the only `contents: write` authority, which is why it is split from build — so there is no remote, and `gh release create` shells out to git looking for one before it does anything else. `GITHUB_REPOSITORY` is set in the environment, but **`gh` does not read it**. The variable it reads is `GH_REPO`. ### This portfolio had already solved it `self-osint-monitor` #25 is literally *"fix(ci): give `gh release create` the repo via `GH_REPO`"*. I rediscovered the same defect from scratch by running into it. That is worth recording in itself: the fix existed, in a sibling repo, and nothing surfaced it — which is an argument for the shared release workflow this repo now calls, not against it. ### Honest accounting of my own diagnosis I attributed the first failure entirely to `--verify-tag`. That flag *is* broken here for the same underlying reason, and removing it was right, but I stated a complete cause when I had only found one contributor. The test now pins `GH_REPO` alongside the no-checkout and no-`--verify-tag` assertions, so the incomplete version of this fix cannot be mistaken for the complete one again. ### Verified 21 tests pass. **Negative control:** stripping the `GH_REPO` line fails exactly `test_the_publish_job_does_not_ask_git_a_question_it_cannot_answer` and nothing else. The first restore left the file differing from the tested state — I had reinserted the line without its comment block — so it was rebuilt from the branch point and re-applied, and `git hash-object` confirms the committed file is the one the tests ran against. *Prepared with AI assistance; reviewed before submission.*
|
Correcting this PR after the fact: its stated cause was wrong, and it removed a check that was never broken. This PR removed The evidence against my theory was already in hand when I wrote it: run The single cause of both failures is that #153 restores This was caught by another agent reading Prepared with AI assistance; reviewed before submission. |
The first release this workflow ever performed failed here.
authorizesucceeded,buildsucceeded, and publication died with:gh release create --verify-tagshells out to git to confirm the tag exists locally. The publish job deliberately never checks out code — that separation is the point of splitting it from build, since it holds the onlycontents: writeauthority. So the flag was asking a question the job is designed to be unable to answer.Nothing is lost by removing it
The two lines immediately above the call already do something strictly stronger:
TAG_OBJECT_SHAcomes fromauthorize, which produced it after verifying the tag's SSH signature against the committed allowed-signers file. So that is an identity check against the live repository.--verify-tagis only an existence check — and it was being made against a working tree that is not there.The alternative I did not take
Adding
actions/checkoutto the publish job would also make the flag work, and would be the wrong fix: it puts a working tree in the one job holding write authority, to satisfy a weaker version of a check that already passes. The regression test pins all three facts together — publish still creates the release, does not pass--verify-tag, and does not check out code — so both regressions fail, and the second one fails with an explanation of why it is refused.Verified
21 tests pass. Negative control: re-adding
--verify-tagfails exactlytest_the_publish_job_does_not_ask_git_a_question_it_cannot_answerand nothing else. Restoring afterward initially left the file matchingorigin/mainrather than my edit —git checkout --restores to the branch point, not to uncommitted work — so the fix was re-applied and confirmed byte-identical to the tested state bygit hash-objectbefore committing.Why this was never found before
This defect is reachable only by running the workflow, and this workflow had never run. It could not: it called a reusable workflow from a private repo, which a public repo cannot read, so every dispatch failed at parse time. #151 fixed that; this is the next thing standing between
v0.1.0and a published release.Prepared with AI assistance; reviewed before submission.