Start from a clean checkout at main.
Before running through the release it's good to run the build and the tests locally, and make sure CI is passing. You can also test-drive the commit in an existing Bazel workspace to sanity check functionality.
Releases are managed using a semi-automated process centered around a GitHub Release Tracking Issue and automated workflows triggered by comments or issue edits.
Note
Comment-based commands must be posted by project maintainers (Owner, Member, or Collaborator) and must be on their own line (leading and trailing whitespace is ignored).
-
Prepare the Release: Run the Release: Prepare workflow manually. You can trigger it from the GitHub Actions UI or using the GitHub CLI:
gh workflow run release_prepare.yaml --repo bazel-contrib/rules_python
This will automatically determine the next version, create a release tracking issue, and send a preparation PR.
-
Approve and Merge: Approve and merge the PR. Once merged, a release branch will be created automatically.
-
Add Backports (if needed): If there are backports, add them following the How to add backports steps.
-
Create an RC: Comment
/create-rcon the tracking issue. This will automatically process pending backports before creating the RC. If any backport fails, the RC creation will abort. -
Iterate: Repeat steps 3 and 4 until backports and RCs are no longer needed.
-
Finalize the Release: Comment
/promoteon the tracking issue to finalize the release.
The release workflow can be manually triggered using the GitHub CLI (gh).
This is useful for re-running a release or for creating a release from a
specific commit.
To trigger the workflow, use the gh workflow run command:
gh workflow run release_publish.yaml --ref <TAG>By default, the workflow will publish the wheel to PyPI. To skip this step,
you can set the publish_to_pypi input to false:
gh workflow run release_publish.yaml --ref <TAG> -f publish_to_pypi=falseIf PyPI publishing failed or was skipped during the main release, the PyPI
publishing workflow can be triggered manually using the GitHub CLI (gh) or
via the GitHub Actions UI:
gh workflow run publish_pypi.yaml --ref <TAG> -f tag_name=<TAG>rules_python uses semantic version, so releases with API changes and new features bump the minor, and those with only bug fixes and other minor changes bump the patch digit.
The release tool will automatically determine the next version number based on
the VERSION_NEXT_* placeholders in the codebase. To see what changes are
being accumulated for the next release, review the pending news entries in the
news/ directory.
To add backports to an active release, you can use one of the following methods:
Comment /backport on the PR you wish to backport. This will automatically
add the PR to the active release's backports checklist. Once the PR is merged,
the backports will be automatically processed.
Note
Commenting /backport on an open PR will block further release publishing
(like creating RCs or promoting) until the PR is merged or manually set to
status=ignore in the checklist.
Comment /add-backports <PR_REF> [<PR_REF> ...] (space or comma separated) on
the tracking issue. The <PR_REF> can be a PR number (optionally prefixed with
#) or a PR URL (strictly for the configured repository). This will
automatically add the PRs to the checklist and trigger processing.
- Manually add checklist items under the
## Backportssection of the Release Tracking Issue. The format must be:- [ ] #<PR_NUMBER>(e.g.,- [ ] #1234). - When ready, comment
/process-backportson the tracking issue to trigger processing.
You can use the release tool to add backports from your local checkout:
bazel run //tools/private/release -- add-backports <PR_REF> [<PR_REF> ...]The <PR_REF> can be:
- A PR number (e.g.,
124or#124) - A PR URL (e.g.,
https://github.com/bazel-contrib/rules_python/pull/124orhttps://github.com/bazel-contrib/rules_python/pull/124/files) - Only URLs for the configured repository are accepted.
If a backport fails to process (e.g., due to cherry-pick conflicts):
- The failed backport checklist item will remain unchecked with
status=error-<reason>. - You must resolve the conflict manually: checkout the release branch,
cherry-pick the PR, resolve conflicts, push to remote, and manually check
the box on the tracking issue checklist with
status=donemetadata.
If you need to backport a PR to multiple older active release branches (e.g.,
backporting a fix to 1.7, 1.8, and 1.9 when the latest release is
2.2.0), you can automate the creation of release tracking issues and
verification of cherry-picks using a Backport Tracking Issue.
-
Create a Backport Tracking Issue: Create a new issue on GitHub with the label
type: backport-pr.- The title should describe the backport, e.g.,
Backport: #1234(referencing the PR to backport). - The body must contain the target range in the following format:
This tells the tool to target all active release branches between
* PR: #1234 * From version: 1.7 * To version: 2.2
release/1.7andrelease/2.2inclusive.
- The title should describe the backport, e.g.,
-
Prepare the Backports: Trigger the preparation by commenting
/prepareon the backport tracking issue, or by manually running the Backport: Prepare workflow with the issue number.- The workflow will checkout each release branch in the range, attempt to cherry-pick the PR, and verify if the changelog can be updated.
- It will then update the backport tracking issue body with a list of
tasks:
Verify apply <minor_version>: Automatically checked if the cherry-pick succeeded, or left unchecked withstatus=failed-conflictorstatus=failed-changelogif it failed.Release issue <next_version>: A task to initiate the release for each target version.
-
Resolve Conflicts (if any): If any
Verify applytask failed:- You must resolve the conflict manually on that specific release branch (checkout branch, cherry-pick, resolve conflicts, push to remote).
- Once resolved, manually check the corresponding
Verify applytask box on the tracking issue and set its metadata tostatus=success(e.g.,- [x] Verify apply 1.8 | status=success).
-
Initiate Releases: Once all
Verify applytasks are successful (either automatically or after manual resolution), comment/create-releaseson the backport tracking issue, or manually run the Backport: Create Releases workflow.- This will automatically create a standard Release Tracking Issue for
each target version (e.g.,
Release 1.7.1,Release 1.8.1, etc.). - For patch releases, the created release tracking issues will have
Tag RCtasks automatically removed, as release candidates are not required for patch releases. - The backport PR will be automatically added to the checklist of each created release tracking issue.
- This will automatically create a standard Release Tracking Issue for
each target version (e.g.,
-
Execute Releases: Follow the standard release process for each created release tracking issue. Since these are patch releases, you can skip the
/create-rcstep and comment/promotedirectly to tag and publish the release from the release branch head.
If a patch release from head would contain changes that aren't appropriate for a patch release, then the patch release needs to be based on the original release tag and the patch changes cherry-picked into it.
In this example, release 0.37.0 is being patched to create release 0.37.1.
The fix being included is commit deadbeef.
git checkout release/0.37git cherry-pick -x deadbeef- Fix merge conflicts, if any.
git cherry-pick --continue(if applicable)git push upstream
If multiple commits need to be applied, repeat the git cherry-pick step for
each.
Once the release branch is in the desired state, comment /create-rc on the
tracking issue to tag it, as done with a release from head.
We announce releases in the #python channel in the Bazel slack (bazelbuild.slack.com). Here's a template:
Greetings Pythonistas,
rules_python X.Y.Z-rcN is now available
Changelog: https://rules-python.readthedocs.io/en/X.Y.Z-rcN/changelog.html#vX-Y-Z
It will be promoted to stable next week, pending feedback.
It's traditional to include notable changes from the changelog, but not required.
Re-releasing a version (i.e. changing the commit a tag points to) is sometimes possible, but it depends on how far into the release process it got.
The two points of no return are:
- If the PyPI package has been published: PyPI disallows using the same filename/version twice. Once published, it cannot be replaced.
- If the BCR package has been published: Once it's been committed to the BCR registry, it cannot be replaced.
If release steps fail prior to those steps, then its OK to change the tag. You may need to manually delete the GitHub release.
You can manually edit the Release Tracking Issue to control the release flow.
The checklist items use metadata suffix: | key=value key2=value2.
- Retry Prepare Release: Reset the task to
- [ ] Prepare Release | status=awaiting-preparation. - Force Task Done: Check the box
- [x]and add appropriate metadata (e.g.status=done).
Part of the release process uploads packages to PyPI as the user rules-python.
This account is managed by rickeylev. Note that Google also has recovery access
and can be contacted at rules-python-pypi@google.com if something needs to be
done with the PyPI account.