From 7030267751aa8ea5954541fb15e3e6e23e994069 Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Thu, 12 Nov 2026 11:37:05 -0800 Subject: [PATCH 1/3] ci: make all-done jobs fail when a needed job fails Without a status function in its if, an all-done job is skipped (not failed) when a needed job fails or is cancelled, and a skipped required check counts as passing, also in the merge queue. Run all-done and all-done-validate unless the workflow is cancelled, and explicitly fail them if any of the needed jobs has failed or was cancelled (but not skipped). This is the same as done in runc. Signed-off-by: Kir Kolyshkin --- .github/workflows/test.yml | 18 +++++++++++++++++- .github/workflows/validate.yml | 18 +++++++++++++++++- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e0399a2..95ee704 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -75,9 +75,25 @@ jobs: run: LIMA_WORKDIR=/tmp/cgroups lima sudo GOTOOLCHAIN=auto CGROUPS_ALLOW_UNSAFE_TESTS=true go test -v ./... all-done: + # Without a status function this job is skipped (not failed) when a needed + # job fails, and a skipped required check counts as passing. Run it anyway + # and fail if any of the needed jobs has failed or was cancelled (skipped + # jobs, e.g. ones not applicable to the event, are fine). + if: ${{ !cancelled() }} needs: - cgroup-v2 - cgroup-v1 runs-on: ubuntu-26.04 steps: - - run: echo "All jobs completed" + - name: check that all jobs succeeded + env: + NEEDS: ${{ toJSON(needs) }} + run: | + failed=$(jq -r 'to_entries[] + | select(.value.result != "success" and .value.result != "skipped") + | "::error::Job \(.key) result: \(.value.result)"' <<<"$NEEDS") + if [ -n "$failed" ]; then + echo "$failed" + exit 1 + fi + echo "All jobs completed" diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 2ea4962..f5b862c 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -90,6 +90,11 @@ jobs: annotations: true all-done-validate: + # Without a status function this job is skipped (not failed) when a needed + # job fails, and a skipped required check counts as passing. Run it anyway + # and fail if any of the needed jobs has failed or was cancelled (skipped + # jobs, e.g. ones not applicable to the event, are fine). + if: ${{ !cancelled() }} needs: - codespell - deps @@ -99,4 +104,15 @@ jobs: - zizmor runs-on: ubuntu-26.04 steps: - - run: echo "All jobs completed" + - name: check that all jobs succeeded + env: + NEEDS: ${{ toJSON(needs) }} + run: | + failed=$(jq -r 'to_entries[] + | select(.value.result != "success" and .value.result != "skipped") + | "::error::Job \(.key) result: \(.value.result)"' <<<"$NEEDS") + if [ -n "$failed" ]; then + echo "$failed" + exit 1 + fi + echo "All jobs completed" From a7c1917de9b6be3f47be348071401152ee8ff856 Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Thu, 12 Nov 2026 11:37:11 -0800 Subject: [PATCH 2/3] ci: drop all-done-actionlint It only wraps the single actionlint job and, having no status function, is skipped (and passes as a required check) when actionlint fails. Drop it; actionlint itself can be required instead. Signed-off-by: Kir Kolyshkin --- .github/workflows/actionlint.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.github/workflows/actionlint.yml b/.github/workflows/actionlint.yml index d6c6eb7..e5e2715 100644 --- a/.github/workflows/actionlint.yml +++ b/.github/workflows/actionlint.yml @@ -28,10 +28,3 @@ jobs: with: persist-credentials: false - uses: kjanat/actionlint@1a9278318c43b72cdf644214128fb0786d210147 # v1.17 - - all-done-actionlint: - needs: - - actionlint - runs-on: ubuntu-26.04 - steps: - - run: echo "All jobs completed" From 2104295ce839a50e8503425c0bc96f7d960613ef Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Thu, 12 Nov 2026 11:37:11 -0800 Subject: [PATCH 3/3] ci: support merge queue With the merge queue enabled, all required checks must also pass for the merge group commit; a check that is not reported there makes the queue time out. Add the merge_group trigger to all the workflows that provide (or may provide) required checks. This includes review-policy: the reusable workflow from runc already handles merge_group (by doing nothing), but the triggers of a reusable workflow are ignored, so it must be added to the calling one. Signed-off-by: Kir Kolyshkin --- .github/workflows/actionlint.yml | 1 + .github/workflows/review-policy.yml | 5 +++++ .github/workflows/test.yml | 1 + .github/workflows/validate.yml | 1 + 4 files changed, 8 insertions(+) diff --git a/.github/workflows/actionlint.yml b/.github/workflows/actionlint.yml index e5e2715..0d11327 100644 --- a/.github/workflows/actionlint.yml +++ b/.github/workflows/actionlint.yml @@ -8,6 +8,7 @@ on: branches: - main - release-* + merge_group: pull_request: # Cancel superseded runs of the same pull request. For everything else diff --git a/.github/workflows/review-policy.yml b/.github/workflows/review-policy.yml index d06779e..b4e700d 100644 --- a/.github/workflows/review-policy.yml +++ b/.github/workflows/review-policy.yml @@ -12,6 +12,11 @@ name: review-policy on: pull_request_review: types: [submitted, edited, dismissed] + # All required checks must pass in the merge queue, too. The reusable + # workflow does nothing for merge_group, since a pull request can only be + # added to the queue once this check has passed for it. Note that the + # triggers must be set here, as those of a reusable workflow are ignored. + merge_group: permissions: {} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 95ee704..efed340 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,6 +6,7 @@ on: branches: - main - release-* + merge_group: pull_request: schedule: # Runs at 00:00 UTC every Monday diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index f5b862c..970ce5a 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -6,6 +6,7 @@ on: branches: - main - release-* + merge_group: pull_request: schedule: # Runs at 00:00 UTC every Monday