If pyproject.toml already carries that version — a re-run of a release, or a version corrected by hand — nothing is staged, git commit exits non-zero, and set -euo pipefail fails the job. By that point the image has already been pushed, so the release is half-done: published container, no tag. The next run then computes the same version again from the same commits.
The fix
Skip the commit and its branch push when there is nothing staged; tag either way.
Verification
The step was extracted from the workflow and run against a scratch repository with a real origin:
VERSION equal to the file's version → logs pyproject.toml is already at 0.1.0, pushes the tag, no commit.
VERSION different → commits chore(release): v0.2.0, pushes the branch, then the tag.
Both paths leave main and the tags consistent. bash -n clean.
Found while porting this same release scheme to music-mirror, which carries the guarded version from the start.
## The defect
The release step added in #17 commits the computed version unconditionally:
```sh
git add pyproject.toml
git commit -m "chore(release): v${VERSION}"
```
If `pyproject.toml` already carries that version — a re-run of a release, or a version corrected by hand — nothing is staged, `git commit` exits non-zero, and `set -euo pipefail` fails the job. By that point the image has already been pushed, so the release is half-done: published container, no tag. The next run then computes the same version again from the same commits.
## The fix
Skip the commit and its branch push when there is nothing staged; tag either way.
## Verification
The step was extracted from the workflow and run against a scratch repository with a real `origin`:
- `VERSION` equal to the file's version → logs `pyproject.toml is already at 0.1.0`, pushes the tag, no commit.
- `VERSION` different → commits `chore(release): v0.2.0`, pushes the branch, then the tag.
Both paths leave `main` and the tags consistent. `bash -n` clean.
Found while porting this same release scheme to `music-mirror`, which carries the guarded version from the start.
The release step added in #17 commits the computed version unconditionally. If
pyproject.toml already carries that version -- a re-run of a release, or a
version corrected by hand -- there is nothing staged and `git commit` exits
non-zero, failing the job after the image has already been pushed and before
the tag is created.
Skip the commit and its push in that case, and tag either way.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
The defect
The release step added in #17 commits the computed version unconditionally:
If
pyproject.tomlalready carries that version — a re-run of a release, or a version corrected by hand — nothing is staged,git commitexits non-zero, andset -euo pipefailfails the job. By that point the image has already been pushed, so the release is half-done: published container, no tag. The next run then computes the same version again from the same commits.The fix
Skip the commit and its branch push when there is nothing staged; tag either way.
Verification
The step was extracted from the workflow and run against a scratch repository with a real
origin:VERSIONequal to the file's version → logspyproject.toml is already at 0.1.0, pushes the tag, no commit.VERSIONdifferent → commitschore(release): v0.2.0, pushes the branch, then the tag.Both paths leave
mainand the tags consistent.bash -nclean.Found while porting this same release scheme to
music-mirror, which carries the guarded version from the start.