From b5fe8f542d23c6ff769403479283c77b8343d279 Mon Sep 17 00:00:00 2001 From: ffranr Date: Thu, 27 Nov 2025 21:18:56 +0000 Subject: [PATCH] Makefile: add release-tag target with SemVer validation Add a `release-tag` target to the Makefile, mirroring the approach used in taproot-assets. This target creates a signed Git tag derived from `version.go`, and validates that it conforms to Semantic Versioning. This prevents tagging with an invalid or non-compliant version. --- Makefile | 17 +++++++++++++ scripts/get-git-tag-name.sh | 51 +++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100755 scripts/get-git-tag-name.sh diff --git a/Makefile b/Makefile index f698ec9cb..5e16093f6 100644 --- a/Makefile +++ b/Makefile @@ -10,6 +10,7 @@ GOIMPORTS_PKG := github.com/rinchsan/gosimports/cmd/gosimports GO_BIN := ${GOPATH}/bin GOIMPORTS_BIN := $(GO_BIN)/gosimports +VERSION_GO_FILE := "version.go" GOBUILD := CGO_ENABLED=0 GO111MODULE=on go build -v GOINSTALL := CGO_ENABLED=0 GO111MODULE=on go install -v @@ -86,6 +87,22 @@ docker-release: docker-release-builder @if [ "$(tag)" = "" ]; then echo "Must specify tag=!"; exit 1; fi $(DOCKER_RELEASE_BUILDER) bash release.sh $(tag) +# release-tag: Create a signed Git tag from version.go if valid +# Derives the tag name from version.go, validates that it conforms to +# Semantic Versioning (SemVer), and creates a signed Git tag. Ensures +# the tag matches the version declared in version.go to avoid accidental +# or incorrect releases. +release-tag: + @$(call print, "Adding release tag.") + + tag=$$(./scripts/get-git-tag-name.sh ${VERSION_GO_FILE}); \ + exit_status=$$?; \ + if [ $$exit_status -ne 0 ]; then \ + echo "Script encountered an error with exit status $$exit_status."; \ + fi; \ + echo "Adding git tag: $$tag"; \ + git tag -as -m "Tag generated using command \`make release-tag\`." "$$tag"; + rpc: @$(call print, "Compiling protos.") cd ./swapserverrpc; ./gen_protos_docker.sh diff --git a/scripts/get-git-tag-name.sh b/scripts/get-git-tag-name.sh new file mode 100755 index 000000000..cb11941f2 --- /dev/null +++ b/scripts/get-git-tag-name.sh @@ -0,0 +1,51 @@ +#!/bin/bash + +# Derive a git tag name from the version fields defined in the given Go file. + +set -e + +get_git_tag_name() { + local file_path="$1" + + if [ ! -f "$file_path" ]; then + echo "Error: File not found at $file_path" >&2 + exit 1 + fi + + local app_major + app_major=$(grep -oP 'appMajor\s*uint\s*=\s*\K\d+' "$file_path") + + local app_minor + app_minor=$(grep -oP 'appMinor\s*uint\s*=\s*\K\d+' "$file_path") + + local app_patch + app_patch=$(grep -oP 'appPatch\s*uint\s*=\s*\K\d+' "$file_path") + + local app_pre_release + app_pre_release=$(grep -oP 'appPreRelease\s*=\s*"\K([A-Za-z0-9.-]*)' "$file_path") + + if [ -z "$app_major" ] || [ -z "$app_minor" ] || [ -z "$app_patch" ]; then + echo "Error: Could not parse version constants from $file_path" >&2 + exit 1 + fi + + local tag_name="v${app_major}.${app_minor}.${app_patch}" + + if [ -n "$app_pre_release" ]; then + tag_name+="-${app_pre_release}" + fi + + echo "$tag_name" +} + +file_path="$1" +echo "Reading version fields from file: $file_path" >&2 +tag_name=$(get_git_tag_name "$file_path") +echo "Derived git tag name: $tag_name" >&2 + +if ! [[ "$tag_name" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$ ]]; then + echo "Error: Derived tag \"$tag_name\" is not semver compliant" >&2 + exit 1 +fi + +echo "$tag_name"