From 8ec0c2685c6f2f758044b71f282794cc6107665a Mon Sep 17 00:00:00 2001 From: fOuttaMyPaint <154358121+TMHSDigital@users.noreply.github.com> Date: Sat, 25 Apr 2026 14:24:24 -0400 Subject: [PATCH] fix: release.yml tag introspection and add floating tag automation Fixes two related bugs in release.yml: DTD#23: git describe --tags --abbrev=0 was used to find the latest tag for VERSION comparison. This returns the highest reachable tag (which can be a floating tag like v1.0 aliased to a commit), not the highest semver patch tag. When v1.0 was an annotated tag aliasing v1.8.2, the comparison broke entirely. Replaces with git for-each-ref --sort=-v:refname filtered to the semver pattern v[0-9]*.[0-9]*.[0-9]*. This returns clean semver output regardless of what floating tags exist. DTD#14: floating major.minor and major tags (v1.7, v1.0) had to be force-updated manually after each release. Adds an automated step that creates/updates vMAJOR.MINOR and vMAJOR lightweight tags pointing at the commit of the just-pushed patch tag. Both as lightweight tags (matches actions/checkout convention, avoids the alias bug that DTD#4's investigation surfaced). The floating tags are explicitly resolved through ^{commit} so the lightweight refs point at the underlying commit, not at the annotated patch tag's tag object. Closes #14, #23. Signed-off-by: 154358121+TMHSDigital@users.noreply.github.com Made-with: Cursor --- .github/workflows/release.yml | 35 ++++++++++++++++++++++++++++++++++- VERSION | 2 +- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e194f7b..d388bb2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -55,7 +55,14 @@ jobs: exit 1 fi - LATEST_TAG="$(git describe --tags --abbrev=0 2>/dev/null || echo '')" + # DTD#23: walk tag refs sorted by semver, filtered to the + # vMAJOR.MINOR.PATCH pattern. Excludes floating tags like v1 + # and v1.7 (which lack the third segment) so the comparison + # cannot be confused by an aliased or stale floating tag. + # Glob is fnmatch: '[0-9]*' matches a digit followed by + # anything, so vX.Y.Z and pre-releases (vX.Y.Z-rc1) match + # while vX, vX.Y do not. + LATEST_TAG="$(git for-each-ref --sort=-v:refname --format='%(refname:short)' 'refs/tags/v[0-9]*.[0-9]*.[0-9]*' | head -n1)" LATEST_VERSION="${LATEST_TAG#v}" echo "VERSION file: $VERSION" @@ -125,6 +132,32 @@ jobs: git tag -a "$TAG" -m "Release $TAG" git push origin "$TAG" + - name: Update floating major and major.minor tags + env: + TAG: ${{ needs.check-version.outputs.tag }} + VERSION: ${{ needs.check-version.outputs.version }} + run: | + set -euo pipefail + # DTD#14: maintain vMAJOR and vMAJOR.MINOR floating tags + # automatically. Both patterns are in production: drift-check + # consumers pin @v1.7 (MAJOR.MINOR train), release-doc-sync + # consumers pin @v1 (MAJOR train). + MAJOR="${VERSION%%.*}" + REST="${VERSION#*.}" + MINOR="${REST%%.*}" + + # Resolve the patch tag to its commit. Required because a + # bare 'git tag -f FLOAT ANNOTATED_TAG' would create a tag + # pointing to the annotated tag object, not the commit - + # the same alias-shape that broke DTD#4. + PATCH_COMMIT="$(git rev-parse "${TAG}^{commit}")" + + for FLOAT in "v${MAJOR}.${MINOR}" "v${MAJOR}"; do + git tag -f "$FLOAT" "$PATCH_COMMIT" + git push -f origin "$FLOAT" + echo "Updated $FLOAT -> $PATCH_COMMIT" + done + - name: Assemble release notes id: notes env: diff --git a/VERSION b/VERSION index a7ee35a..bfa363e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.8.3 +1.8.4