Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 9 additions & 34 deletions .github/ISSUE_TEMPLATE/release_tracking_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,46 +12,21 @@ labels: ['type: release']

## Backports

<details>
<summary><b>How to add backports</b></summary>

To request a backport:
1. Add a new checklist item under the `## Backports` section.
2. The format must be: `- [ ] #<PR_NUMBER>` (e.g., `- [ ] #1234`).
3. Trigger the [Process Backports Workflow][process_backports].
</details>
To request a backport, add it to the checklist below and process it. See [RELEASING.md: How to add backports](https://github.com/bazel-contrib/rules_python/blob/main/RELEASING.md#how-to-add-backports) for details.

---
*Maintainers: Automation will react to changes on this issue.*

<details>
<summary><b>Manual Editing</b></summary>

You can manually edit this issue to control the release flow.
The checklist items use metadata suffix: `| key=value key2=value2`.
- **Retry Prepare Release**: Reset to `- [ ] Prepare Release | status=awaiting-preparation`.
- **Force Task Done**: Check the box `- [x]` and add appropriate metadata (e.g. `status=done`).
</details>
To manually control the release flow, see the [RELEASING.md: Manual Editing](https://github.com/bazel-contrib/rules_python/blob/main/RELEASING.md#manual-editing-of-tracking-issue) section.

<details>
<summary><b>Available Commands</b></summary>

Maintainers can trigger automation by:
- Running manual workflows:
- [Process Backports Workflow][process_backports]
- [Create RC Workflow][create_rc]
- [Promote RC to Final Release Workflow][promote_rc]
- Commenting on this issue (requires the issue to have the `type: release`
label):
- `/prepare` at the beginning of a line to trigger the Release Prepare
workflow.
- `/create-rc` at the beginning of a line to trigger the Create RC
workflow.
- `/process-backports` at the beginning of a line to trigger the Process
Backports workflow.
Comment commands:
- `/prepare`: Determines version, creates tracking issue and preparation PR.
- `/create-rc`: Tags and publishes a new release candidate (RC).
- `/process-backports`: Cherry-picks pending backports.
- `/add-backports <PRs>`: Adds PRs to the backports and processes backports.
- `/promote`: Promotes the latest RC to final release.

See [RELEASING.md](https://github.com/bazel-contrib/rules_python/blob/main/RELEASING.md) for details on how to use them.
</details>

[process_backports]: https://github.com/bazel-contrib/rules_python/actions/workflows/release_process_backports.yaml
[create_rc]: https://github.com/bazel-contrib/rules_python/actions/workflows/release_create_rc.yaml
[promote_rc]: https://github.com/bazel-contrib/rules_python/actions/workflows/release_promote_rc.yaml
37 changes: 36 additions & 1 deletion .github/workflows/on_issue_comment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,41 @@ jobs:
outputs:
command: ${{ steps.parse.outputs.command }}
issue_number: ${{ github.event.issue.number }}
backports: ${{ steps.parse.outputs.backports }}
steps:
- name: Parse comment
id: parse
env:
COMMENT_BODY: ${{ github.event.comment.body }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
if echo "$COMMENT_BODY" | grep -qE '^[[:space:]]*/create-rc([[:space:]]|$)'; then
echo "command=create-rc" >> "$GITHUB_OUTPUT"
elif echo "$COMMENT_BODY" | grep -qE '^[[:space:]]*/prepare([[:space:]]|$)'; then
echo "command=prepare" >> "$GITHUB_OUTPUT"
elif echo "$COMMENT_BODY" | grep -qE '^[[:space:]]*/process-backports([[:space:]]|$)'; then
echo "command=process-backports" >> "$GITHUB_OUTPUT"
elif echo "$COMMENT_BODY" | grep -qE '^[[:space:]]*/add-backports([[:space:]]|$)'; then
args=$(echo "$COMMENT_BODY" | grep -E '^[[:space:]]*/add-backports([[:space:]]|$)' | sed -E 's/^[[:space:]]*\/add-backports[[:space:]]*//')
# Strip leading/trailing spaces and commas
args=$(echo "$args" | sed -e 's/^[[:space:],]*//' -e 's/[[:space:],]*$//')
# Replace internal spaces/commas with single comma
csv=$(echo "$args" | sed -E 's/[[:space:],]+/ /g' | tr ' ' ',')
if [ -n "$csv" ]; then
echo "command=add-backports" >> "$GITHUB_OUTPUT"
echo "backports=$csv" >> "$GITHUB_OUTPUT"
else
echo "command=none" >> "$GITHUB_OUTPUT"
echo "Error: No PRs specified for add-backports." >&2
gh api \
--method POST \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
/repos/${{ github.repository }}/issues/comments/${{ github.event.comment.id }}/reactions \
-f "content=-1"
fi
elif echo "$COMMENT_BODY" | grep -qE '^[[:space:]]*/promote([[:space:]]|$)'; then
echo "command=promote" >> "$GITHUB_OUTPUT"
else
echo "command=none" >> "$GITHUB_OUTPUT"
fi
Expand All @@ -61,8 +84,20 @@ jobs:

call_process_backports:
needs: parse_comment
if: needs.parse_comment.outputs.command == 'process-backports'
if: |
needs.parse_comment.outputs.command == 'process-backports' ||
needs.parse_comment.outputs.command == 'add-backports'
uses: ./.github/workflows/release_process_backports.yaml
with:
issue: ${{ needs.parse_comment.outputs.issue_number }}
add_backports: ${{ needs.parse_comment.outputs.command == 'add-backports' && needs.parse_comment.outputs.backports || '' }}
comment_id: "${{ github.event.comment.id }}"
secrets: inherit

call_promote:
needs: parse_comment
if: needs.parse_comment.outputs.command == 'promote'
uses: ./.github/workflows/release_promote_rc.yaml
with:
issue: ${{ needs.parse_comment.outputs.issue_number }}
secrets: inherit
31 changes: 29 additions & 2 deletions .github/workflows/release_process_backports.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,28 @@ on:
description: 'The Release Tracking Issue Number (e.g., 142)'
required: true
type: string
add_backports:
description: 'CSV list of PR numbers to add and process (optional)'
required: false
type: string
comment_id:
description: 'The ID of the comment that triggered this run (optional)'
required: false
type: string
workflow_call:
inputs:
issue:
description: 'The Release Tracking Issue Number (e.g., 142)'
required: true
type: string
add_backports:
description: 'CSV list of PR numbers to add and process (optional)'
required: false
type: string
comment_id:
description: 'The ID of the comment that triggered this run (optional)'
required: false
type: string

permissions:
contents: write
Expand Down Expand Up @@ -40,7 +56,18 @@ jobs:
- name: Process Pending Backports
run: |
bazel run //tools/private/release -- \
process-backports --issue ${{ inputs.issue }} --remote origin --no-dry-run
ARGS=()
if [ -n "${{ inputs.add_backports }}" ]; then
ARGS+=("--add=${{ inputs.add_backports }}")
fi
if [ -n "${{ inputs.comment_id }}" ]; then
ARGS+=("--triggering-comment=${{ inputs.comment_id }}")
fi
bazel run //tools/private/release -- process-backports \
--issue ${{ inputs.issue }} \
--remote origin \
--no-dry-run \
"${ARGS[@]}"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
23 changes: 21 additions & 2 deletions .github/workflows/release_promote_rc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ on:
description: 'The final version to release (e.g., 0.38.0)'
required: true
type: string
workflow_call:
inputs:
version:
description: 'The final version to release (e.g., 0.38.0)'
required: false
type: string
issue:
description: 'The tracking issue number'
required: true
type: string

permissions:
contents: write
Expand All @@ -33,7 +43,16 @@ jobs:

- name: Run Promote RC
run: |
bazel run //tools/private/release -- \
promote-rc ${{ inputs.version }} --remote origin
ARGS=()
if [ -n "${{ inputs.version }}" ]; then
ARGS+=("${{ inputs.version }}")
fi
if [ -n "${{ inputs.issue }}" ]; then
ARGS+=("--issue" "${{ inputs.issue }}")
fi
ARGS+=("--remote" "origin")
ARGS+=("--no-dry-run")

bazel run //tools/private/release -- promote-rc "${ARGS[@]}"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
113 changes: 66 additions & 47 deletions RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,54 +8,40 @@ existing Bazel workspace to sanity check functionality.

## Releasing from HEAD

These are the steps for a regularly scheduled release from HEAD.
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).

### Steps

1. Update the changelog and replace the version placeholders by running the
release tool. The next version number will be automatically determined
based on the presence of `VERSION_NEXT_*` placeholders and git tags. The
tool will read all news entry files in the `news/` directory, assemble
them into the changelog, and delete the processed news files.

```shell
bazel run //tools/private/release
```

If you want to append news entries to an already existing release section in
the changelog (for example, to update a drafted release or a release
branch), you can specify the version explicitly:

```shell
bazel run //tools/private/release -- X.Y.Z
```

1. Send these changes for review and get them merged.
1. Create a branch for the new release, named `release/X.Y`
```
git branch --no-track release/X.Y upstream/main && git push upstream release/X.Y
```

The next step is to create tags to trigger release workflow, **however**
we start by using release candidate tags (`X.Y.Z-rcN`) before tagging the
final release (`X.Y.Z`).

1. Create release candidate tag and push. The first RC uses `N=0`. Increment
`N` for each RC.
```
git tag X.Y.0-rcN upstream/release/X.Y && git push upstream tag X.Y.0-rcN
```
2. Announce the RC release: see [Announcing Releases]
3. Wait a week for feedback.
* Follow [Patch release with cherry picks] to pull bug fixes into the
release branch.
* Repeat the RC tagging step, incrementing `N`.
4. Finally, tag the final release tag:
```shell
git tag X.Y.0 upstream/release/X.Y && git push upstream tag X.Y.0
```

Release automation will create a GitHub release and BCR pull request.
1. **Prepare the Release**: Run the [Release: Prepare](https://github.com/bazel-contrib/rules_python/actions/workflows/release_prepare.yaml)
workflow manually. You can trigger it from the GitHub Actions UI or using
the GitHub CLI:
```shell
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.

2. **Approve and Merge**: Approve and merge the PR. Once merged, a release
branch will be created automatically.

3. **Add Backports (if needed)**: If there are backports, add them following
the [How to add backports](#how-to-add-backports) steps.

4. **Create an RC**: Comment `/create-rc` on the tracking issue. All pending
backports must be successfully processed before creating the RC.

5. **Iterate**: Repeat steps 3 and 4 until backports and RCs are no longer
needed.

6. **Finalize the Release**: Comment `/promote` on the tracking issue to
finalize the release.


### Manually triggering the release workflow

Expand Down Expand Up @@ -87,6 +73,31 @@ 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.

## How to add backports

To add backports to an active release, you can use one of the following
methods:

### Method A: Manual Checklist Update
1. Manually add checklist items under the `## Backports` section of the
Release Tracking Issue. The format must be: `- [ ] #<PR_NUMBER>` (e.g.,
`- [ ] #1234`).
2. When ready, comment `/process-backports` on the tracking issue to trigger
processing.

### Method B: Comment Shortcut
1. Comment `/add-backports <PR_NUMBER> [<PR_NUMBER> ...]` (space or comma
separated) on the tracking issue. This will automatically add the PRs to the
checklist and trigger processing.

### Failure Behavior
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=done` metadata.

## Patch release with cherry picks

If a patch release from head would contain changes that aren't appropriate for
Expand All @@ -105,8 +116,8 @@ The fix being included is commit `deadbeef`.
If multiple commits need to be applied, repeat the `git cherry-pick` step for
each.

Once the release branch is in the desired state, use `git tag` to tag it, as
done with a release from head. Release automation will do the rest.
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.

### Announcing releases

Expand Down Expand Up @@ -139,6 +150,14 @@ The two points of no return are:
If release steps fail _prior_ to those steps, then its OK to change the tag. You
may need to manually delete the GitHub release.

## Manual Editing of Tracking Issue

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`).

## Secrets

### PyPI user rules-python
Expand Down
Loading