diff --git a/.github/workflows/release-xmemo-skill.yml b/.github/workflows/release-xmemo-skill.yml index 57fc827..bdc371d 100644 --- a/.github/workflows/release-xmemo-skill.yml +++ b/.github/workflows/release-xmemo-skill.yml @@ -205,24 +205,30 @@ jobs: echo "Announcement accepted: HTTP $http_code" break ;; - 4*) - echo "Announcement rejected with HTTP $http_code; not retrying." >&2 + 000 | 408 | 429 | 5*) + # A transport failure, a timeout, a rate limit, or a server + # error can each succeed later, so these share the retry + # handling below. + : ;; + *) + # Any other answer will not become a 2xx on retry, so it is + # reported at once instead of retried until the step times out. + echo "Announcement rejected with HTTP ${http_code:-none}; not retrying." >&2 head -c 500 "$response_body" >&2 || true echo >&2 exit 1 ;; - *) - if [[ "$attempt" -ge "$max_attempts" ]]; then - echo "Announcement failed after $attempt attempts (last status: ${http_code:-none})." >&2 - head -c 500 "$response_body" >&2 || true - echo >&2 - exit 1 - fi - echo "Announcement attempt $attempt failed (status: ${http_code:-none}); retrying." >&2 - sleep "$((attempt * 3))" - attempt=$((attempt + 1)) - ;; esac + + if [[ "$attempt" -ge "$max_attempts" ]]; then + echo "Announcement failed after $attempt attempts (last status: ${http_code:-none})." >&2 + head -c 500 "$response_body" >&2 || true + echo >&2 + exit 1 + fi + echo "Announcement attempt $attempt failed (status: ${http_code:-none}); retrying." >&2 + sleep "$((attempt * 3))" + attempt=$((attempt + 1)) done - name: Verify xmemo.dev serves this release diff --git a/test/release-workflow.test.js b/test/release-workflow.test.js index 086b370..1e24848 100644 --- a/test/release-workflow.test.js +++ b/test/release-workflow.test.js @@ -25,7 +25,12 @@ test('the Skill release announcement fails fast instead of retrying a rejection' const workflow = await readFile(workflowPath, 'utf8'); assert.doesNotMatch(workflow, /--retry-all-errors/); - assert.match(workflow, /Announcement rejected with HTTP \$http_code; not retrying\./); + assert.match(workflow, /Announcement rejected with HTTP \$\{http_code:-none\}; not retrying\./); + + // Retrying every error turned one rejection into four identical rejections + // followed by an opaque failure. Only answers that can plausibly change on a + // second attempt are retried. + assert.match(workflow, /000 \| 408 \| 429 \| 5\*\)/); }); test('the Skill release is verified against the public endpoint before it is called done', async () => {