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:
@@ -81,6 +81,14 @@ fix: ## Format Go and templ sources, tidy go.mod
|
||||
|
||||
image: ## Build and tag an image as vYYYYMMDD-N. Creates a git tag.
|
||||
@test -n "$(FOODSTER_REPO)" || { echo "set FOODSTER_REPO in .env"; exit 1; }
|
||||
@# A release tag must point into main, or the tag records a commit that
|
||||
@# was never released.
|
||||
@branch=$$(git symbolic-ref --short HEAD); \
|
||||
if [ "$$branch" != "main" ]; then \
|
||||
echo "releases are cut from main, not $$branch:"; \
|
||||
echo " git switch main && git merge --ff-only dev"; \
|
||||
exit 1; \
|
||||
fi
|
||||
@day=$$(date +%Y%m%d); \
|
||||
tag="v$$day-$$(( $$(git tag -l "v$$day-*" | wc -l) + 1 ))"; \
|
||||
echo "==> $$tag"; \
|
||||
|
||||
@@ -360,7 +360,10 @@ on the server and run with Docker Compose.
|
||||
|
||||
- **Branches**: `main` carries released versions only, so its history is the
|
||||
deployment history and every release tag points into it. Development happens
|
||||
on `dev` and merges into `main` when a release is cut.
|
||||
on `dev`, and `main` is protected on the remote: it accepts no direct
|
||||
pushes, so a release arrives as a pull request from `dev`. `make image`
|
||||
additionally refuses to run outside `main` — that one has to be local,
|
||||
because the tag and the image are made before anything reaches the remote.
|
||||
- **Versioning**: CalVer `vYYYYMMDD-N`, where `N` is the Nth build of that
|
||||
day. `make image` derives `N` by counting the day's existing git tags,
|
||||
creates the new tag, and bakes the version into the binary through
|
||||
|
||||
@@ -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
|
||||
# ... 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
|
||||
|
||||
Reference in New Issue
Block a user