diff --git a/Makefile b/Makefile index e75b982..e436bac 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,8 @@ CMD_SERVER := ./cmd/amcs-server BUILDINFO_PKG := git.warky.dev/wdevs/amcs/internal/buildinfo UI_DIR := $(CURDIR)/ui PATCH_INCREMENT ?= 1 +RELEASE_VERSION ?= +RELEASE_REMOTE ?= origin VERSION_TAG ?= $(shell git describe --tags --exact-match 2>/dev/null || echo dev) COMMIT_SHA ?= $(shell git rev-parse --short HEAD 2>/dev/null || echo unknown) BUILD_DATE ?= $(shell date -u +%Y-%m-%dT%H:%M:%SZ) @@ -20,7 +22,7 @@ LDFLAGS := -s -w \ -X $(BUILDINFO_PKG).Commit=$(COMMIT_SHA) \ -X $(BUILDINFO_PKG).BuildDate=$(BUILD_DATE) -.PHONY: all build clean migrate release-version test generate-migrations generate-models check-schema-drift build-cli ui-install ui-build ui-dev ui-check help +.PHONY: all build clean migrate release-version release-build test generate-migrations generate-models check-schema-drift build-cli ui-install ui-build ui-dev ui-check help all: build @@ -31,7 +33,8 @@ help: @echo " test Run all tests (includes UI check)" @echo " clean Remove build artifacts" @echo " migrate Run database migrations" - @echo " release-version Tag and push a new patch release (PATCH_INCREMENT=N)" + @echo " release-version Tag and push a release (auto patch bump or RELEASE_VERSION=vX.Y.Z)" + @echo " release-build Build with a specific release tag (RELEASE_VERSION=vX.Y.Z)" @echo " generate-migrations Generate SQL migration from DBML schema files" @echo " generate-models Generate Go models from DBML schema" @echo " check-schema-drift Verify generated migration matches current schema" @@ -64,22 +67,41 @@ release-version: @case "$(PATCH_INCREMENT)" in \ ''|*[!0-9]*|0) echo "PATCH_INCREMENT must be a positive integer" >&2; exit 1 ;; \ esac - @latest=$$(git tag --list 'v[0-9]*.[0-9]*.[0-9]*' --sort=-v:refname | head -n 1); \ - if [ -z "$$latest" ]; then latest="v0.0.0"; fi; \ - version=$${latest#v}; \ - major=$${version%%.*}; \ - rest=$${version#*.}; \ - minor=$${rest%%.*}; \ - patch=$${rest##*.}; \ - next_patch=$$((patch + $(PATCH_INCREMENT))); \ - next_tag="v$$major.$$minor.$$next_patch"; \ + @if ! git diff --quiet || ! git diff --cached --quiet; then \ + echo "Refusing to release from a dirty working tree. Commit or stash changes first." >&2; \ + exit 1; \ + fi + @next_tag="$(RELEASE_VERSION)"; \ + if [ -z "$$next_tag" ]; then \ + latest=$$(git tag --list 'v[0-9]*.[0-9]*.[0-9]*' --sort=-v:refname | head -n 1); \ + if [ -z "$$latest" ]; then latest="v0.0.0"; fi; \ + version=$${latest#v}; \ + major=$${version%%.*}; \ + rest=$${version#*.}; \ + minor=$${rest%%.*}; \ + patch=$${rest##*.}; \ + next_patch=$$((patch + $(PATCH_INCREMENT))); \ + next_tag="v$$major.$$minor.$$next_patch"; \ + fi; \ + case "$$next_tag" in \ + v[0-9]*.[0-9]*.[0-9]*) ;; \ + *) echo "RELEASE_VERSION must look like vX.Y.Z (got '$$next_tag')" >&2; exit 1 ;; \ + esac; \ if git rev-parse -q --verify "refs/tags/$$next_tag" >/dev/null; then \ echo "$$next_tag already exists" >&2; \ exit 1; \ fi; \ git tag -a "$$next_tag" -m "Release $$next_tag"; \ - git push origin "$$next_tag"; \ - echo "$$next_tag" + git push $(RELEASE_REMOTE) "$$next_tag"; \ + $(MAKE) release-build RELEASE_VERSION="$$next_tag"; \ + echo "Released $$next_tag" + +release-build: + @case "$(RELEASE_VERSION)" in \ + v[0-9]*.[0-9]*.[0-9]*) ;; \ + *) echo "RELEASE_VERSION must look like vX.Y.Z" >&2; exit 1 ;; \ + esac + @$(MAKE) build build-cli VERSION_TAG="$(RELEASE_VERSION)" migrate: ./scripts/migrate.sh