From 45ca79a3836e9001f9f1d20c38f47845eeb5c05b Mon Sep 17 00:00:00 2001 From: Cory Johns Date: Tue, 20 Oct 2026 18:23:26 +0000 Subject: [PATCH] fix: make the release dispatch ask which bump it wants (ENG-9233) [ENG-9233](https://stacklet.atlassian.net/browse/ENG-9233) What ---- - Opens the caller's `bump` dropdown on `(choose one)` rather than defaulting to `patch`, so a dispatch has to answer the question. The called workflow already rejects anything but the three real values, so the placeholder needs no new validation. - Drops the step that required a first release to be a major bump. - Updates the README to match, in the prose about refusals and in the caller block it offers for copying. Why ---- `patch` was a poor default on a dispatch that cannot be taken back. On a repository with no tags it opens at `v0.0.1`, and immutable releases burn that name for good. On any later release it quietly ships a patch for work that earned a minor, which nothing caught, because the guard only ever looked at first releases. Asking the question fixes both, and it fixes them at the point where the default was wrong rather than downstream of it. The guard can then go. A repository that explicitly asks for a patch on an empty tag history means `v0.0.1`, and a minor bump climbs out of it, so there is nothing left worth refusing. Whether a repository opens at `v0.0.1`, `v0.1.0` or `v1.0.0` is its own call, and `cut-release.yml` no longer holds a view on it. Testing ---- - [x] `just lint` passes here and in the five module repositories. - [x] `uvx zizmor@1.23.1 -v --gh-token=... .github/workflows/` reports no findings, with the five online audits scheduled rather than skipped. - [x] Ran the bump check against `(choose one)`, `patch`, `minor`, `major`, `Patch`, empty and `majorly`. Only the three lowercase values pass, so the placeholder stops a run the same way any other unrecognised bump does. - [x] Parsed each caller to confirm the placeholder survives YAML as the literal `(choose one)` and that no `default` key remains. - [ ] After merge, dispatch Release here and confirm the dropdown opens on `(choose one)` and that submitting it fails at the bump check. - [ ] Dispatch Release with a `minor` bump and confirm `v1.1.0` publishes against `v1.0.0` as previous. Docs ---- The README's account of the refusals now covers the placeholder, and says what each bump opens at on a repository with no tags rather than naming one of them as required. Co-Authored-By: Claude Opus 5 --- .github/workflows/cut-release.yml | 14 -------------- .github/workflows/release.yml | 4 ++-- README.md | 12 ++++++++---- 3 files changed, 10 insertions(+), 20 deletions(-) diff --git a/.github/workflows/cut-release.yml b/.github/workflows/cut-release.yml index e5fe311..44978e5 100644 --- a/.github/workflows/cut-release.yml +++ b/.github/workflows/cut-release.yml @@ -111,20 +111,6 @@ jobs: echo "| Dry run | ${DRY_RUN} |" } >> "${GITHUB_STEP_SUMMARY}" - # Only fires on the first release, where the baseline is 0.0.0. A patch - # from there lands v0.0.1 permanently, so this is enforced rather than - # left to the input description. Reads `previous_version` rather than - # `previous_tag`, which carries the action's tag prefix and would make - # this a second copy of a default owned elsewhere. - - name: Require the first release to be major - if: ${{ steps.version.outputs.previous_version == '0.0.0' && inputs.bump != 'major' }} - env: - BUMP: ${{ inputs.bump }} - run: | - echo "This repository has no releases yet, so the first one has to be a" >&2 - echo "major bump to land v1.0.0. This run asked for ${BUMP}." >&2 - exit 1 - publish: needs: version # `success()` is implicit here, and it is what keeps the version job's diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2d3f099..e1a4f4d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,11 +4,11 @@ on: workflow_dispatch: inputs: bump: - description: Which part of the version to raise. The first release has to be major, because the count starts from 0.0.0. + description: Which part of the version to raise. required: true type: choice - default: patch options: + - (choose one) - patch - minor - major diff --git a/README.md b/README.md index cd721d7..fc38592 100644 --- a/README.md +++ b/README.md @@ -63,11 +63,11 @@ on: workflow_dispatch: inputs: bump: - description: Which part of the version to raise. The first release has to be major, because the count starts from 0.0.0. + description: Which part of the version to raise. required: true type: choice - default: patch options: + - (choose one) - patch - minor - major @@ -95,8 +95,12 @@ jobs: The workflow refuses to run against anything but the calling repository's default branch, refuses any re-run of a run it has already started, and refuses to publish over -a tag it did not create. A retry means dispatching again. The first release has to be a major bump, because the version -walk starts from 0.0.0 and a patch from there spends `v0.0.1` permanently. +a tag it did not create. A retry means dispatching again. + +The `bump` dropdown opens on `(choose one)`, which the workflow rejects. The version +walk starts from 0.0.0, so on a repository with no tags patch opens at `v0.0.1`, minor +at `v0.1.0` and major at `v1.0.0`. Which of those a repository wants is its own call, +so the workflow asks rather than assumes. `STEP_SECURITY_API_KEY` is optional. Without it the Harden Runner step is skipped and the rest runs unchanged.