ci: make the release workflow safe to trigger - #45
Open
vkruoso wants to merge 1 commit into
Open
Conversation
A version can only be uploaded to PyPI once, so the release has to be ordered and guarded around that step. - trigger on the bare tags this project has always used, as well as on prefixed ones, so a release is not silently skipped - check that the tag matches the version in receita/__init__.py before anything is published, since the version comes from that file and not from the tag - publish to PyPI only after the image is pushed, as an image tag can be replaced but a PyPI version cannot - keep the latest image tag on final releases only
There was a problem hiding this comment.
🟢 Approval recommended
The workflow changes match the stated release-safety requirements and do not introduce any clear functional or operational blockers.
Pull request overview
This PR hardens the GitHub Actions release pipeline so tagging 3.0.0 reliably triggers a release, validates the tag against the packaged version, and prevents irreversible publishing from happening before reversible steps (Docker push).
Changes:
- Expand tag trigger patterns to support both bare tags (
3.0.0) andv-prefixed tags (v3.0.0). - Add a CI check that fails early when the pushed tag doesn’t match
receita/__init__.py’s__version__. - Serialize release steps by making PyPI publish depend on the Docker job, and prevent
latestfrom moving on pre-release tags.
File summaries
| File | Description |
|---|---|
| .github/workflows/release.yml | Makes release triggering/version validation stricter and orders Docker before PyPI to avoid unrecoverable releases. |
Review details
- Files reviewed: 1/1 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+27
to
+33
| version=$(sed -n 's/^__version__ = "\(.*\)"$/\1/p' receita/__init__.py) | ||
| tag=${GITHUB_REF_NAME#v} | ||
| echo "tag: $GITHUB_REF_NAME package version: $version" | ||
| if [ "$tag" != "$version" ]; then | ||
| echo "::error::tag $GITHUB_REF_NAME does not match the version $version in receita/__init__.py" | ||
| exit 1 | ||
| fi |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The release workflow needed fixing before
3.0.0is tagged. Each item below would have caused a broken or unrecoverable release.The tag pattern did not match this project
The workflow triggered on
v*, but every tag in this repository is bare:1.0,2.0.2,2.0.3,2.1.1,2.2.0. Tagging3.0.0would have matched nothing and the release would have been silently skipped, with no run and no error. It now triggers on[0-9]*andv[0-9]*, so either form works.The tag was not checked against the packaged version
The version is read from
receita/__init__.pythrough[tool.setuptools.dynamic], so the tag has no effect on what gets built. Taggingv3.0.0-rc1as a trial run would have uploaded the real3.0.0to PyPI, and that version could never be uploaded again. Thetestjob now compares the tag against the file and fails before anything is published:The irreversible step could run before the reversible one
publishanddockerboth depended only ontest, so they ran in parallel. If PyPI succeeded and the image push failed,3.0.0could not be published again and the only way forward would be a version bump for a problem unrelated to the package.publishnow depends ondocker: an image tag can be overwritten, a PyPI version cannot, so the step that cannot be repeated runs last.The latest image tag moved for pre-releases
type=raw,value=latestapplied to any tag, so a pre-release would have becomelateston Docker Hub. It is now limited to tags without a suffix.