From c39f11fda7f2efd41a82a476cca8092fe685f741 Mon Sep 17 00:00:00 2001 From: Joakim Olsson Date: Tue, 12 May 2026 13:19:00 +0000 Subject: [PATCH] fix(release): poll branch readiness before .version write (#22) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Why Release workflow intermittently failed at the `.version` write step with `exit 22` and no diagnostic output. The CHANGELOG.md PUT creates the `next-release` branch via the `new_branch` parameter, then the `.version` PUT fires ~2s later — racing Gitea's branch indexing. Because the call used `curl -sf` (fail-silent), 404/409 responses produced exit 22 with no body, leaving logs unhelpful. ## Changes - Move the existing branch-readiness poll to run **right after** the CHANGELOG.md commit, before `.version` is written. - Replace the silent `.version` write with a 5-attempt retry loop that logs HTTP code and body on failure (same pattern already used for PR creation). ## Test plan - [ ] Trigger Release.yml on a repo with a pending changelog entry; confirm `.version` write succeeds first try and PR is created. - [ ] If a transient failure happens, log now shows HTTP code + body. Reviewed-on: https://gitea.unbound.se/unboundsoftware/shared-workflows/pulls/22 --- .gitea/workflows/Release.yml | 79 ++++++++++++++++++++++-------------- 1 file changed, 48 insertions(+), 31 deletions(-) diff --git a/.gitea/workflows/Release.yml b/.gitea/workflows/Release.yml index 562d9ef..99e3e73 100644 --- a/.gitea/workflows/Release.yml +++ b/.gitea/workflows/Release.yml @@ -158,37 +158,7 @@ jobs: exit 1 fi - # Check if .version exists on base branch - VERSION_SHA=$(curl -sf --retry 3 --retry-delay 2 --retry-connrefused \ - -H "Authorization: token ${TOKEN}" \ - "${API_URL}/contents/.version?ref=${BASE_BRANCH}" | jq -r '.sha // empty') - - if [ -n "${VERSION_SHA}" ]; then - echo "Updating .version on next-release branch..." - curl -sf --retry 3 --retry-delay 2 --retry-connrefused -X PUT \ - -H "Authorization: token ${TOKEN}" \ - -H "Content-Type: application/json" \ - --data "$(jq -n \ - --arg content "${VERSION_CONTENT}" \ - --arg sha "${VERSION_SHA}" \ - --arg message "${TITLE}" \ - --arg branch "next-release" \ - '{content: $content, sha: $sha, message: $message, branch: $branch}')" \ - "${API_URL}/contents/.version" - else - echo "Creating .version on next-release branch..." - curl -sf --retry 3 --retry-delay 2 --retry-connrefused -X POST \ - -H "Authorization: token ${TOKEN}" \ - -H "Content-Type: application/json" \ - --data "$(jq -n \ - --arg content "${VERSION_CONTENT}" \ - --arg message "${TITLE}" \ - --arg branch "next-release" \ - '{content: $content, message: $message, branch: $branch}')" \ - "${API_URL}/contents/.version" - fi - - echo "Creating new PR..." + # Wait for next-release branch to be indexed by Gitea before subsequent writes echo "Waiting for next-release branch to be ready..." for i in $(seq 1 10); do BRANCH_STATUS=$(curl -s --retry 3 --retry-delay 2 --retry-connrefused \ @@ -207,6 +177,53 @@ jobs: sleep 3 done + # Check if .version exists on base branch + VERSION_SHA=$(curl -sf --retry 3 --retry-delay 2 --retry-connrefused \ + -H "Authorization: token ${TOKEN}" \ + "${API_URL}/contents/.version?ref=${BASE_BRANCH}" | jq -r '.sha // empty') + + if [ -n "${VERSION_SHA}" ]; then + echo "Updating .version on next-release branch..." + VERSION_PAYLOAD=$(jq -n \ + --arg content "${VERSION_CONTENT}" \ + --arg sha "${VERSION_SHA}" \ + --arg message "${TITLE}" \ + --arg branch "next-release" \ + '{content: $content, sha: $sha, message: $message, branch: $branch}') + VERSION_METHOD=PUT + else + echo "Creating .version on next-release branch..." + VERSION_PAYLOAD=$(jq -n \ + --arg content "${VERSION_CONTENT}" \ + --arg message "${TITLE}" \ + --arg branch "next-release" \ + '{content: $content, message: $message, branch: $branch}') + VERSION_METHOD=POST + fi + + for i in $(seq 1 5); do + RESPONSE=$(curl -s --retry 3 --retry-delay 2 --retry-connrefused \ + -w "\n%{http_code}" -X "${VERSION_METHOD}" \ + -H "Authorization: token ${TOKEN}" \ + -H "Content-Type: application/json" \ + --data "${VERSION_PAYLOAD}" \ + "${API_URL}/contents/.version") + HTTP_CODE=$(echo "${RESPONSE}" | tail -1) + BODY=$(echo "${RESPONSE}" | sed '$d') + if [ "${HTTP_CODE}" -lt 400 ]; then + echo ".version write succeeded" + break + fi + if [ "${i}" = "5" ]; then + echo "Error writing .version after 5 attempts (HTTP ${HTTP_CODE}): ${BODY}" + exit 1 + fi + echo ".version write attempt ${i}/5 failed (HTTP ${HTTP_CODE}): ${BODY} — retrying..." + sleep 3 + done + + echo "Creating new PR..." + PR_DATA=$(jq -n \ --arg title "${TITLE}" \ --arg body "${DESCRIPTION}" \