Skip to content

fix(release): derive the version bump from commit types (#54) - #60

Merged
abienkowski merged 10 commits into
mainfrom
fix/release-version-bump
Oct 7, 2026
Merged

abienkowski merged 10 commits into
mainfrom
fix/release-version-bump

Conversation

@abienkowski

Copy link
Copy Markdown
Collaborator

Description

The release workflow always bumped the patch number (release.yml "Bump patch version"), while AGENTS.md said version bumps derive from commit types. As a result, #47 (feat!:) shipped as v0.2.22 and #53 (fix!:) as v0.2.26, both as patch releases with hand-written breaking-change notes.

This PR derives the bump from every commit since the latest vX.Y.Z tag. The rule is defined in docs/release-versioning.md:

Row Commits since the last tag include Below 1.0 1.0 and above
release-as Release-As: vX.Y.Z (the newest one decides) exactly that version same
breaking type!: / type(scope)!: subject, or a BREAKING CHANGE: / BREAKING-CHANGE: line minor major
feature feat: / feat(scope): subject minor minor
other anything else patch patch
no-tag no vX.Y.Z tag start from v0.0.0 —
  • Subject-only detection. Only the subject line sets the type. GitHub's default squash body lists commits as * … bullets, and those don't count.
  • Whole range scanned. One release can cover several merges: v0.2.25 covered fix(ts): strip dotted API-version prefixes (#52) #56 and fix: strip only numeric API-version prefixes in Go and Rust (#57) #58.
  • Generated notes. A ⚠️ Breaking changes section (subjects plus multi-line footer text) is generated and passed via --notes-file alongside --generate-notes, so breaking changes reach the notes without hand-editing.
  • Release-As. It sets the version exactly. A malformed value, or one not greater than the latest tag, fails the bump step before any tag is created. Because only the newest Release-As decides, a bad footer is fixed by merging a corrected one.
  • Unchanged: every push to main still releases. Apart from the version step and --notes-file on gh release create, nothing in release.yml changed. The tag search is now limited to tags reachable from HEAD (--merged HEAD).

Closes #54

Implementation

  • scripts/release-version.sh and scripts/release-notes.sh: plain bash, portable to macOS bash 3.2. They read git log -z --format=%B <tag>..HEAD on stdin.
  • scripts/release-version_test.sh: 51 cases, each named after its rule row. They include an end-to-end case that pipes a real git log from a throwaway repo.
    • Run by: make test-release and a new CI job, release-scripts.
    • Written first: the RED commits 8bfac4d and 0cd1ad9 failed every case before the scripts existed.
  • AGENTS.md step 4 now points to the doc, so its claim is true. docs/repo-standard.md has a one-line pointer.

Dry runs against real history

v0.2.21..v0.2.22: bump=minor tag=v0.3.0     (#47 feat!, shipped as v0.2.22)
v0.2.24..v0.2.25: bump=patch tag=v0.2.25    (#56 + #58, both fix)
v0.2.25..b2cf1b2: bump=minor tag=v0.3.0     (#53 fix!, shipped as v0.2.26)

Generated notes for v0.2.25..b2cf1b2:

## ⚠️ Breaking changes

- fix!: deny percent-encoded request paths (#53) (#59)
  - requests whose path contains '%' are denied with 403 for every method; ...

Merging this PR cuts v0.3.0

The squash body carries a Release-As: v0.3.0 footer. That version reflects the breaking changes that shipped as patches (#47 in v0.2.22, #53 in v0.2.26). Please squash-merge (not rebase: a rebase merge would put the RED commits on main and drop the footer) with exactly the message below. The Release-As: line must start at column 0. If GitHub's default squash body is used instead, this releases as v0.2.27; recover by merging a follow-up commit carrying Release-As: v0.3.0.

  • Title: fix(release): derive the version bump from commit types (#54)
  • Body:
    Derive the release version from the commits since the last tag; see
    docs/release-versioning.md.
    
    Release-As: v0.3.0
    

Type of change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update

Implementation(s) changed

  • Go
  • Rust
  • TypeScript
  • Quint specification
  • CI / infrastructure (release.yml, ci.yml, scripts/, Makefile)

Testing

  • make test-release: 51 passed, 0 failed under macOS /bin/bash 3.2. Also 51/51 under bash 5 (Docker, with git installed).
  • shellcheck (koalaman/shellcheck:stable) on scripts/*.sh: clean. actionlint 1.7.12 on the workflows: clean.
  • make test-all / make test-integration: not run, because no product code changed.
  • New tests added for the change

Not testable before merge: the version job on a real Actions runner. The first real run is this PR's own merge, which is expected to produce v0.3.0.

Checklist

  • I have read CONTRIBUTING.md
  • My code follows the project's coding style
  • I have updated documentation as needed

@abienkowski abienkowski added the Type: Maintenance Added to issues and PRs when a change is for repository maintenance , such as CI or linter changes. label Oct 7, 2026
@abienkowski abienkowski self-assigned this Oct 7, 2026
@abienkowski
abienkowski merged commit c3202ac into main Oct 7, 2026
7 checks passed
@abienkowski
abienkowski deleted the fix/release-version-bump branch October 7, 2026 23:45
abienkowski added a commit that referenced this pull request Oct 8, 2026
The default squash message for a single-commit PR is the commit's own
message, so a footer written here survives a default merge. Footers kept
only in the PR description or a merge-message file were dropped three
times (#60, #62, #64).

Release-As: v0.3.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Type: Maintenance Added to issues and PRs when a change is for repository maintenance , such as CI or linter changes.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Release pipeline always bumps patch; AGENTS.md claims versions derive from commit types

1 participant