Skip to content

Prepare Release

Prepare Release #28

name: Prepare Release
# The explicit release: a pull request that only bumps VERSION, for releasing what the target
# branch already has. (A feature pull request can carry its own bump instead.) Either way,
# merging the bump is the release: Publish Release runs on that merge, uploads the wheel to
# PyPI, and only then moves the `latest` branch installers follow.
#
# gh workflow run release-prepare.yml --ref main -f bump=patch
#
# runs scripts/release/bump-version.sh on a fresh `release/X.Y.Z` branch from the target -- the
# bump, the derived metadata and every cadgen pin -- and opens that pull request with
# PREPARE_RELEASE_TOKEN: a pull request the workflow's own token opens starts no workflows, so
# no check would ever run on it. It never merges anything: a person merges the pull request
# once its checks pass, and that merge releases it.
#
# `target=build-test` rehearses: the same pull request against build-test, whose Publish
# Release builds and installs without uploading anything.
on:
workflow_dispatch:
inputs:
bump:
description: Semver part to bump when set_version is empty.
required: true
default: patch
type: choice
options:
- patch
- minor
- major
set_version:
description: An exact X.Y.Z to release instead of bumping. Leave empty unless you are naming a specific new version.
required: false
default: ""
type: string
target:
description: Branch the release pull request goes into. main for releases; build-test to rehearse.
required: true
default: main
type: string
dry_run:
description: Show the version changes without opening a pull request.
required: true
default: false
type: boolean
permissions:
contents: read
concurrency:
group: release-prepare-${{ inputs.target }}
cancel-in-progress: false
jobs:
release-pr:
name: Release pull request
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Check out target branch
uses: actions/checkout@v7
with:
ref: ${{ inputs.target }}
fetch-depth: 0
persist-credentials: false
- name: Set up Node.js
uses: actions/setup-node@v7
with:
node-version: "22"
- name: Bump the version
id: version
env:
BUMP: ${{ inputs.bump }}
SET_VERSION: ${{ inputs.set_version }}
TARGET: ${{ inputs.target }}
run: |
scripts/release/bump-version.sh "${SET_VERSION:-$BUMP}" --base "origin/$TARGET"
echo "version=$(tr -d '[:space:]' < VERSION)" >> "$GITHUB_OUTPUT"
- name: Show the version changes
if: inputs.dry_run
run: |
git diff --stat
git diff -- VERSION
- name: Open the release pull request
if: ${{ !inputs.dry_run }}
id: pr
env:
GH_TOKEN: ${{ secrets.PREPARE_RELEASE_TOKEN }}
TARGET: ${{ inputs.target }}
VERSION: ${{ steps.version.outputs.version }}
run: |
if [ -z "$GH_TOKEN" ]; then
echo "PREPARE_RELEASE_TOKEN is not set. It opens the pull request so that its checks run." >&2
exit 1
fi
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git"
branch="release/$VERSION"
git checkout -B "$branch"
git commit -qam "Release $VERSION"
git push --force-with-lease origin "$branch"
body="Releases $VERSION: VERSION, the derived metadata and every cadgen pin. Opened by Prepare Release. Merging it releases it: Publish Release uploads the wheel to PyPI, then moves the latest branch."
# Only an OPEN pull request from this branch is ours to update: a closed or merged one
# with the same head name (a previous attempt) cannot be reopened onto a new commit.
number="$(gh pr list --repo "$GITHUB_REPOSITORY" --head "$branch" --base "$TARGET" --state open --json number --jq '.[0].number // empty')"
if [ -z "$number" ]; then
url="$(gh pr create --repo "$GITHUB_REPOSITORY" --base "$TARGET" --head "$branch" --title "Release $VERSION" --body "$body")"
number="$(gh pr view "$url" --repo "$GITHUB_REPOSITORY" --json number --jq .number)"
fi
echo "number=$number" >> "$GITHUB_OUTPUT"
{
echo "Release pull request: https://github.com/$GITHUB_REPOSITORY/pull/$number"
echo "Merge it once its checks pass: merging it releases $VERSION."
} | tee -a "$GITHUB_STEP_SUMMARY"