Skip to content

Commit ff19e47

Browse files
committed
chore: document release
1 parent bf590cf commit ff19e47

2 files changed

Lines changed: 96 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ When you run `ssh server.example.com`, OpenSSH's Match exec triggers `epithet ma
6161
- [Policy Server Guide](docs/policy-server.md) - Setup and configuration for the policy server
6262
- [Authentication](docs/authentication.md) - Auth plugin protocol and custom plugins
6363
- [OIDC Setup](docs/oidc-setup.md) - Provider-specific OIDC configuration (Google, Okta, Azure AD)
64+
- [Releasing](docs/RELEASING.md) - How to cut a release
6465

6566
## Development
6667

docs/RELEASING.md

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# Releasing
2+
3+
Releases are triggered by pushing an annotated `vX.Y.Z` git tag. Everything
4+
downstream — building binaries, publishing the GitHub Release, updating the
5+
Homebrew tap, and building the FreeBSD package — is automated in CI. You never
6+
run goreleaser by hand for a real release; you only create and push the tag.
7+
8+
## Quick procedure
9+
10+
```bash
11+
jj st # confirm the working copy is clean and committed
12+
make next-version # sanity-check current vs. computed next version
13+
make release # runs tests, then creates the vX.Y.Z tag
14+
git push origin vX.Y.Z # this push is what triggers the release (make release prints it)
15+
```
16+
17+
Then watch the `release` workflow in GitHub Actions and confirm the GitHub
18+
Release, its `checksums.txt`, and the updated formula in the
19+
`epithet-ssh/homebrew-tap` repository.
20+
21+
## How the version is chosen
22+
23+
`make release` uses [`svu`](https://github.com/caarlos0/svu), which reads
24+
Conventional Commits since the last tag to compute the next version:
25+
26+
- `fix:` → patch (`0.17.1``0.17.2`)
27+
- `feat:` → minor (`0.17.1``0.18.0`)
28+
- `feat!:` or a `BREAKING CHANGE:` footer → major (`0.17.1``1.0.0`)
29+
30+
This is why commits must follow Conventional Commits — the version number is
31+
derived from them, not chosen by hand.
32+
33+
Override the bump when needed via `VERSION`:
34+
35+
```bash
36+
make release VERSION=patch # force a patch bump
37+
make release VERSION=minor # force a minor bump
38+
make release VERSION=major # force a major bump
39+
make release VERSION=0.17.5 # pin an explicit version
40+
```
41+
42+
`make release VERSION=next` (the default) is the `svu`-computed value.
43+
44+
## The trigger model
45+
46+
Two workflows split CI from releasing on the tag:
47+
48+
- `.github/workflows/build.yml` runs on every branch and pull request but
49+
**ignores `v*` tags** (`tags-ignore`). Pushing code never releases.
50+
- `.github/workflows/release.yml` runs **only on `v*` tags**. Pushing the tag
51+
is the release trigger.
52+
53+
So a release happens exactly when — and only when — a `v*` tag is pushed.
54+
55+
## What CI produces
56+
57+
`release.yml` runs two jobs:
58+
59+
1. **release** — checks out full history, runs `make test`, then goreleaser
60+
(`release --clean`, config in `.goreleaser.yaml`). goreleaser builds six
61+
binaries (linux, darwin, freebsd × amd64, arm64), publishes a GitHub Release
62+
with a filtered changelog and `checksums.txt`, and pushes an updated formula
63+
to `epithet-ssh/homebrew-tap`.
64+
2. **freebsd-pkg** — after the release job, builds the FreeBSD `.pkg` in a
65+
FreeBSD VM (`contrib/freebsd`) and uploads it to the same release.
66+
67+
## Required secrets
68+
69+
`release.yml` needs `HOMEBREW_TAP_GITHUB_TOKEN` (a token with write access to
70+
`epithet-ssh/homebrew-tap`) so goreleaser can push the formula update.
71+
`GITHUB_TOKEN` is provided automatically by Actions.
72+
73+
## Dry run before cutting a tag
74+
75+
Test the goreleaser build locally without publishing anything:
76+
77+
```bash
78+
make release-dry-run # goreleaser release --snapshot --clean --skip=publish
79+
```
80+
81+
Artifacts land in `dist/`. Use this to catch build or config problems before
82+
creating a real tag.
83+
84+
The dry run currently prints a deprecation warning: the `brews:` block in
85+
`.goreleaser.yaml` is deprecated in favor of `homebrew_casks` (see
86+
<https://goreleaser.com/deprecations#brews>). It still works with the pinned
87+
`~> v2` goreleaser, but should be migrated before bumping goreleaser to a
88+
version that removes it.
89+
90+
## Note on jj
91+
92+
This repository uses `jj`, but `make release` calls `git tag -a` (jj and git
93+
share the same colocated repo). Make sure the working copy is committed
94+
(`jj st` clean) before running `make release` so the tag lands on the intended
95+
commit.

0 commit comments

Comments
 (0)