Skip to content

Commit a7ab079

Browse files
sirtimidclaude
andauthored
fix(ci): simplify CI gate to prevent skip/re-run failures (#905)
## Summary The `all-jobs-complete` gate was duplicating each upstream job's `if` condition in bash to verify the right jobs ran. This mirrored logic got out of sync with the actual job conditions, causing two distinct failures: 1. **Merge queue skip**: when `check-skip-merge-queue` determined the PR was already up-to-date, gated jobs (`lint-build-test`, `analyse-code`, `check-workflows`) were correctly skipped by their own `if` conditions, but the gate still required `success` — so it failed. 2. **Partial re-runs**: when "Re-run failed jobs" was used, previously-succeeded jobs reported `skipped` instead of `success`, which the gate also rejected. This PR replaces the complex per-job validation with a simple loop that checks no dependency has `failure` or `cancelled` result. Each job's own `if` condition remains the single source of truth for when it runs — the gate just verifies nothing went wrong. Also simplifies `all-jobs-pass` by removing the redundant `check-skip-merge-queue` fallback, since `all-jobs-complete` now handles that case correctly via the transitive dependency chain. - Replaces ~35 lines of conditional bash with a ~10 line loop - Fixes the failure seen in [run 23651945359](https://github.com/MetaMask/ocap-kernel/actions/runs/23651945359/job/69214610408) - No new jobs need gate updates — just add them to the `needs` list ## Test plan The CI gate itself runs as part of this PR's checks. Verifying: - The `all-jobs-complete` and `all-jobs-pass` jobs both succeed on this PR - A docs-only or config-only PR still correctly skips code jobs without failing the gate 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes the CI gating logic in `.github/workflows/main.yml`, which could inadvertently allow failures through or block merges if misconfigured. Scope is limited to workflow result checking and does not touch product code. > > **Overview** > Simplifies the `all-jobs-complete` CI gate by replacing per-job conditional checks with a loop that fails only when a dependency job result is `failure` or `cancelled`, treating `skipped` as acceptable. > > Also tightens `all-jobs-pass` to depend solely on `all-jobs-complete`’s `passed` output, removing the extra merge-queue skip fallback logic. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 30a48c0. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent aa5e10b commit a7ab079

1 file changed

Lines changed: 19 additions & 36 deletions

File tree

.github/workflows/main.yml

Lines changed: 19 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -242,42 +242,28 @@ jobs:
242242
steps:
243243
- name: Set passed output
244244
id: set-output
245+
env:
246+
RESULTS: >-
247+
detect-changes=${{ needs.detect-changes.result }}
248+
check-skip-merge-queue=${{ needs.check-skip-merge-queue.result }}
249+
check-workflows=${{ needs.check-workflows.result }}
250+
analyse-code=${{ needs.analyse-code.result }}
251+
lint-build-test=${{ needs.lint-build-test.result }}
252+
lint-only=${{ needs.lint-only.result }}
245253
run: |
246-
# detect-changes must always succeed — without it we can't trust any outputs
247-
if [[ "${{ needs.detect-changes.result }}" != "success" ]]; then
248-
echo "detect-changes did not succeed"
249-
exit 1
250-
fi
251-
252-
HAS_CODE="${{ needs.detect-changes.outputs.has-code }}"
253-
HAS_CI="${{ needs.detect-changes.outputs.has-ci }}"
254-
HAS_LINT="${{ needs.detect-changes.outputs.has-lint-targets }}"
254+
echo "Job results: $RESULTS"
255255
256-
# If code changed, analyse-code and lint-build-test must have succeeded
257-
if [[ "$HAS_CODE" == "true" ]]; then
258-
if [[ "${{ needs.analyse-code.result }}" != "success" || "${{ needs.lint-build-test.result }}" != "success" ]]; then
259-
echo "Code jobs did not succeed"
256+
# Each job's own `if` condition controls whether it runs or is
257+
# skipped. This gate only needs to verify that nothing *failed*
258+
# or was *cancelled* — both "success" and "skipped" are acceptable.
259+
for entry in $RESULTS; do
260+
job="${entry%%=*}"
261+
result="${entry#*=}"
262+
if [[ "$result" == "failure" || "$result" == "cancelled" ]]; then
263+
echo "::error::$job did not succeed (result: $result)"
260264
exit 1
261265
fi
262-
fi
263-
264-
# check-workflows runs for both CI and code changes; require it when either is present
265-
# It is intentionally skipped when the merge queue decides to skip (PR already up-to-date)
266-
if [[ "$HAS_CI" == "true" || "$HAS_CODE" == "true" ]]; then
267-
if [[ "${{ needs.check-skip-merge-queue.outputs.skip-merge-queue }}" != "true" \
268-
&& "${{ needs.check-workflows.result }}" != "success" ]]; then
269-
echo "check-workflows did not succeed"
270-
exit 1
271-
fi
272-
fi
273-
274-
# If only lint targets changed (no code), lint-only must have succeeded
275-
if [[ "$HAS_CODE" != "true" && "$HAS_LINT" == "true" ]]; then
276-
if [[ "${{ needs.lint-only.result }}" != "success" ]]; then
277-
echo "Lint-only job did not succeed"
278-
exit 1
279-
fi
280-
fi
266+
done
281267
282268
echo "passed=true" >> "$GITHUB_OUTPUT"
283269
@@ -287,12 +273,9 @@ jobs:
287273
runs-on: ubuntu-latest
288274
needs:
289275
- all-jobs-complete
290-
- check-skip-merge-queue
291276
steps:
292277
- name: Check that all jobs have passed
293-
env:
294-
PASSED: ${{ needs.all-jobs-complete.outputs.passed == 'true' || needs.check-skip-merge-queue.outputs.skip-merge-queue == 'true' }}
295278
run: |
296-
if [[ "$PASSED" != "true" ]]; then
279+
if [[ "${{ needs.all-jobs-complete.outputs.passed }}" != "true" ]]; then
297280
exit 1
298281
fi

0 commit comments

Comments
 (0)