REGISTRY := git.ryuvia.com # The personal namespace, not ryuvia — deliberately, and for one reason: Gitea # scopes package visibility to the owner with no per-package override, so # ryuvia/* is private because the org is. Publishing here keeps the image and # chart anonymously pullable, so no pull secret is needed in the cluster and # Flux needs no registry credentials. Same choice riksdata and rd-web made. OWNER := niklas IMAGE := $(REGISTRY)/$(OWNER)/terdut-server HELM_CHART := charts/terdut-server HELM_REPO := oci://$(REGISTRY)/$(OWNER) # go.mod pins an exact patch release so nobody builds the shipped binary with a # toolchain carrying known stdlib CVEs. Fedora's Go package overrides the # upstream GOTOOLCHAIN default to `local`, which turns that pin into a hard # failure on a dev box one patch behind, so restore the upstream default here. export GOTOOLCHAIN ?= auto .PHONY: help help: ## Show this help @grep -hE '^[a-zA-Z_-]+:.*?## ' $(MAKEFILE_LIST) | \ awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-22s\033[0m %s\n", $$1, $$2}' ## --- checks --- # # These three mirror .gitea/workflows/ci.yaml step for step, so a green `make fmt # lint test` here means the same thing CI means. The one deliberate difference is # -race below. .PHONY: test test: ## Run the test suite go test -race ./... # CI runs a bare `go test ./...`. This is stricter on purpose: the sweeper, the # notifier goroutine and the deadman sweep all touch the same single-connection # database, and a race there would surface as a flaky production incident rather # than a failed build. It passes today; if it ever costs more than it catches, # the honest fix is to teach CI -race too, not to quietly drop it here. .PHONY: lint lint: ## go vet go vet ./... # Copied from ci.yaml rather than simplified, because both of gofmt's failure # modes need handling and they are not alike. A file that is merely misformatted # is listed on stdout with exit 0 — so the failure has to be raised by hand. A # file that does not parse is the opposite: nothing on stdout and exit 2, which a # naive `[ -n "$$out" ]` reads as success. See 9046f6e. .PHONY: fmt fmt: ## Report unformatted files @if ! unformatted=$$(gofmt -l .); then \ echo "gofmt could not parse the tree:"; gofmt -l .; exit 1; \ fi; \ if [ -n "$$unformatted" ]; then \ echo "gofmt needed:"; echo "$$unformatted"; gofmt -d .; exit 1; \ fi .PHONY: helm-lint helm-lint: ## Lint and render the chart helm lint $(HELM_CHART) --set image.tag=v0.0.0 helm template terdut-server $(HELM_CHART) --namespace terdut-server \ --set image.tag=v0.0.0 >/dev/null @# networking.listener defaults to "", which attaches the route to every @# matching listener including plaintext HTTP. Production sets it, so the @# default render proves nothing about the path that actually ships. helm template terdut-server $(HELM_CHART) --namespace terdut-server \ --set image.tag=v0.0.0 --set networking.listener=https-terdut >/dev/null ## --- release --- # The release process (~/.claude/skills/release) reads these rather than restating them. # One definition, so the version that gets tagged, the image that gets pushed and the chart # the wrapper pins cannot drift apart in a second copy. .PHONY: release-vars release-vars: ## Print the variables the release process reads @printf 'IMAGE=%s\nHELM_CHART=%s\nHELM_REPO=%s\n' '$(IMAGE)' '$(HELM_CHART)' '$(HELM_REPO)' # There is deliberately no build/push/helm-package/helm-push/release here, unlike # riksdata and rd-web. .gitea/workflows/release.yaml owns publishing for this repo, # and it does two things a local make cannot: it builds linux/amd64 and linux/arm64 # through buildx, and it stamps the chart's version and appVersion from the tag. A # `docker build && docker push` target would push a single-architecture image over # the multi-arch tag, which is both easy to do by accident and invisible afterwards # — the tag would still resolve, just not on arm64. Publishing happens by pushing a # tag; nothing else.