From 341ef34374445f9438a5851eabea33729dc467a9 Mon Sep 17 00:00:00 2001 From: Micheal Wilkinson Date: Sat, 21 Mar 2026 19:37:44 +0000 Subject: [PATCH] fix(publish): use tag's actual commit SHA for release target MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GITHUB_SHA (github.sha) reflects the workflow trigger commit, which is the main HEAD before the prepare job ran. The tag itself points to the release commit created by prepare — a different SHA. Gitea rejects PATCH and POST with 403 when target_commitish doesn't match the tag's commit. Use git rev-list -n 1 TAG to resolve the exact SHA the tag points to, ensuring the target field is always correct regardless of when or how the release workflow is called. --- publish/action.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/publish/action.yml b/publish/action.yml index ef4617f..134eaea 100644 --- a/publish/action.yml +++ b/publish/action.yml @@ -95,7 +95,6 @@ runs: RELEASE_NOTES_FILE: ${{ steps.write-notes.outputs.notes_file }} GITHUB_API_URL: ${{ github.api_url }} GITHUB_SERVER_URL: ${{ github.server_url }} - GITHUB_SHA: ${{ github.sha }} GITHUB_REPOSITORY: ${{ github.repository }} run: | set -euo pipefail @@ -105,6 +104,12 @@ runs: exit 1 fi + # Resolve the exact commit SHA the tag points to. Using git rev-list + # rather than github.sha avoids the common mismatch where the workflow + # was triggered from a pre-release commit but the tag was created on + # the subsequent release commit by the prepare job. + tag_sha="$(git rev-list -n 1 "${TAG_NAME}")" + release_notes="$(cat "$RELEASE_NOTES_FILE")" escaped_release_notes="$(printf '%s' "$release_notes" | sed 's/\\/\\\\/g; s/"/\\"/g; :a;N;$!ba;s/\n/\\n/g')" release_api="${GITHUB_API_URL:-${GITHUB_SERVER_URL%/}/api/v1}/repos/${GITHUB_REPOSITORY}/releases" @@ -128,7 +133,7 @@ runs: -H "Authorization: token ${TOKEN}" \ -H "Content-Type: application/json" \ "${release_api}/${existing_release_id}" \ - --data "{\"tag_name\":\"${TAG_NAME}\",\"target\":\"${GITHUB_SHA}\",\"name\":\"${TAG_NAME}\",\"body\":\"${escaped_release_notes}\",\"draft\":false,\"prerelease\":false}" \ + --data "{\"tag_name\":\"${TAG_NAME}\",\"target\":\"${tag_sha}\",\"name\":\"${TAG_NAME}\",\"body\":\"${escaped_release_notes}\",\"draft\":false,\"prerelease\":false}" \ --output release.json echo "id=$existing_release_id" >> "$GITHUB_OUTPUT" @@ -142,7 +147,7 @@ runs: -H "Authorization: token ${TOKEN}" \ -H "Content-Type: application/json" \ "${release_api}" \ - --data "{\"tag_name\":\"${TAG_NAME}\",\"target\":\"${GITHUB_SHA}\",\"name\":\"${TAG_NAME}\",\"body\":\"${escaped_release_notes}\",\"draft\":false,\"prerelease\":false}" \ + --data "{\"tag_name\":\"${TAG_NAME}\",\"target\":\"${tag_sha}\",\"name\":\"${TAG_NAME}\",\"body\":\"${escaped_release_notes}\",\"draft\":false,\"prerelease\":false}" \ --output release.json release_id="$(sed -n 's/.*"id"[[:space:]]*:[[:space:]]*\([0-9][0-9]*\).*/\1/p' release.json | head -n 1)"