Skip to content

Publish to PyPI on tag push and guard VERSION against the tag - #7165

Merged
albertvillanova merged 3 commits into
mainfrom
guard-release-version
Sep 14, 2026
Merged

albertvillanova merged 3 commits into
mainfrom
guard-release-version

Conversation

@albertvillanova

@albertvillanova albertvillanova commented Sep 10, 2026

Copy link
Copy Markdown
Member

This PR makes it impossible to publish a version of TRL that was never tagged as a release, and rejects a post-release version bump that is not a dev version.

Motivation

v1.12.0 on PyPI is an accidental duplicate of v1.11.0. The publish workflow fired on any push to main touching VERSION and skipped the upload only when the version contained "dev", so a post-release bump that set VERSION to 1.12.0 instead of 1.12.0.dev0 uploaded a release 90 seconds after 1.11.0, with identical code. The version number is burned, since PyPI does not allow re-uploading it.

Two things went wrong: publishing was a side effect of editing a file rather than a deliberate act, and nothing checked that the published version corresponded to a release.

Solution

Publishing is now triggered by the release tag, and the job refuses to upload unless VERSION in the tagged commit is a release version equal to the tag. A separate check runs on pull requests that touch VERSION, and rejects a change from one release version to another: on main, VERSION is a release version only between the release pull request and the post-release bump, so that bump must carry a .dev suffix.

Applied to the history, the bump that produced 1.12.0 fails the pull request check, and even if it were merged, no upload would follow.

Changes

  • Trigger Publish to PyPI on v* tag pushes instead of pushes touching VERSION
  • Refuse to publish unless VERSION is {major}.{minor}.{patch} and equals the tag, replacing the "dev" substring check
  • Add a Version Check workflow on pull requests to main touching VERSION, validating the version format and requiring a dev version after a release version
  • Update RELEASE.md: merging the release pull request no longer publishes, pushing the tag does, and the .dev0 suffix in the bump step is mandatory

Note

Medium Risk
Changes how packages reach PyPI; mis-tagging or workflow mistakes could block releases, but runtime library code is unaffected.

Overview
PyPI publishing is no longer tied to merging or pushing VERSION on main. The Publish to PyPI workflow now runs only on v* tag pushes and fails the job unless VERSION is a strict {major}.{minor}.{patch} release and matches the tag (v$version), replacing the old "dev" substring gate.

A new Version Check workflow runs on PRs to main that change VERSION, enforcing valid release or .dev{n} formats and blocking a bump from one release version to another (post-release bumps must use .dev).

RELEASE.md is updated so merge no longer implies publish, tag push does, tagging must happen before the dev bump, and the .dev0 suffix on the post-release bump is documented as required by CI.

Reviewed by Cursor Bugbot for commit a528085. Bugbot is set up for automated code reviews on this repo. Configure here.

@bot-ci-comment

Copy link
Copy Markdown

The docs for this PR live here. All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update.

@qgallouedec qgallouedec left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks lgtm, it's hard to try this easily, I guess we will see in the next release!

From what I understand it's the right shape

Dropping the v*-release branch trigger shouldn't lose patch releases, since tags aren't branch-scoped and a v* tag on a release branch should still fires.

LGTM.

run: |
version=$(cat VERSION)
echo "VERSION is $version, tag is $GITHUB_REF_NAME"
if [[ ! "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

having rc in this repo is sufficiently rare to keep this as is

@albertvillanova albertvillanova Sep 14, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed on rc, v1.0.0rc1 is the only non-vX.Y.Z tag out of 97 in the repo's history, and relaxing the regex to allow an rc suffix is a one-line change the day we want one.

Keeping the strict form mainly protects the dev case. With the tag trigger, git tag "v$(cat VERSION)" run on a dev main produces v1.14.0.dev0, where tag and VERSION agree, so only the format check refuses it. And a failing check beats the old if: ${{ !contains(steps.get_version.outputs.version, 'dev') }}, which skipped the upload and left the job green: the run for #6938 that published the duplicate 1.12.0 and the run for #7160 that correctly uploaded nothing are both "success" and indistinguishable.

@albertvillanova
albertvillanova merged commit 5354bc7 into main Sep 14, 2026
10 checks passed
@albertvillanova
albertvillanova deleted the guard-release-version branch September 14, 2026 14:45
@albertvillanova albertvillanova added the 🔧 maintenance CI, tooling, tests, or repo upkeep label Sep 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🔧 maintenance CI, tooling, tests, or repo upkeep

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants