mirror of
https://github.com/therootcompany/golib.git
synced 2026-03-13 20:37:59 +00:00
206 lines
7.8 KiB
Markdown
206 lines
7.8 KiB
Markdown
# [monorel](https://github.com/therootcompany/tree/main/tools/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 `goreleaser` and `gh` (multi-arch, cross-compiled)
|
|
- single or multiple binaries per release
|
|
|
|
```sh
|
|
monorel release --recursive ./tools/monorel/
|
|
```
|
|
|
|
Use git tags like this:
|
|
|
|
`git tag`:
|
|
|
|
```sh
|
|
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:
|
|
|
|
```sh
|
|
./ # 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
|
|
|
|
```sh
|
|
webi monorel
|
|
source ~/.config/envman/PATH.env
|
|
```
|
|
|
|
## Go
|
|
|
|
```sh
|
|
webi go goreleaser gh
|
|
source ~/.config/envman/PATH.env
|
|
```
|
|
|
|
```sh
|
|
go install github.com/therootcompany/golib/tools/monorel@latest
|
|
```
|
|
|
|
# Usage
|
|
|
|
1. `init`
|
|
```sh
|
|
monorel init --recursive ./
|
|
```
|
|
Generates a `.goreleaser.yaml` in every module directory (next to each `go.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.
|
|
2. `bump`
|
|
```sh
|
|
monorel bump --recursive ./
|
|
```
|
|
Uses `git log -- <path>` and `git tag` to tag NOT the latest commit of the repo, but the most recent commit changing _in the module_, with the next semver version.
|
|
3. `release`
|
|
```sh
|
|
monorel release --recursive ./
|
|
```
|
|
Uses `goreleaser` to cross-compile a wide range of binaries and then creates a release with `gh` (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`.
|
|
|
|
```sh
|
|
monorel init --recursive ./
|
|
```
|
|
|
|
| Flag | Default | Description |
|
|
| --------------- | ------- | ----------------------------------------------------------------------------------------------- |
|
|
| `--almost-all` | off | Widen build matrix to include esoteric platforms (see [Build matrix](#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.
|
|
|
|
```sh
|
|
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.
|
|
|
|
```sh
|
|
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
|
|
|
|
1. **Create git tag** — skipped when a tag for this version already exists.
|
|
2. **Push commits and tags** — `git push && git push --tags`.
|
|
3. **Build with goreleaser** — `goreleaser release --clean --skip=validate,announce`
|
|
with `VERSION=<semver>` set in the environment.
|
|
4. **Create GitHub release** — always created as `--draft --prerelease` so
|
|
artifacts can be uploaded before the release goes public.
|
|
5. **Upload artifacts** — `gh release upload` with all `.tar.gz`, `.tar.zst`,
|
|
`.zip`, and checksum files from `dist/`.
|
|
6. **Finalize release visibility** — removes `--draft` and/or `--prerelease`
|
|
flags as appropriate (see `--draft` / `--prerelease` below).
|
|
|
|
# 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:
|
|
|
|
```yaml
|
|
- 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](https://developer.android.com/ndk):
|
|
|
|
```yaml
|
|
- id: <binary>-android
|
|
env:
|
|
- CGO_ENABLED=1
|
|
goos:
|
|
- android
|
|
goarch:
|
|
- arm64
|
|
```
|
|
|
|
# vs GoReleaser Pro
|
|
|
|
This isn't a replacement for [GoRoleaser Pro](https://goreleaser.com/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).
|