Cut releases from main only, enforced where it can be

main is protected on the remote and takes no direct pushes, so a release
arrives as a pull request from dev. Document that flow.

`make image` refuses to run outside main. That check has to live locally:
the tag and the image are made before anything reaches the remote, so branch
protection cannot catch a release built from the wrong branch.

A pre-commit hook was tried and dropped. It needed installing per clone, so
it enforced nothing that the remote was not already enforcing, while implying
it did.
This commit is contained in:
Esa Kataja
2026-09-05 20:52:16 +03:00
parent 813e82ef5c
commit 705ad5af26
3 changed files with 32 additions and 6 deletions
+20 -5
View File
@@ -50,16 +50,31 @@ One static Go binary. No Node.js, no bundler, no separate database server.
## Branches
`main` holds released versions only. Every release tag points at a commit on
`main`, so its history is the deployment history.
`main`, so its history is the deployment history. **Nothing is committed to
`main` directly** — it moves only by fast-forwarding `dev` into it.
All development happens on `dev`. Merge into `main` when cutting a release,
then build and push the image from there.
All development happens on `dev`. `main` is protected on the remote: it takes
no direct pushes, so a release arrives through a pull request.
```sh
git switch dev # where the work happens
git switch main && git merge dev && make release
git switch dev # where the work happens
# ... commits ...
make check # lint, unit tests, smoke
git push origin dev
tea pr create --base main --head dev # or open it in the forge
# merge the pull request, then:
git switch main && git pull --ff-only
make release # builds, tags vYYYYMMDD-N, pushes the image
git push origin --tags
```
`make image` additionally refuses to run from any branch but `main`, so a
release tag can never point at a commit that was not released. That check
lives locally because it has to: tags and images are built before anything
reaches the remote, so protection there cannot catch it.
## Quick start
```sh