Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
b210aaf
build: remove eachdist.py
ocelotl Jul 2, 2026
cbcc70a
changelog: add fragment for PR 5381
ocelotl Jul 2, 2026
9976a6d
build: split release.py into single-purpose scripts
ocelotl Jul 3, 2026
cecb734
build: use from-import style in new release scripts
ocelotl Jul 3, 2026
ec1a336
build: remove update-version.sh wrappers, patch repo.ini in Python
ocelotl Jul 3, 2026
b58d658
build: convert repo.ini to repo.toml
ocelotl Jul 3, 2026
2e90901
build: drop toml dependency, use stdlib tomllib for reads
ocelotl Jul 3, 2026
2a54630
build: use tomlkit for repo.toml, fix missing dep in public-symbols-c…
ocelotl Jul 3, 2026
54e8d9c
build: move release-only scripts into scripts/release/
ocelotl Jul 3, 2026
a49cccc
build: use from-import style for sys.path insertion in release scripts
ocelotl Jul 3, 2026
4043af6
build: un-share single-caller dependency-update functions
ocelotl Jul 3, 2026
5e84154
build: drop main()/parse_args() wrappers from release scripts
ocelotl Jul 3, 2026
952c39c
build: inline single-caller find() and filter_packages() helpers
ocelotl Jul 3, 2026
fbc48a0
build: replace version.py's generic --mode with --stable/--unstable
ocelotl Jul 3, 2026
e30d561
build: rename version.py to print_version.py
ocelotl Jul 3, 2026
970f05b
build: add type hints to release scripts and repo_targets.py
ocelotl Jul 3, 2026
ae58383
build: inline single-use variables in release scripts
ocelotl Jul 3, 2026
9933ab9
build: add docstrings to release script functions
ocelotl Jul 3, 2026
426ac17
build: rename targets to package_dirs, use logging instead of print
ocelotl Jul 3, 2026
7fee098
build: add module-level docstrings to release scripts
ocelotl Jul 3, 2026
a1b9a94
build: give --stable/--unstable their own associated string via args
ocelotl Jul 3, 2026
fe10125
build: rename version_files.py to edit.py and update_* to edit_*
ocelotl Jul 3, 2026
800a86a
docs: add detailed documentation to the 3 release workflows
ocelotl Jul 3, 2026
e1e1c40
build: rename repo_targets.py to find.py, package_dir(s) to
ocelotl Jul 3, 2026
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
1 change: 1 addition & 0 deletions .changelog/5381.removed
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Removed `scripts/eachdist.py` and the `.github/scripts/update-version*.sh` wrappers in favor of tox and small purpose-built scripts: `scripts/version.py`, `scripts/update_version.py`, and `scripts/update_patch_version.py` for release version bumping, and `scripts/repo_targets.py` for distribution discovery. Renamed `eachdist.ini` to `repo.toml`.
11 changes: 0 additions & 11 deletions .github/scripts/update-version-patch.sh

This file was deleted.

6 changes: 0 additions & 6 deletions .github/scripts/update-version.sh

This file was deleted.

88 changes: 83 additions & 5 deletions .github/workflows/prepare-patch-release.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,30 @@
# =============================================================================
# Prepare patch release workflow
# =============================================================================
#
# Purpose: prepares a patch release (e.g. 1.44.0 -> 1.44.1) on an existing
# long-term release branch. Opens a PR against that same branch which bumps
# the patch version and regenerates the changelog -- mirroring what
# prepare-release-branch.yml does for a brand new release branch -- and, in
# addition, backports the new changelog entry to main via a second PR, since
# main's own version isn't touched by a patch release but its CHANGELOG.md
# should still document that the patch happened.
#
# Run this manually (workflow_dispatch) on the long-term release branch you
# want to patch (one previously created by prepare-release-branch.yml's
# "normal release" path -- see that file's header comment; one-off
# prerelease branches, e.g. release/v1.45.0rc2-0.66b0, are never patched
# this way). Once the PR this workflow opens is merged, run release.yml on
# that branch again to actually publish the patch. See release.yml's header
# comment for how this fits into the full 3-workflow release pipeline.
#
# Unlike prepare-release-branch.yml/update_version.py, this workflow (via
# scripts/release/update_patch_version.py) can't rely on version pins ending
# in ".dev" to know what to bump -- a release branch's versions are already
# finalized, non-dev values -- so it explicitly computes both the previous
# and the next patch version and passes both to the script, which replaces
# only pins matching the exact previous version.
# =============================================================================
name: Prepare patch release
on:
workflow_dispatch:
Expand All @@ -14,20 +41,34 @@ jobs:
steps:
- uses: actions/checkout@v4

# tomlkit: read/write repo.toml (via scripts/release/print_version.py
# and update_patch_version.py). towncrier: generate the changelog
# section for this patch below.
- name: Install dependencies
run: pip install toml towncrier

run: pip install tomlkit towncrier

# Guard rail: this workflow only makes sense on a long-term release
# branch, i.e. one named "release/vX.Y.x-0.ZbX" (the "x" is a literal
# placeholder character in the branch name, standing in for "whatever
# patch number", not a wildcard) -- the kind created by
# prepare-release-branch.yml's non-prerelease path. It refuses to run
# on main, a one-off prerelease branch, or anything else.
- run: |
if [[ ! $GITHUB_REF_NAME =~ ^release/v[0-9]+\.[0-9]+\.x-0\.[0-9]+bx$ ]]; then
echo this workflow should only be run against long-term release branches
exit 1
fi

# Reads this branch's current (already-published) version and
# computes both the version being patched (*_PREV) and the new patch
# version (bumping the patch number by 1 on both tracks).
- name: Set environment variables
run: |
stable_version=$(./scripts/eachdist.py version --mode stable)
unstable_version=$(./scripts/eachdist.py version --mode prerelease)
stable_version=$(./scripts/release/print_version.py --stable)
unstable_version=$(./scripts/release/print_version.py --unstable)

# Split e.g. "1.44.0" into stable_major_minor="1.44"
# stable_patch=0.
if [[ $stable_version =~ ^([0-9]+\.[0-9]+)\.([0-9]+)$ ]]; then
stable_major_minor="${BASH_REMATCH[1]}"
stable_patch="${BASH_REMATCH[2]}"
Expand All @@ -36,6 +77,7 @@ jobs:
exit 1
fi

# Split e.g. "0.65b0" into unstable_minor=65 unstable_patch=0.
if [[ $unstable_version =~ ^0\.([0-9]+)b([0-9]+)$ ]]; then
unstable_minor="${BASH_REMATCH[1]}"
unstable_patch="${BASH_REMATCH[2]}"
Expand All @@ -44,6 +86,9 @@ jobs:
exit 1
fi

# *_prev is just the current (pre-patch) version, restated from
# its parsed pieces; the *_version (without _prev) is that same
# version with its patch number incremented by one.
stable_version_prev="$stable_major_minor.$((stable_patch))"
unstable_version_prev="0.${unstable_minor}b$((unstable_patch))"
stable_version="$stable_major_minor.$((stable_patch + 1))"
Expand All @@ -54,21 +99,39 @@ jobs:
echo "STABLE_VERSION_PREV=$stable_version_prev" >> $GITHUB_ENV
echo "UNSTABLE_VERSION_PREV=$unstable_version_prev" >> $GITHUB_ENV

# Rewrites repo.toml, every package's pyproject.toml pins currently
# matching the exact previous version, and every package's
# __version__, to the new patch version. See
# scripts/release/update_patch_version.py's own module docstring for
# a worked before/after example.
- name: Update version
run: .github/scripts/update-version-patch.sh $STABLE_VERSION $UNSTABLE_VERSION $STABLE_VERSION_PREV $UNSTABLE_VERSION_PREV
run: ./scripts/release/update_patch_version.py --stable_version=$STABLE_VERSION --unstable_version=$UNSTABLE_VERSION --stable_version_prev=$STABLE_VERSION_PREV --unstable_version_prev=$UNSTABLE_VERSION_PREV

# Consumes the .changelog/*.<type> fragments accumulated since the
# last release into a new "## Version X/Y" section in CHANGELOG.md,
# same as prepare-release-branch.yml does for a normal release.
- name: Generate changelog
run: towncrier build --yes --version "$STABLE_VERSION/$UNSTABLE_VERSION"

# Configures git's committer identity as the "otelbot" account so the
# commits made below pass this repo's CLA check.
- name: Use CLA approved github bot
run: .github/scripts/use-cla-approved-github-bot.sh

# Mints a short-lived GitHub App installation token for otelbot,
# reused by both PR-creating steps below (this workflow only needs
# one token for its single job, unlike prepare-release-branch.yml
# which mints one per job).
- uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6
id: otelbot-token
with:
app-id: ${{ vars.OTELBOT_APP_ID }}
private-key: ${{ secrets.OTELBOT_PRIVATE_KEY }}

# Commits the version bump + changelog changes, pushes them to a new
# otelbot-owned branch, and opens a PR from that branch back into
# *this same release branch* (not into main -- see the backport steps
# below for how main's changelog gets updated separately).
- name: Create pull request
id: create_pr
env:
Expand All @@ -86,20 +149,32 @@ jobs:
--base $GITHUB_REF_NAME)

echo "pr_url=$pr_url" >> $GITHUB_OUTPUT
# Tags the PR so it's easy to find/filter in the repo's PR list. Only
# runs if a PR URL was actually produced above.
- name: Add prepare-release label to PR
if: steps.create_pr.outputs.pr_url != ''
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh pr edit ${{ steps.create_pr.outputs.pr_url }} --add-label "prepare-release"

# Switches the workspace to main, so the remaining steps operate on
# main's git history instead of the release branch's (needed to build
# a PR whose base is main, below).
- uses: actions/checkout@v4
with:
ref: main

- name: Use CLA approved github bot
run: .github/scripts/use-cla-approved-github-bot.sh

# Since a patch release doesn't touch main's own version, main's
# CHANGELOG.md needs its own separate PR to pick up the new "##
# Version X/Y" section -- this step builds that PR. It fetches the
# otelbot branch pushed above (which already has the correct,
# towncrier-generated CHANGELOG.md from the release branch), copies
# just that one file into a fresh commit on top of main, and opens a
# PR from that commit into main.
- name: Backport patch release changelog to main
id: backport_pr
env:
Expand All @@ -123,6 +198,9 @@ jobs:
--base main)
echo "pr_url=$pr_url" >> $GITHUB_OUTPUT

# "Skip Changelog": this PR's only change *is* CHANGELOG.md itself
# (copied verbatim from the release branch above), so it doesn't need
# -- and shouldn't be asked for -- a changelog fragment of its own.
- name: Add Skip Changelog label to backport PR
if: steps.backport_pr.outputs.pr_url != ''
env:
Expand Down
Loading
Loading