Prepare a Release
This workflow prepares a new release of inspect_evals. It creates a release branch, collects changelog fragments, bumps the version tag, and opens a PR. After merge it tags the merge commit and creates a GitHub release.
Reference: PACKAGE_VERSIONING.md
Prerequisites
- The
gh CLI must be authenticated
- You must have push access to the repository
- There must be changelog fragments in
changelog.d/ (beyond .gitkeep and TEMPLATE.md)
Phase 1 — Prepare the release branch
Ensure main is up to date:
git fetch origin
git checkout main
git merge --ff-only origin/main
If the merge fails, stop and inform the user that their local main has diverged from origin/main.
Check for changelog fragments:
List files in changelog.d/ excluding .gitkeep, TEMPLATE.md, and README.*. If there are no fragments, stop and tell the user there is nothing to release.
Determine the new version:
Find the current version from the latest v* git tag:
git tag --sort=-v:refname --list 'v*' | head -1
Ask the user what kind of bump this is, presenting the semver table from PACKAGE_VERSIONING.md:
| Component |
When to bump |
Examples |
| Major |
Breaking changes |
Removing an eval, API changes, scorer output format changes |
| Minor |
New features |
Adding new evals, new task parameters, new utilities |
| Patch |
Bug fixes |
Eval fixes, scorer fixes, dataset loading fixes |
Compute the new version string (e.g. 0.4.0, 0.3.107). Confirm with the user.
Create the release branch:
The branch name is release-YYYY-MM-DD using today's date.
git checkout -b release-YYYY-MM-DD
Phase 2 — Collect the changelog
Run scriv collect:
uv run scriv collect --version <NEW_VERSION>
This removes the individual fragment files from changelog.d/ and prepends a new section to CHANGELOG.md.
Present the changelog diff to the user for review:
git diff CHANGELOG.md
Tell the user: "Please review the collected changelog above. You can edit CHANGELOG.md directly — let me know when you are satisfied, or tell me what changes to make."
Do not proceed until the user confirms the changelog is ready.
Normalise the collected changelog:
changelog.d/ fragments are excluded from the mdformat and markdownlint-fix pre-commit hooks (fragments are partial documents), so a hand-edit during review — or an unusual fragment — can leave CHANGELOG.md in a state those hooks would rewrite. That turns the Markdown Lint and README check jobs red on main after the release PR merges (see #2225, #2329). Run the hooks over CHANGELOG.md, then confirm a second pass is clean:
uv run --group dev pre-commit run mdformat --files CHANGELOG.md || true
uv run --group dev pre-commit run markdownlint-fix --files CHANGELOG.md || true
# A second pass must be clean: applying fixes is fine, failing to
# converge means a real error that would still break main.
uv run --group dev pre-commit run mdformat --files CHANGELOG.md
uv run --group dev pre-commit run markdownlint-fix --files CHANGELOG.md
If the second pass still reports changes, resolve them before committing.
Stage and commit:
git add CHANGELOG.md changelog.d/
git commit -m "Prepare release v<NEW_VERSION>"
Phase 3 — Push and open a PR
Push the branch:
git push -u origin release-YYYY-MM-DD
Open a draft PR:
Extract the new version's section from CHANGELOG.md (everything from the version heading up to but not including the next ## heading). Use this as the PR body:
gh pr create --draft \
--title "Release v<NEW_VERSION>" \
--body "<EXTRACTED_CHANGELOG_SECTION>"
Important: The PR title must start with Release v (e.g. Release v0.4.0) — this is how the release-on-merge.yml workflow identifies release PRs.
Tell the user the PR URL and that it is in draft. They should mark it ready for review when appropriate.
Phase 4 — After the PR is merged (automated)
Once the release PR is merged into main, the .github/workflows/release-on-merge.yml GitHub Actions workflow automatically:
- Tags the merge commit with
v<NEW_VERSION>
- Creates a GitHub release with the changelog section as the body
- Builds and publishes the package to PyPI
- Notifies Slack
No manual action is required. The package version is derived from the new tag by setuptools_scm.
Notes
- The package version is derived entirely from git tags via
setuptools_scm — there is no version file to edit.
- If something goes wrong mid-workflow, the release branch can be deleted and the process restarted.
- The
v prefix on tags is required (e.g. v0.3.107, not 0.3.107).
- The
weekly-release.yml workflow can also automate Phases 1–3 on a schedule or via manual dispatch, creating the release branch and draft PR for you.
1---2name: prepare-release3description: Prepare a new release of inspect_evals by creating a release branch, collecting changelog fragments, and opening a PR. Use when user asks to cut/prepare/create a new release or version bump.4---56# Prepare a Release78This workflow prepares a new release of `inspect_evals`. It creates a release branch, collects changelog fragments, bumps the version tag, and opens a PR. After merge it tags the merge commit and creates a GitHub release.910Reference: `PACKAGE_VERSIONING.md`1112## Prerequisites1314- The `gh` CLI must be authenticated15- You must have push access to the repository16- There must be changelog fragments in `changelog.d/` (beyond `.gitkeep` and `TEMPLATE.md`)1718## Phase 1 — Prepare the release branch19201. **Ensure `main` is up to date**:2122 ```bash23 git fetch origin24 git checkout main25 git merge --ff-only origin/main26 ```2728 If the merge fails, stop and inform the user that their local `main` has diverged from `origin/main`.29302. **Check for changelog fragments**:3132 List files in `changelog.d/` excluding `.gitkeep`, `TEMPLATE.md`, and `README.*`. If there are no fragments, stop and tell the user there is nothing to release.33343. **Determine the new version**:3536 1. Find the current version from the latest `v*` git tag:3738 ```bash39 git tag --sort=-v:refname --list 'v*' | head -140 ```4142 2. Ask the user what kind of bump this is, presenting the semver table from `PACKAGE_VERSIONING.md`:4344 | Component | When to bump | Examples |45 | --------- | ---------------- | ----------------------------------------------------------- |46 | **Major** | Breaking changes | Removing an eval, API changes, scorer output format changes |47 | **Minor** | New features | Adding new evals, new task parameters, new utilities |48 | **Patch** | Bug fixes | Eval fixes, scorer fixes, dataset loading fixes |4950 3. Compute the new version string (e.g. `0.4.0`, `0.3.107`). Confirm with the user.51524. **Create the release branch**:5354 The branch name is `release-YYYY-MM-DD` using today's date.5556 ```bash57 git checkout -b release-YYYY-MM-DD58 ```5960## Phase 2 — Collect the changelog61621. **Run scriv collect**:6364 ```bash65 uv run scriv collect --version <NEW_VERSION>66 ```6768 This removes the individual fragment files from `changelog.d/` and prepends a new section to `CHANGELOG.md`.69702. **Present the changelog diff to the user for review**:7172 ```bash73 git diff CHANGELOG.md74 ```7576 Tell the user: *"Please review the collected changelog above. You can edit `CHANGELOG.md` directly — let me know when you are satisfied, or tell me what changes to make."*7778 **Do not proceed until the user confirms the changelog is ready.**79803. **Normalise the collected changelog**:8182 `changelog.d/` fragments are excluded from the `mdformat` and `markdownlint-fix` pre-commit hooks (fragments are partial documents), so a hand-edit during review — or an unusual fragment — can leave `CHANGELOG.md` in a state those hooks would rewrite. That turns the Markdown Lint and README check jobs red on `main` after the release PR merges (see #2225, #2329). Run the hooks over `CHANGELOG.md`, then confirm a second pass is clean:8384 ```bash85 uv run --group dev pre-commit run mdformat --files CHANGELOG.md || true86 uv run --group dev pre-commit run markdownlint-fix --files CHANGELOG.md || true87 # A second pass must be clean: applying fixes is fine, failing to88 # converge means a real error that would still break main.89 uv run --group dev pre-commit run mdformat --files CHANGELOG.md90 uv run --group dev pre-commit run markdownlint-fix --files CHANGELOG.md91 ```9293 If the second pass still reports changes, resolve them before committing.94954. **Stage and commit**:9697 ```bash98 git add CHANGELOG.md changelog.d/99 git commit -m "Prepare release v<NEW_VERSION>"100 ```101102## Phase 3 — Push and open a PR1031041. **Push the branch**:105106 ```bash107 git push -u origin release-YYYY-MM-DD108 ```1091102. **Open a draft PR**:111112 <!-- markdownlint-disable-next-line no-space-in-code -->113114 Extract the new version's section from `CHANGELOG.md` (everything from the version heading up to but not including the next `##` heading). Use this as the PR body:115116 ```bash117 gh pr create --draft \118 --title "Release v<NEW_VERSION>" \119 --body "<EXTRACTED_CHANGELOG_SECTION>"120 ```121122 **Important**: The PR title **must** start with `Release v` (e.g. `Release v0.4.0`) — this is how the `release-on-merge.yml` workflow identifies release PRs.123124 Tell the user the PR URL and that it is in draft. They should mark it ready for review when appropriate.125126## Phase 4 — After the PR is merged (automated)127128Once the release PR is merged into `main`, the `.github/workflows/release-on-merge.yml` GitHub Actions workflow automatically:1291301. Tags the merge commit with `v<NEW_VERSION>`1312. Creates a GitHub release with the changelog section as the body1323. Builds and publishes the package to PyPI1334. Notifies Slack134135No manual action is required. The package version is derived from the new tag by `setuptools_scm`.136137## Notes138139- The package version is derived entirely from git tags via `setuptools_scm` — there is no version file to edit.140- If something goes wrong mid-workflow, the release branch can be deleted and the process restarted.141- The `v` prefix on tags is required (e.g. `v0.3.107`, not `0.3.107`).142- The `weekly-release.yml` workflow can also automate Phases 1–3 on a schedule or via manual dispatch, creating the release branch and draft PR for you.