From 0b726c52334d090b4455858603f158fbc3fd3c4b Mon Sep 17 00:00:00 2001 From: August Cayzer Date: Fri, 4 Sep 2026 11:47:08 +0100 Subject: [PATCH] fix: read the tag annotation checkout has not yet clobbered (#63) actions/checkout fetches the annotated tag and then force-updates refs/tags/ to the commit it checks out, leaving a lightweight tag. Both jobs that read the annotation read it after that, so verify refused every tag and the release notes would have been the commit message. The second is the failure that matters. Refusing a lightweight tag exists precisely because for-each-ref falls through to the commit message on one, and the guard was defeated by the same mechanism it guards against. Only the loud failure stopped it publishing. Both jobs now fetch the tag ref back before trusting it. fetch-depth: 0 does not help, because checkout's second fetch runs regardless. --- .github/workflows/release.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index dadd64b..d88f544 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -33,6 +33,18 @@ jobs: # The tag object itself is needed, not just the commit it points at. fetch-depth: 0 + - name: restore the annotated tag object + # actions/checkout fetches the real tag and then force-updates + # refs/tags/ to point straight at the commit it was told to check + # out, which leaves a lightweight tag behind: + # git fetch ... +refs/tags/*:refs/tags/* <- the annotated object + # git fetch ... +:refs/tags/ <- clobbers the ref + # Everything below reads the annotation, so fetch the ref back before + # trusting it. Without this the release notes silently become the + # commit message, which is precisely the failure the next step exists + # to catch. + run: git fetch --force origin "refs/tags/${GITHUB_REF_NAME}:refs/tags/${GITHUB_REF_NAME}" + - name: the tag and the version must agree run: | tag="${GITHUB_REF_NAME}" @@ -94,6 +106,18 @@ jobs: with: fetch-depth: 0 + - name: restore the annotated tag object + # actions/checkout fetches the real tag and then force-updates + # refs/tags/ to point straight at the commit it was told to check + # out, which leaves a lightweight tag behind: + # git fetch ... +refs/tags/*:refs/tags/* <- the annotated object + # git fetch ... +:refs/tags/ <- clobbers the ref + # Everything below reads the annotation, so fetch the ref back before + # trusting it. Without this the release notes silently become the + # commit message, which is precisely the failure the next step exists + # to catch. + run: git fetch --force origin "refs/tags/${GITHUB_REF_NAME}:refs/tags/${GITHUB_REF_NAME}" + - name: build the source tarball id: tarball run: |