From 324e7f957add5266ad55c1a3b34599b04c0fcabe Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Wed, 26 Aug 2026 16:39:02 +0200 Subject: [PATCH] End the eligibility step on an explicit exit 0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All twelve checks ran and the verdict was recorded, but the step still failed. Its exit code is that of its last command, and the last one to run was the test on UNKNOWN: with no errored check that variable is empty, the test returns 1, and the step fails on a perfectly normal outcome. The step reports a verdict, it does not pass or fail on it — eligibility is carried by the output. Reproduced against #3366: same verdict either way, exit 1 before, exit 0 after. The other five steps across both workflows were not affected but get the same explicit ending, so no step's result depends on whichever command happens to be last. --- .github/workflows/automerge-cron.yml | 9 +++++++++ .github/workflows/automerge-eligibility.yml | 13 +++++++++++++ 2 files changed, 22 insertions(+) diff --git a/.github/workflows/automerge-cron.yml b/.github/workflows/automerge-cron.yml index f3abc0d4a6..705f2ad255 100644 --- a/.github/workflows/automerge-cron.yml +++ b/.github/workflows/automerge-cron.yml @@ -88,6 +88,8 @@ jobs: echo "Today ($TODAY) is outside the absence period ($START → $END)" echo "suspended=false" >> "$GITHUB_OUTPUT" + exit 0 + - name: Merge what is eligible and ripe id: merge env: @@ -230,6 +232,11 @@ jobs: echo "failed_list<> "$GITHUB_OUTPUT" + # Explicit, so the step's result never depends on whichever command + # happens to be last. A merge that failed is reported through + # failed_list and the Slack alert, not by failing this step. + exit 0 + - name: Post the daily recap to Slack if: always() && inputs.dry_run != true env: @@ -288,3 +295,5 @@ jobs: -H "Content-type: application/json; charset=utf-8" \ -d "$(jq -n --arg channel "$SLACK_CHANNEL" --arg text "$TEXT" '{channel: $channel, text: $text}')" \ > /dev/null || echo "Slack notification failed (non-blocking)" + + exit 0 diff --git a/.github/workflows/automerge-eligibility.yml b/.github/workflows/automerge-eligibility.yml index 4a827de994..4b3bf5150c 100644 --- a/.github/workflows/automerge-eligibility.yml +++ b/.github/workflows/automerge-eligibility.yml @@ -171,6 +171,15 @@ jobs: echo "**Eligible.** All checks passed." >> "$GITHUB_STEP_SUMMARY" fi + # The step's exit code is that of its last command, and the last one to + # run above is `[ -n "$UNKNOWN" ]`. When no check errored — the normal + # case — that test is false and returns 1, failing the step even though + # every check ran and the verdict was recorded. + # + # This step reports a verdict; it does not pass or fail on it. Whether + # the PR is eligible is carried by the `eligible` output. + exit 0 + - name: Update the eligibility label if: steps.scope.outputs.in_scope == 'true' id: label @@ -208,6 +217,8 @@ jobs: echo "newly_eligible=false" >> "$GITHUB_OUTPUT" fi + exit 0 + # The veto window. Posted once, when a PR first becomes eligible, roughly # 24 hours before the cron merges it. # @@ -261,3 +272,5 @@ jobs: -H "Content-type: application/json; charset=utf-8" \ -d "$(jq -n --arg channel "$SLACK_CHANNEL" --arg text "$TEXT" '{channel: $channel, text: $text}')" \ > /dev/null || echo "Slack notification failed (non-blocking)" + + exit 0