Repository navigation
internal/cmd/gorums-release: automate releases with a Go program - #348
Conversation
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
There was a problem hiding this comment.
🟡 Changes recommended
Release version selection, dry-run safety, module tidying, PR validation, and proxy verification have correctness or reliability gaps.
8 open findings
Propagate GitHub PR lookup failures · New Select release version after applying dependency upgrades · New Tidy benchkit after regenerating files · New Keep git fetch out of dry-run query execution · New Compare complete semantic versions including pre-releases · New Verify releases with a fresh public Go proxy cache · New Print query commands during dry runs · New Remove untracked generated files during recovery · New
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, andpublishrelease 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.
…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
left a comment
There was a problem hiding this comment.
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.
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
9956566 to
ac409b0
Compare



Closes #346.
Replaces the four
release-*Makefile targets and the manual version edits with one program,gorums-release, ininternal/cmd/gorums-release.It uses only the standard library and shells out to
git,gh,gorelease, andgo.Install it from a checkout with
go install ./internal/cmd/gorums-release.Commands
All commands work without flags, and all accept
-dry-run.prepare: runsgoreleaseon the clean tree and adopts its suggested version (or checks-version), upgrades and tidies the root,examples, andbenchkitmodules, writes the version constants, runsmake genproto, and runs the tests. It changes files and makes no commits.pr: createsrelease/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), tagsvX.Y.Zandbenchkit/vX.Y.Zon 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
benchkitis released in lockstep with the root module.v0.12.0-rc.1, is a pre-release.v0.X.Yis not.v0tov1, stops unless-allow-majoris given, for a suggested version and for-version.v2and higher are refused, because they need a new module path.GenVersionandMinVersionchange only with-bump-genor-bump-min, before the code is regenerated, because the generated code containsGenVersion. A dry run hints when the generator output changed since the last release.preparechecks thatgit,make,go,protoc, andghare installed, thatghis logged in, and that the Go bin directory is onPATH.Changes to existing files
release-*Makefile targets are removed.doc/release-guide.mdis rewritten as a short overview of the steps and their outcomes.doc/dev-guide.mdpoints to the guide.Testing
prepare -skip-testsran for real in a throwaway clone ofmaster: all three modules build afterward.pr -dry-runandprepare -dry-runwere run for real.pr, and everything inpublish(merge, tags, release, proxy check). I suggest a first release with-version v0.12.0-rc.1.Open
gh pr mergebehaves under branch protection that requires reviews is untested.masterreadsvX.Y.Zwith no-develsuffix; nothing bumps it back.