# ── Configuration ───────────────────────────────────────────────────────────── REGISTRY := code.nochebuena.dev/einherjar/spa-server BASE_IMAGE := alpine:3.21 # ── Git metadata ────────────────────────────────────────────────────────────── BRANCH := $(shell git rev-parse --abbrev-ref HEAD 2>/dev/null || echo unknown) SHA := $(shell git rev-parse --short HEAD 2>/dev/null || echo unknown) # Highest semver tag pointing at HEAD; falls back to the most recent reachable tag. _TAG_AT_HEAD := $(shell git tag --points-at HEAD 2>/dev/null | sort -V | tail -1) VERSION := $(if $(_TAG_AT_HEAD),$(_TAG_AT_HEAD),$(shell git describe --tags --abbrev=0 2>/dev/null || echo v0.0.0)) # ── Branch suffix ───────────────────────────────────────────────────────────── # main → (none) # develop → -dev- # release/* → -qa- # other → -dev- # # Note: case/esac cannot be used inside $(shell) — the pattern delimiters ")" # are mistaken by Make's parser for the closing paren of the function call. # if/elif is used instead. BRANCH_SUFFIX := $(shell \ b='$(BRANCH)'; s='$(SHA)'; \ if [ "$$b" = "main" ]; then \ echo ""; \ elif [ "$$b" = "develop" ]; then \ echo "-dev-$$s"; \ elif echo "$$b" | grep -q "^release/"; then \ echo "-qa-$$s"; \ else \ echo "-dev-$$s"; \ fi) # ── Image tags ──────────────────────────────────────────────────────────────── VERSIONED_TAG := $(REGISTRY):$(VERSION)$(BRANCH_SUFFIX) LATEST_TAG := $(if $(filter main,$(BRANCH)),$(REGISTRY):latest,) ALL_TAGS := $(strip $(VERSIONED_TAG) $(LATEST_TAG)) TAG_FLAGS := $(foreach t,$(ALL_TAGS),--tag $(t) ) # ── Targets ─────────────────────────────────────────────────────────────────── .DEFAULT_GOAL := dry-run .PHONY: dry-run build push release help ## dry-run : show what would be built and pushed — no side effects. dry-run: @echo "" @echo " Registry : $(REGISTRY)" @echo " Branch : $(BRANCH)" @echo " SHA : $(SHA)" @echo " Version : $(VERSION)" @echo "" @echo " Tags:" @$(foreach t,$(ALL_TAGS),echo " $(t)";) @echo "" @echo " Build args:" @echo " VERSION = $(VERSION)" @echo " GIT_SHA = $(SHA)" @BASE=$$(docker inspect --format='{{index .RepoDigests 0}}' $(BASE_IMAGE) 2>/dev/null | head -1); \ echo " BASE_DIGEST = $${BASE:-(not resolved — run: docker pull $(BASE_IMAGE))}" @echo "" ## build : build the image with all computed tags and OCI labels. build: docker build \ $(TAG_FLAGS) \ --build-arg VERSION=$(VERSION) \ --build-arg GIT_SHA=$(SHA) \ --build-arg BASE_DIGEST=$$(docker inspect --format='{{index .RepoDigests 0}}' $(BASE_IMAGE) 2>/dev/null | head -1) \ . ## push : push all computed tags to the registry. push: @for tag in $(ALL_TAGS); do \ echo "→ pushing $$tag"; \ docker push $$tag || exit 1; \ done ## release : build then push. release: build push ## help : list available targets. help: @grep -E '^## ' Makefile | sed 's/^## / /'