Skip to content

ci(release): add one-button release cut from main - #20

Merged
hectorvent merged 1 commit into
mainfrom
feat/one-button-release
Aug 27, 2026
Merged

ci(release): add one-button release cut from main#20
hectorvent merged 1 commit into
mainfrom
feat/one-button-release

Conversation

@hectorvent

Copy link
Copy Markdown
Contributor

Summary

Releases were tag-driven and manual in three separate steps: hand-bump <version> in pom.xml, hand-move the CHANGELOG.md [Unreleased] entries under a new heading, commit, then push a SemVer tag. Each step could disagree with the others.

This adds a manually-dispatched Release Cut workflow that runs semantic-release against main: it analyzes the Conventional Commits since the last tag, bumps pom.xml via mvn versions:set, regenerates CHANGELOG.md, commits both, tags (tagFormat: ${version}), and creates the GitHub Release. The tag push then fires release.yml exactly as a manual tag push did — the binary build and homebrew-bump.yml chain is untouched. A dry-run input previews the next version and release notes without releasing anything.

Supporting changes:

  • CHANGELOG.md becomes generated output. The hand-maintained [Unreleased] section and its compare link are removed and the header states the new contract; historic sections stay as they were. Changelog Guard fails any PR that edits the file by hand unless a maintainer applies the changelog-edit label.
  • Conventional Commits linter — since commit messages are now the changelog, every non-merge commit in a PR is validated against the types semantic-release recognizes.
  • release.yml — dropped the hand-written installation body; the release now carries just the attachments and semantic-release writes the notes.

Token and supply-chain notes

The cut requires a fine-grained PAT (GH_TOKEN, contents:write), not the default GITHUB_TOKEN: tags pushed with GITHUB_TOKEN do not trigger other workflows (GitHub's recursion guard), so release.yml would never run.

The semantic-release toolchain is pinned by its own package-lock.json and installed with npm ci --ignore-scripts, so the job holding that write PAT never resolves mutable versions. Action refs in release-cut.yml are SHA-pinned.

Type of change

  • Bug fix (fix:)
  • New feature (feat:)
  • Breaking change (feat!: or fix!:)
  • Docs / chore — ci: (release automation only; no src/ changes, so no version bump of its own)

Product trees affected

  • AWS (root tree)
  • GCP (commands/gcp/)
  • Azure (commands/az/)
  • N/A (shared infrastructure, docs, CI)

Checklist

  • mvn test passes locally — unchanged; this PR touches no src/, and CI runs the suite
  • New or updated tests — none needed, no CLI behavior changes (workflow YAML validated locally; pinned action SHAs verified to resolve)
  • CHANGELOG.md entry — N/A by design: this PR is what makes the file generated. The hand edit here is the point of the PR, hence the changelog-edit label
  • README.md updated — not affected
  • Native binary — unaffected, no Jackson or dependency changes
  • Commit messages / PR title follow Conventional Commits

Before merging

  • Confirm the GH_TOKEN secret has contents:write on this repo. The existing GH_TOKEN used by homebrew-bump.yml needs scope on floci-io/homebrew-floci, which is a different grant — if it is tap-only, the release cut fails at the push step.
  • Recommended first run: dispatch Release Cut with dry-run: true to preview the computed version and notes. With this PR landing as ci:, the next cut releases whatever real feat:/fix: commits sit on main — currently the fix(env): single-quote exported values in every product tree #19 env-quoting fix, i.e. a patch.

Releases were tag-driven: a maintainer hand-bumped pom.xml, hand-moved the
CHANGELOG [Unreleased] entries under a new heading, committed, then pushed a
SemVer tag. Three manual steps, each able to disagree with the others.

Add a manually-dispatched Release Cut workflow that runs semantic-release
against main: it analyzes the Conventional Commits since the last tag, bumps
pom.xml via `mvn versions:set`, regenerates CHANGELOG.md, commits both, tags
(tagFormat ${version}), and creates the GitHub Release. The tag push then
fires release.yml exactly as a manual tag push did, so the binary build and
homebrew-bump chain is untouched. A dry-run input previews the next version
and notes without releasing.

The cut needs a fine-grained PAT (GH_TOKEN, contents:write) rather than the
default GITHUB_TOKEN, whose tag pushes do not trigger other workflows — with
it, release.yml would never run. The semantic-release toolchain is pinned by
its own package-lock.json and installed with `npm ci --ignore-scripts`, so
the job holding that PAT never resolves mutable versions.

CHANGELOG.md becomes generated output. The hand-maintained [Unreleased]
section and its compare link are removed, the header explains the new
contract, and historic sections stay as they were. Changelog Guard fails any
PR that edits the file by hand unless a maintainer applies the
`changelog-edit` label.

Since commit messages are now the changelog, add a Conventional Commits
workflow that lints every non-merge commit in a PR against the types
semantic-release recognizes.

Also drop the hand-written installation body from release.yml — the release
now carries just the attachments, and semantic-release writes the notes.
@hectorvent hectorvent added the changelog-edit Allows a hand edit to CHANGELOG.md past the Changelog Guard (genuine corrections only) label Aug 27, 2026
@greptile-apps

greptile-apps Bot commented Aug 27, 2026

Copy link
Copy Markdown

Greptile Summary

This PR replaces the manual release sequence with a semantic-release workflow that updates the Maven version and changelog, creates the release tag and notes, and hands artifact publication to the existing tag-driven pipeline.

  • Adds a pinned semantic-release dependency tree and release configuration.
  • Adds changelog and Conventional Commit pull-request checks.
  • Preserves the existing binary and Homebrew publication chain while changing release-note ownership.
  • Introduces one non-blocking supply-chain hardening issue in the commit-lint workflow.

Confidence Score: 4/5

The PR appears safe to merge, with a non-blocking recommendation to pin the checkout action used by the new commit-lint workflow.

The release handoff, runtime versions, generated changelog flow, and downstream Homebrew trigger remain coherent; the only accepted concern is the mutable action reference in a read-only pull-request workflow.

Files Needing Attention: .github/workflows/conventional-commits.yml

Security Review

The commit-lint workflow uses a mutable actions/checkout@v7 reference. Its read-only permissions and lack of secrets limit the impact, but pinning the action to a full commit SHA would prevent unreviewed upstream retargeting. How this was verified: The pull-request workflow invokes the mutable tag with contents: read before running its validation step.

Important Files Changed

Filename Overview
.github/workflows/release-cut.yml Adds a serialized, manually dispatched semantic-release job using a write PAT and SHA-pinned actions.
.releaserc.json Configures version analysis, Maven version updates, generated changelog commits, numeric tags, and GitHub release notes.
.github/workflows/conventional-commits.yml Adds commit-message validation but invokes checkout through a mutable major-version tag.
.github/workflows/changelog-guard.yml Prevents direct changelog edits unless maintainers apply the documented override label.
.github/workflows/release.yml Leaves artifact publication intact while allowing semantic-release’s generated notes to remain on the existing release.
.github/release-tooling/package.json Declares exact semantic-release tooling versions backed by the committed lockfile.

Sequence Diagram

sequenceDiagram
    participant M as Maintainer
    participant C as Release Cut
    participant S as semantic-release
    participant R as Release workflow
    participant G as GitHub Release
    participant H as Homebrew bump
    M->>C: Dispatch from main
    C->>S: Analyze Conventional Commits
    S->>S: Update pom.xml and CHANGELOG.md
    S->>G: Commit, tag, and create release notes
    S-->>R: Push SemVer tag
    R->>R: Build binaries, JAR, and checksums
    R->>G: Attach release assets
    R-->>H: Successful workflow completion
    H->>H: Open tap update PR
Loading

Reviews (1): Last reviewed commit: "ci(release): add one-button release cut ..." | Re-trigger Greptile

Comment thread .github/workflows/conventional-commits.yml
@hectorvent
hectorvent merged commit 7cef52b into main Aug 27, 2026
4 checks passed
@hectorvent

Copy link
Copy Markdown
Contributor Author

🎉 This PR is included in version 0.2.1 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changelog-edit Allows a hand edit to CHANGELOG.md past the Changelog Guard (genuine corrections only) released

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant