From dc1bf711d6de005316411c4f32bfe57604c6259f Mon Sep 17 00:00:00 2001 From: Petr Glaser Date: Thu, 8 Oct 2026 21:43:14 +0200 Subject: [PATCH 1/2] ci: add quality-gate job required by the master ruleset The Master ruleset requires a 'quality-gate' status check, but no workflow on master produced one, so every PR showed as blocked and needed an admin bypass. The job mirrors the result of the existing 'main' CI job. Co-Authored-By: Claude Opus 5.5 (1M context) --- .github/workflows/ci.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1b9a4d3e98..8603f7e3e0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -87,3 +87,24 @@ jobs: - name: Prove Herbatika Pages hard statuses through Docker ingress if: contains(steps.determine_affected.outputs.projects_csv, ',herbatika,') run: pnpm --filter=herbatika test:m00:wire + + # Required status check for master (ruleset "Master"). It mirrors the CI + # result so the ruleset has one stable name to require; add new blocking + # jobs to `needs` instead of editing the ruleset. + quality-gate: + name: quality-gate + if: always() + needs: + - main + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Require every blocking job to pass + env: + MAIN: ${{ needs.main.result }} + run: | + echo "main: $MAIN" + if [ "$MAIN" != "success" ]; then + echo "::error::CI job 'main' finished with '$MAIN'." + exit 1 + fi From 23d370aaa85f3a9d2c49a639c015965f462f78bd Mon Sep 17 00:00:00 2001 From: Petr Glaser Date: Thu, 8 Oct 2026 21:52:07 +0200 Subject: [PATCH 2/2] ci: make quality-gate check every job in needs Co-Authored-By: Claude Opus 5.5 (1M context) --- .github/workflows/ci.yml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8603f7e3e0..5685bdb283 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -88,9 +88,9 @@ jobs: if: contains(steps.determine_affected.outputs.projects_csv, ',herbatika,') run: pnpm --filter=herbatika test:m00:wire - # Required status check for master (ruleset "Master"). It mirrors the CI - # result so the ruleset has one stable name to require; add new blocking - # jobs to `needs` instead of editing the ruleset. + # Required status check for master (ruleset "Master"). It fails unless every + # job in `needs` succeeded, so the ruleset has one stable name to require. + # To make another job blocking, add it to `needs`; don't edit the ruleset. quality-gate: name: quality-gate if: always() @@ -101,10 +101,11 @@ jobs: steps: - name: Require every blocking job to pass env: - MAIN: ${{ needs.main.result }} + NEEDS: ${{ toJSON(needs) }} run: | - echo "main: $MAIN" - if [ "$MAIN" != "success" ]; then - echo "::error::CI job 'main' finished with '$MAIN'." + echo "$NEEDS" | jq -r 'to_entries[] | "\(.key): \(.value.result)"' + failed=$(echo "$NEEDS" | jq -r '[to_entries[] | select(.value.result != "success") | .key] | join(", ")') + if [ -n "$failed" ]; then + echo "::error::Blocking jobs did not succeed: $failed" exit 1 fi