oficina / home Public

make release: build a stamped linux-arm64 binary into releases/

Releases are published from a tag now, so the stamp a binary reports
from GET /api/version should be that tag. git describe --tags --always
resolves to it when the build sits on one and falls back to the short
sha it used to carry when it does not, so nothing is lost.

The artifact is named releases/<app>-linux-arm64 because amadan release
create uploads a file under its basename, and a release's files cannot
be deleted once they exist.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Paul Campbell pushed by paul@keymail.dev fc1959f7a872837c1ae5ccfbd99ad753a49a601d parent 4cbae5f
2 files changed, +44 −1
  • .gitignore +1 −0
  • Makefile +43 −1

CI passed — run details

diff --git a/.gitignore b/.gitignore
index 82408b5..0975d7c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,3 +18,4 @@
.superpowers/
writing/
+/releases/
diff --git a/Makefile b/Makefile
index 0059c25..ab3b822 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@ export GOPRIVATE := $(GOPRIVATE),amadan.net/oficina/estilo.git
private_comma := ,
export GOPRIVATE := $(if $(GOPRIVATE),$(GOPRIVATE)$(private_comma))amadan.net/oficina/estilo.git,amadan.net/carlos/platform.git
-.PHONY: build test test-vet test-fmt test-build test-go test-race
+.PHONY: build release test test-vet test-fmt test-build test-go test-race
# One binary, CGO_ENABLED=0, cgo-free SQLite (AGENTS.md / Deploys). Set
# per-target rather than exported globally, because test-race is a
@@ -12,6 +12,48 @@ export GOPRIVATE := $(if $(GOPRIVATE),$(GOPRIVATE)$(private_comma))amadan.net/of
build:
CGO_ENABLED=0 go build ./...
+# release is what ships, and it is the ONLY way a binary should be built
+# for shipping. rastrillo's BuildVersion defaults to "dev", so an
+# unstamped binary answers GET /api/version with "dev" from every build
+# ever made — and that is the field the deploy check compares, so an
+# unstamped release makes the check structurally incapable of failing
+# while still reporting green. A plain `go build` sent to an instance is
+# exactly the mistake this target removes.
+#
+# linux/arm64 because that is what the instances run; building for this
+# Mac and shipping it is a silent architecture mismatch that uploads
+# fine and fails to exec. Override for a one-off:
+# make release RELEASE_GOARCH=amd64
+#
+# -s -w drops the symbol table and DWARF. Panic traces keep their
+# function names and line numbers either way (pclntab is untouched);
+# what you lose is delve and gdb, so build without them for that.
+#
+# git describe --tags, because the tag is what gets published. A dirty
+# tree is refused rather than suffixed: a -dirty stamp names a commit
+# plus changes nobody can name, so two different binaries can carry the
+# identical string, which makes the check look reliable while it is not.
+# If you mean to ship uncommitted work, say so out loud:
+# make release VERSION=v0.1.0-wip
+APP := home
+RELEASE_GOOS ?= linux
+RELEASE_GOARCH ?= arm64
+RELEASE_BIN := releases/$(APP)-$(RELEASE_GOOS)-$(RELEASE_GOARCH)
+VERSION ?= $(shell git describe --tags --always 2>/dev/null)
+
+release:
+ @git diff --quiet && git diff --cached --quiet || \
+ { echo "refusing to build a release from a dirty tree"; exit 1; }
+ @test -n "$(VERSION)" || \
+ { echo "make release: no version to stamp; commit, or name it: make release VERSION=v0.1.0"; exit 1; }
+ @mkdir -p releases
+ CGO_ENABLED=0 GOOS=$(RELEASE_GOOS) GOARCH=$(RELEASE_GOARCH) go build -trimpath \
+ -ldflags "-s -w -X github.com/carlosframework/rastrillo.BuildVersion=$(VERSION)" \
+ -o $(RELEASE_BIN) ./cmd/$(APP)
+ @echo "built $(RELEASE_BIN) reporting version $(VERSION)"
+ @echo "publish it with:"
+ @echo " amadan release create -repo oficina/$(APP) -notes-file NOTES.md $(VERSION) $(RELEASE_BIN)"
+
# The gate, split into named targets so CI can report them individually
# (.amadan/ci.d calls these one at a time, each its own step). `make
# test` runs exactly the same things in the same order, so the local