From bed0d47d39211f063de7a3d10a8e270d6b7e0819 Mon Sep 17 00:00:00 2001 From: MotherSphere Date: Thu, 27 Aug 2026 23:55:49 +0200 Subject: [PATCH] fix(release): suppress the implicit success() that kept skipping the build The second recovery dispatch still built nothing, with the same shape as the first: `target` succeeded and `build`, `sign` and `aur` skipped while the run reported success. Naming the dependencies explicitly in #73 was necessary but not sufficient. A job `if:` that contains no status-check function gets an implicit `success()` ANDed onto it, and that `success()` is evaluated over the whole ancestor graph rather than the direct `needs`. `release-please` is skipped on a dispatch, so the implicit `success()` was false and the job skipped no matter what the explicit condition said. The evidence was already in the file: `target` carries `!cancelled() && !failure()` and RAN despite the skipped ancestor, while `build` carried only `needs.target.result == 'success'` and skipped even though `target` had succeeded. Naming any status function suppresses the implicit one, so `!cancelled()` on each downstream job lets the explicit conditions govern. The explicit conditions from #73 are what make that safe to do: `!cancelled()` alone would run these jobs after a FAILED dependency, which is exactly what the per-dependency checks prevent. The two changes only work together. --- .github/workflows/release-please.yml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index 89afbf7..112c2bc 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -114,7 +114,13 @@ jobs: # clear the skip inherited from `release-please` for the jobs after it. # Without this, a recovery dispatch resolves the tag and then silently # builds nothing - which is exactly what the first v0.10.0 dispatch did. - if: ${{ needs.target.result == 'success' }} + # `!cancelled()` is load-bearing, not decoration. A job `if:` containing NO + # status-check function gets an implicit `success()` ANDed onto it, and that + # `success()` accounts for the whole ancestor graph - so the skipped + # `release-please` made it false and this job skipped even though its own + # condition was true and its direct dependency had succeeded. Naming any + # status function suppresses the implicit one. + if: ${{ !cancelled() && needs.target.result == 'success' }} runs-on: ${{ matrix.os }} strategy: fail-fast: false @@ -237,7 +243,7 @@ jobs: needs: [target, build] # Every dependency named explicitly. Guarding on `target` alone would let # this run after a FAILED build and try to sign assets that do not exist. - if: ${{ needs.target.result == 'success' && needs.build.result == 'success' }} + if: ${{ !cancelled() && needs.target.result == 'success' && needs.build.result == 'success' }} runs-on: ubuntu-latest env: # Single source of truth for the four launcher assets. Declared once so the @@ -332,7 +338,7 @@ jobs: needs: [target, sign] # `sign` too: without it, a failed signing job would still bump the AUR # package to a release that has no signatures. - if: ${{ needs.target.result == 'success' && needs.sign.result == 'success' }} + if: ${{ !cancelled() && needs.target.result == 'success' && needs.sign.result == 'success' }} uses: ./.github/workflows/aur-publish.yml with: tag: ${{ needs.target.outputs.tag }}