7.8 KiB
monorel
Manage independently-versioned modules and releases in a single repository.
- initializes monorepo-compatible
.goreleaser.yaml - bumps versions correctly with
git(tags by commit to amodule) - releases with
goreleaserandgh(multi-arch, cross-compiled) - single or multiple binaries per release
monorel release --recursive ./tools/monorel/
Use git tags like this:
git tag:
v0.1.0
v0.1.1
cmd/sql-migrate/v1.0.2
cmd/sql-migrate/v2.0.3
io/transform/gsheet2csv/v1.0.4
io/transform/gsheet2csv/v1.0.5
tools/monorel/v0.6.5
tools/monorel/v1.0.0
to manage packaged releases for a project like this:
./ # v0.1.1
├── go.mod # (module-only)
├── cmd/
│ └── sql-migrate/ # cmd/sql-migrate/v2.0.3
│ ├── .goreleaser.yaml # (module for binary)
│ └── go.mod
├── io/
│ └── transform/
│ └── gsheet2csv/ # io/transform/gsheet2csv/v1.0.5
│ ├── .goreleaser.yaml # (module with 3 binaries)
│ ├── go.mod
│ └── cmd/
│ ├── gsheet2csv/
│ ├── gsheet2env/
│ └── gsheet2tsv/
└── tools/
└── monorel/ # tools/monorel/v1.0.0
├── .goreleaser.yaml # (module for binaries)
└── go.mod
Install
monorel also uses
Linux & macOS
webi monorel
source ~/.config/envman/PATH.env
Go
webi go goreleaser gh
source ~/.config/envman/PATH.env
go install github.com/therootcompany/golib/tools/monorel@latest
Usage
init
Generates amonorel init --recursive ./.goreleaser.yamlin every module directory (next to eachgo.mod) that contains at least one command package (package main), configured to build and release all discovered binaries together (per each target build release package). Also tags an initial v0.1.0 if none is present. Uses a hard-coded command name with the{{ .Env.VERSION }}placeholder to sidestep monorepo config issues.bump
Usesmonorel bump --recursive ./git log -- <path>andgit tagto tag NOT the latest commit of the repo, but the most recent commit changing in the module, with the next semver version.release
Usesmonorel release --recursive ./goreleaserto cross-compile a wide range of binaries and then creates a release withgh(the GitHub CLI) - first as a draft, then uploading the assets, then finalizing the release as public (non-draft).
Init
Creates a .goreleaser.yaml for the go.mod of each package main.
monorel init --recursive ./
| Flag | Default | Description |
|---|---|---|
--almost-all |
off | Widen build matrix to include esoteric platforms (see Build matrix) |
--android-ndk |
off | Adds additional Android build entries (ones that require CGO_ENABLED=1 and the Android NDK) |
--dry-run |
off | Print what would happen without writing or tagging |
--ios |
off | Add an iOS build entry (requires CGO_ENABLED=1 and Xcode) |
--recursive |
off | Find all main packages recursively under each path |
Bump
Maths out the previous and proper next semver release.
monorel bump --recursive ./
| Flag | Default | Description |
|---|---|---|
--dry-run |
off | Print the tag that would be created without creating it |
--force |
off | If no new commits, create an empty bump commit and tag it |
--recursive |
off | Find all main packages recursively |
Release
Build all binaries, puts them in common package formats (.tar.gz, .tar.zst, .zip), creates a GitHub Release, uploads the packages, and makes the release public.
monorel release --recursive ./
| Flag | Default | Description |
|---|---|---|
--draft |
off | Keep the GitHub release in draft state after uploading |
--dry-run |
off | Show each step without running it |
--prerelease |
off | Keep the GitHub release marked as pre-release even for clean tags |
--recursive |
off | Find all main packages recursively |
--yes |
off | Run all steps without prompting |
Interactive Prompts
- Create git tag — skipped when a tag for this version already exists.
- Push commits and tags —
git push && git push --tags. - Build with goreleaser —
goreleaser release --clean --skip=validate,announcewithVERSION=<semver>set in the environment. - Create GitHub release — always created as
--draft --prereleaseso artifacts can be uploaded before the release goes public. - Upload artifacts —
gh release uploadwith all.tar.gz,.tar.zst,.zip, and checksum files fromdist/. - Finalize release visibility — removes
--draftand/or--prereleaseflags as appropriate (see--draft/--prereleasebelow).
Build matrix
The generated .goreleaser.yaml targets CGO_ENABLED=0 for by default.
Platforms that require CGO or a special toolchain are only included when the
corresponding flag is given.
The default matrix contains:
| Values | |
|---|---|
goos |
darwin freebsd js linux netbsd openbsd wasip1 windows |
goarch |
amd64 arm arm64 mips64le mipsle ppc64le riscv64 wasm |
goamd64 |
v1 v2 |
goamd64 |
v3 v4 |
goarm |
6 7 |
--almost-all adds less-commonly-targeted platforms:
| Added values | |
|---|---|
goos |
aix dragonfly illumos plan9 solaris |
goarch |
386 loong64 mips mips64 ppc64 s390x |
goamd64 |
v1 v2 v3 v4 |
--ios adds an ios build entry, which requires the Xcode toolchain:
- id: <binary>-ios
env:
- CGO_ENABLED=1
goos:
- ios
goarch:
- arm64
--android-ndk adds a build entry for Android/arm64, which requires the Android NDK:
- id: <binary>-android
env:
- CGO_ENABLED=1
goos:
- android
goarch:
- arm64
vs GoReleaser Pro
This isn't a replacement for GoRoleaser Pro.
Although I wouldn't have created it if multi-module version management were available in a (free or paid) version of GoReleaser without a subscription, this handles initialization, versioning, and releasing in the way that I've wanted for my workflow (and this repository).