Skip to content

internal/cmd/gorums-release: automate releases with a Go program - #348

Merged
meling merged 8 commits into
masterfrom
feature/346/release-tool
Oct 10, 2026
Merged

meling merged 8 commits into
masterfrom
feature/346/release-tool

Conversation

@meling

@meling meling commented Oct 9, 2026 •

Copy link
Copy Markdown
Member

Closes #346.

Replaces the four release-* Makefile targets and the manual version edits with one program, gorums-release, in internal/cmd/gorums-release.
It uses only the standard library and shells out to git, gh, gorelease, and go.

Install it from a checkout with go install ./internal/cmd/gorums-release.

Commands

All commands work without flags, and all accept -dry-run.

  • prepare: runs gorelease on the clean tree and adopts its suggested version (or checks -version), upgrades and tidies the root, examples, and benchkit modules, writes the version constants, runs make genproto, and runs the tests. It changes files and makes no commits.
  • pr: creates release/vX.Y.Z, makes two commits (version and dependencies, then generated code), pushes, and opens the pull request.
  • publish: squash-merges the pull request if it is still open (after a CI check and a confirmation), tags vX.Y.Z and benchkit/vX.Y.Z on one commit, creates the GitHub release, and checks that the Go module proxy serves both tags.

Each command lists its steps under gorums-release <command> -h.

Decisions

  • benchkit is released in lockstep with the root module.
  • A version with a suffix, such as v0.12.0-rc.1, is a pre-release. v0.X.Y is not.
  • A major version bump, such as v0 to v1, stops unless -allow-major is given, for a suggested version and for -version. v2 and higher are refused, because they need a new module path.
  • GenVersion and MinVersion change only with -bump-gen or -bump-min, before the code is regenerated, because the generated code contains GenVersion. A dry run hints when the generator output changed since the last release.
  • prepare checks that git, make, go, protoc, and gh are installed, that gh is logged in, and that the Go bin directory is on PATH.

Changes to existing files

  • The four release-* Makefile targets are removed.
  • doc/release-guide.md is rewritten as a short overview of the steps and their outcomes.
  • doc/dev-guide.md points to the guide.

Testing

  • Unit tests use a fake command runner and cover version parsing, the version file rewrite, command order for each command, pre-release handling, and refusals.
  • prepare -skip-tests ran for real in a throwaway clone of master: all three modules build afterward.
  • pr -dry-run and prepare -dry-run were run for real.
  • Not run for real: the push and PR creation in pr, and everything in publish (merge, tags, release, proxy check). I suggest a first release with -version v0.12.0-rc.1.

Open

  • How gh pr merge behaves under branch protection that requires reviews is untested.
  • After a release, master reads vX.Y.Z with no -devel suffix; nothing bumps it back.

meling added 2 commits October 9, 2026 19:10
The release steps were spread over four Makefile targets and manual
edits of the version files. The new program covers them in three
commands that all work without flags.

prepare asks gorelease for the next version, or checks the one given
with -version, then upgrades and tidies the root, examples, and benchkit
modules, writes the version constants, regenerates the code, and runs
the tests. A version with a suffix such as -rc.1 is a pre-release.

pr commits the prepared files on a release branch, as one commit for the
version and dependencies and one for the generated code, and opens the
pull request.

publish squash-merges the pull request if it is still open, tags the
root and benchkit modules with the same version on one commit, creates
the GitHub release, and checks that the Go module proxy serves the tags.

Every command accepts -dry-run. Each command describes its steps under
-h.

Updates #346
Remove release-tools, prepare-release, release-pr, and release-publish
from the Makefile. gorums-release does their work and also covers the
benchkit module.

Rewrite the release guide as a short overview of the three steps and
their outcomes. The step-by-step description moves to the -h text of
each command. Point to the guide from the developer guide.

Updates #346
Copilot AI balanced review requested due to automatic review settings October 9, 2026 19:29

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Release version selection, dry-run safety, module tidying, PR validation, and proxy verification have correctness or reliability gaps.

8 open findings
What changed in this PR

Adds a standard-library Go tool that automates Gorums release preparation, pull requests, tagging, publication, and verification.

Changes:

  • Adds prepare, pr, and publish release commands with dry-run support.
  • Adds unit tests for release workflows, version handling, and failure cases.
  • Replaces Makefile release targets and updates release documentation.
File Description
Makefile Removes legacy release targets.
internal/​cmd/​gorums-release/​main.go Defines the CLI and command flags.
internal/​cmd/​gorums-release/​main_test.go Tests CLI usage and errors.
internal/​cmd/​gorums-release/​tool.go Provides shared release operations.
internal/​cmd/​gorums-release/​tool_test.go Adds shared test helpers and tests.
internal/​cmd/​gorums-release/​runner.go Executes external commands.
internal/​cmd/​gorums-release/​semver.go Parses and compares versions.
internal/​cmd/​gorums-release/​semver_test.go Tests version handling.
internal/​cmd/​gorums-release/​versionfile.go Reads and rewrites version constants.
internal/​cmd/​gorums-release/​versionfile_test.go Tests version-file operations.
internal/​cmd/​gorums-release/​gorelease.go Parses gorelease reports.
internal/​cmd/​gorums-release/​gorelease_test.go Tests report parsing.
internal/​cmd/​gorums-release/​prepare.go Implements release preparation.
internal/​cmd/​gorums-release/​prepare_test.go Tests preparation workflows.
internal/​cmd/​gorums-release/​pr.go Creates release branches and PRs.
internal/​cmd/​gorums-release/​pr_test.go Tests PR creation and staging.
internal/​cmd/​gorums-release/​publish.go Merges, tags, publishes, and verifies releases.
internal/​cmd/​gorums-release/​publish_test.go Tests publication workflows.
doc/​release-guide.md Documents the automated release process.
doc/​dev-guide.md Links developers to the release guide.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread internal/cmd/gorums-release/publish.go
Comment thread internal/cmd/gorums-release/prepare.go
Comment thread internal/cmd/gorums-release/prepare.go Outdated
Comment thread internal/cmd/gorums-release/prepare.go Outdated
Comment thread internal/cmd/gorums-release/prepare.go Outdated
Comment thread internal/cmd/gorums-release/publish.go Outdated
Comment thread internal/cmd/gorums-release/tool.go
Comment thread doc/release-guide.md Outdated
…publish

prepare tidied the benchkit module before it required the new gorums
version and not after code generation. The module replaces gorums with
the local checkout, like examples, so all three modules are now tidied
last. The version check compared only major, minor, and patch, so an
older release candidate was accepted; it now uses full semantic version
precedence. The git fetch ran in a dry run; it is now skipped.

pr now checks the version again with gorelease on the committed tree and
stops before the push if gorelease rejects it. The version is chosen
before the dependency upgrade, which can change the answer.

publish treated every failed pull request lookup as a merged release.
Only "no pull requests found" is treated that way now. The proxy check
now uses the public proxy, a fresh module cache beside the module, and
no private-module settings, so it cannot pass from a local copy.

A dry run now prints the read-only queries it runs, marked with "?", and
the skipped commands, marked with "+".

Updates #346
Explain the "+" and "?" lines of a dry run. Tell the maintainer to
remove the untracked files that code generation adds, because the next
prepare refuses to start with untracked files, and describe what to do
when pr stops after the gorelease check.

Updates #346
…guard

GenVersion and MinVersion were edited by hand after prepare, but the
generated code contains GenVersion, so the edit left the generated
files stale. prepare now takes -bump-gen, which sets GenVersion to the
new minor version, and -bump-min, which sets MinVersion and GenVersion
to it. Both run before make genproto. A dry run prints a hint when the
generator output changed since the last release.

A major version bump now stops unless -allow-major is given, for a
suggested version and for -version. A bump to v2 or higher is refused
because it needs a new module path. A version that resets the minor
below GenVersion is refused, because MaxVersion is the minor version
and the generated code would not compile.

prepare now checks that git, make, go, protoc, and gh are installed, that
gh is logged in, and that the Go bin directory is on PATH. It checks
this before it changes anything.

Updates #346
List the required programs and the PATH setting. Move the version
choice and the runtime version rules into the first step, because the
generated code contains GenVersion and the choice must be made before
prepare runs. Explain when GenVersion and MinVersion change, why, and
which flag does it. Describe the major version guard.

Updates #346

@meling meling left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the current head, 162b6ff. I found three correctness issues: publish can tag a commit outside the release PR, and pr rejects two kinds of files that prepare legitimately changes. The inline comments include reproduction evidence. The eight earlier review threads were checked and are already resolved.

Comment thread internal/cmd/gorums-release/publish.go Outdated
Comment thread internal/cmd/gorums-release/pr.go Outdated
Comment thread internal/cmd/gorums-release/pr.go
pr stopped with "unexpected changes" for two files that prepare changes
on purpose. prepare -bump-gen and -bump-min write
runtime/gorumsimpl/version.go, and go get -u can raise the go directive
in go.work when a dependency needs a newer Go version. Both belong to
the version and dependency commit now.

The file groups are decided by one function, with a table test that
lists every kind of file that prepare, go get -u, and make genproto
change.

Updates #346
publish tagged HEAD after git pull --ff-only. That pull succeeds when
the local master has extra commits, and the version check passes when
those commits leave the version file alone, so unpublished code could
end up under permanent module versions. A later commit on origin/master
had the same effect.

publish now reads the merge commit of the release pull request from
gh, checks that it is in the repository, is on origin/master, and carries
the version, and passes it to both git tag commands. It no longer
switches branches or pulls. A missing pull request is now an error,
because without it there is no merge commit to tag.

Updates #346
@meling
meling force-pushed the feature/346/release-tool branch from 9956566 to ac409b0 Compare October 10, 2026 17:36
@meling
meling merged commit c69ccc0 into master Oct 10, 2026
6 checks passed
@meling
meling deleted the feature/346/release-tool branch October 10, 2026 17:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

chore: automate releases with a Go program

2 participants