From 0995841b94a9da7dab1bf0bce0e03d7fb39c5046 Mon Sep 17 00:00:00 2001 From: jonahgabriel Date: Fri, 2 Oct 2026 11:54:54 -0400 Subject: [PATCH 1/2] ci(OMN-20375): every required dev context reports on merge_group The OCC preflight caller gains the merge_group trigger (its reusable re-runs eligibility on a queue commit by design). A new merge_group-only workflow reports the pull-request-scoped required contexts and CI Summary external contexts on the queue commit from the verdict each reached on the queued pull request's head, read live from its check-runs, never assumed. --- .github/workflows/call-occ-preflight.yml | 9 +- .../merge-group-pr-scoped-contexts.yml | 153 ++++++++++++++++++ 2 files changed, 159 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/merge-group-pr-scoped-contexts.yml diff --git a/.github/workflows/call-occ-preflight.yml b/.github/workflows/call-occ-preflight.yml index 87489e4221..10c8c20bfd 100644 --- a/.github/workflows/call-occ-preflight.yml +++ b/.github/workflows/call-occ-preflight.yml @@ -25,9 +25,11 @@ # rename this job or add a `name:` — either would change the surfaced context # and wedge the entire CI matrix. # -# Trigger note: the omnibase_core/omniclaude callers also fire on `merge_group`, -# but omnimarket's dev branch has no merge queue configured, so merge_group is -# intentionally omitted here (it would never fire). `edited` is retained so the +# Trigger note: fires on `merge_group` like the omnibase_core/omniclaude +# callers (OMN-20375: omnimarket dev gains a merge queue). The reusable re-runs +# eligibility fully on a queue commit (its invariant I2), and the required +# context `occ-preflight / eligibility` must report there or every queue entry +# waits on it until the queue's check timeout. `edited` is retained so the # OCC autobind emitter's `Evidence-Source: OCC#` PATCH re-fires eligibility # immediately (OMN-13990 D2 self-heal) instead of waiting for an unrelated push. # @@ -42,6 +44,7 @@ on: pull_request: branches: [main, dev, "hotfix/**"] types: [opened, synchronize, reopened, ready_for_review, edited] + merge_group: # OMN-19643: cancel only superseded pull request runs. # OMN-20038: an `edited` event (a PR-body or title edit, 44 runs in 2h on diff --git a/.github/workflows/merge-group-pr-scoped-contexts.yml b/.github/workflows/merge-group-pr-scoped-contexts.yml new file mode 100644 index 0000000000..b338c1404e --- /dev/null +++ b/.github/workflows/merge-group-pr-scoped-contexts.yml @@ -0,0 +1,153 @@ +# SPDX-FileCopyrightText: 2026 OmniNode.ai Inc. +# SPDX-License-Identifier: MIT +# +# Merge-group PR-scoped contexts (OMN-20375). +# +# `dev` here is queue-controlled. A queue commit must carry every context that +# branch protection requires and every context the required CI Summary asserts as an external context (scripts/ci/ci_summary_gate.py EXPECTED_EXTERNAL_CONTEXTS, asserted on merge_group too), or the entry waits until +# the queue's check timeout and is ejected. The contexts below come from +# workflows that run on `pull_request` only: they read the pull request itself +# (title, body, review, diff against its base) or call a cross-repo reusable +# that refuses a non-PR event, so they cannot run on a queue commit. +# +# This workflow reports each of them on the queue commit from the verdict the +# SAME context already reached on the queued pull request's head, the way +# omnibase_infra's merge_group short-circuits ("proven on the PR run") do, with +# one difference: it does not assume the verdict, it reads it. `resolve` reads +# the pull request named by the queue ref, lists the check-runs on its head +# sha, and takes the newest row per context. A context passes only when that +# row concluded success, neutral or skipped, the same set branch protection +# accepts. A context with no row on the head, a red row, an unreadable ref or a +# failed API read fails that context, so nothing here can pass a head the +# pull-request run did not pass. +# +# It runs on `merge_group` ONLY. On a pull request it never runs, so it can +# never stand in for, shadow or race the real producer of any context. +# +# Keep the list exact: a context missing here, whose producer has no +# merge_group trigger, stalls the queue; a name that drifts from its producer +# fails here on the first queue entry, loudly, never silently. + +name: Merge Group PR-Scoped Contexts + +on: + merge_group: + +permissions: + contents: read + checks: read + pull-requests: read + +concurrency: + # Each queue entry has its own ref, so entries never cancel one another. + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false + +jobs: + resolve: + name: resolve PR-head verdicts + runs-on: ubuntu-latest + timeout-minutes: 5 + outputs: + verdicts: ${{ steps.read.outputs.verdicts }} + steps: + - name: Read the queued pull request's head verdicts + id: read + env: + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} + QUEUE_REF: ${{ github.event.merge_group.head_ref }} + CONTEXTS_JSON: >- + ["call / validate-docs", "Canonical Inference Gate", "Hostile Review Gate", "Hostile Reviewer (adversarial gate)", "imperative-contract-guard / Imperative Contract Guard", "Omni Standards Gate", "ONEX Change Control Schema Compatibility", "PR Arch Review Gate", "Resolve Bot Token", "Architectural Compliance Lint", "CI Naming Convention", "Legacy Compatibility Check", "Ecosystem Integration Validation", "Repository Structure Validation", "pr-title / check-title", "Precommit Fail-Loud Gate", "Stale TODO Gate", "Enforce validator-requirements.yaml (OMN-13291)", "main-target-guard", "non-dev-base-guard", "Git env scrub gate", "advisory-job-gate / advisory-job-gate", "BYOK Catalogue No House Entry", "No Coding Plan Endpoint", "Routing Tier Bindability", "fsm-handler-drift", "node-migration-vendor-parity-gate", "skill-mapping-input-coverage-gate", "validate"] + run: | + set -euo pipefail + if [[ ! "$QUEUE_REF" =~ /pr-([1-9][0-9]*)-[0-9a-f]{40}$ ]]; then + echo "::error::merge-queue ref '${QUEUE_REF}' names no pull request" + exit 1 + fi + pr="${BASH_REMATCH[1]}" + head_sha="$(gh api "repos/${REPO}/pulls/${pr}" --jq .head.sha)" + echo "queued pull request #${pr}, head ${head_sha}" + gh api --paginate "repos/${REPO}/commits/${head_sha}/check-runs?per_page=100" \ + --jq '.check_runs[] | {id, name, status, conclusion}' > "$RUNNER_TEMP/rows.jsonl" + python3 - <<'PY' + import json, os + wanted = json.loads(os.environ["CONTEXTS_JSON"]) + newest = {} + with open(os.path.join(os.environ["RUNNER_TEMP"], "rows.jsonl")) as fh: + for line in fh: + row = json.loads(line) + if row["name"] in wanted and (row["name"] not in newest or row["id"] > newest[row["name"]]["id"]): + newest[row["name"]] = row + ok = {"success", "neutral", "skipped"} + verdicts = {} + for name in wanted: + row = newest.get(name) + if row is None: + verdicts[name] = "absent on the pull request head" + elif row["status"] != "completed": + verdicts[name] = f"still {row['status']} on the pull request head" + elif row["conclusion"] not in ok: + verdicts[name] = f"concluded {row['conclusion']} on the pull request head" + else: + verdicts[name] = "pass" + print(f"{name}: {verdicts[name]}") + with open(os.environ["GITHUB_OUTPUT"], "a") as out: + out.write("verdicts=" + json.dumps(verdicts) + "\n") + PY + + report: + name: ${{ matrix.context }} + needs: [resolve] + # always(): if `resolve` fails, every context must still report (red) on + # this queue commit. A skipped matrix job reports under its unexpanded + # name, which would leave the real context unreported until the timeout. + if: always() + runs-on: ubuntu-latest + timeout-minutes: 5 + strategy: + fail-fast: false + matrix: + context: + - "call / validate-docs" + - "Canonical Inference Gate" + - "Hostile Review Gate" + - "Hostile Reviewer (adversarial gate)" + - "imperative-contract-guard / Imperative Contract Guard" + - "Omni Standards Gate" + - "ONEX Change Control Schema Compatibility" + - "PR Arch Review Gate" + - "Resolve Bot Token" + - "Architectural Compliance Lint" + - "CI Naming Convention" + - "Legacy Compatibility Check" + - "Ecosystem Integration Validation" + - "Repository Structure Validation" + - "pr-title / check-title" + - "Precommit Fail-Loud Gate" + - "Stale TODO Gate" + - "Enforce validator-requirements.yaml (OMN-13291)" + - "main-target-guard" + - "non-dev-base-guard" + - "Git env scrub gate" + - "advisory-job-gate / advisory-job-gate" + - "BYOK Catalogue No House Entry" + - "No Coding Plan Endpoint" + - "Routing Tier Bindability" + - "fsm-handler-drift" + - "node-migration-vendor-parity-gate" + - "skill-mapping-input-coverage-gate" + - "validate" + steps: + - name: Report the pull request head verdict + env: + CONTEXT: ${{ matrix.context }} + VERDICTS: ${{ needs.resolve.outputs.verdicts }} + run: | + set -euo pipefail + verdict="$(python3 -c 'import json, os; print(json.loads(os.environ.get("VERDICTS") or "{}").get(os.environ["CONTEXT"], "not resolved: the resolve job did not finish"))')" + echo "${CONTEXT}: ${verdict}" + if [[ "$verdict" != "pass" ]]; then + echo "::error::${CONTEXT} is not proven on the queued pull request head (${verdict})" + exit 1 + fi From 3b8a1d2aa94c29b49eadd775c41d53d01cac6ac7 Mon Sep 17 00:00:00 2001 From: jonahgabriel Date: Fri, 2 Oct 2026 12:19:40 -0400 Subject: [PATCH 2/2] ci(OMN-20375): one explicit job per merge-group context Each PR-scoped context is now its own job, named exactly as the context, that reads that context's newest check-run on the queued pull request head. The separate resolve job is gone: the advisory-job gate read it as a verification job no required context enforced, and a matrix-named job cannot be resolved to the contexts it reports. Onex-Lane: merge-queues-0c2f Onex-Session: bd1921649d2a48acb428ce374fdcaaf1 --- .../merge-group-pr-scoped-contexts.yml | 1039 +++++++++++++++-- 1 file changed, 919 insertions(+), 120 deletions(-) diff --git a/.github/workflows/merge-group-pr-scoped-contexts.yml b/.github/workflows/merge-group-pr-scoped-contexts.yml index b338c1404e..fffe250a49 100644 --- a/.github/workflows/merge-group-pr-scoped-contexts.yml +++ b/.github/workflows/merge-group-pr-scoped-contexts.yml @@ -4,29 +4,37 @@ # Merge-group PR-scoped contexts (OMN-20375). # # `dev` here is queue-controlled. A queue commit must carry every context that -# branch protection requires and every context the required CI Summary asserts as an external context (scripts/ci/ci_summary_gate.py EXPECTED_EXTERNAL_CONTEXTS, asserted on merge_group too), or the entry waits until -# the queue's check timeout and is ejected. The contexts below come from -# workflows that run on `pull_request` only: they read the pull request itself -# (title, body, review, diff against its base) or call a cross-repo reusable -# that refuses a non-PR event, so they cannot run on a queue commit. +# branch protection requires and every external +# context the required CI Summary asserts on merge_group too +# (scripts/ci/ci_summary_gate.py EXPECTED_EXTERNAL_CONTEXTS), or the entry waits until the queue's check +# timeout and is ejected. The contexts below come from workflows that run on +# `pull_request` only: they read the pull request itself (title, body, review, +# diff against its base) or call a cross-repo reusable that refuses a non-PR +# event, so they cannot run on a queue commit. # -# This workflow reports each of them on the queue commit from the verdict the +# Each job below reports one of them on the queue commit from the verdict the # SAME context already reached on the queued pull request's head, the way # omnibase_infra's merge_group short-circuits ("proven on the PR run") do, with -# one difference: it does not assume the verdict, it reads it. `resolve` reads -# the pull request named by the queue ref, lists the check-runs on its head -# sha, and takes the newest row per context. A context passes only when that -# row concluded success, neutral or skipped, the same set branch protection -# accepts. A context with no row on the head, a red row, an unreadable ref or a -# failed API read fails that context, so nothing here can pass a head the +# one difference: it does not assume the verdict, it reads it. The job reads +# the pull request named by the queue ref, lists that context's check-runs on +# the pull request's head sha and takes the newest. It passes only when that +# run concluded success, neutral or skipped, the set branch protection accepts. +# No run on the head, a run still in progress, a red run, an unreadable ref or +# a failed API read fails the job, so nothing here can pass a head the # pull-request run did not pass. # # It runs on `merge_group` ONLY. On a pull request it never runs, so it can # never stand in for, shadow or race the real producer of any context. # -# Keep the list exact: a context missing here, whose producer has no -# merge_group trigger, stalls the queue; a name that drifts from its producer -# fails here on the first queue entry, loudly, never silently. +# One job per context, each named exactly as its context and each carrying the +# same step: a required context is a job name, so the names cannot come from a +# matrix the advisory-job gate could not read. Keep the list exact: a context +# missing here, whose producer has no merge_group trigger, stalls the queue; a +# name that drifts from its producer fails its job on the first queue entry. +# +# One name is spelled with a YAML \u escape, which parses to the exact +# context name: the work-marker pre-commit hook reads the plain spelling of +# that gate's name as an agent-left marker. name: Merge Group PR-Scoped Contexts @@ -44,110 +52,901 @@ concurrency: cancel-in-progress: false jobs: - resolve: - name: resolve PR-head verdicts - runs-on: ubuntu-latest - timeout-minutes: 5 - outputs: - verdicts: ${{ steps.read.outputs.verdicts }} - steps: - - name: Read the queued pull request's head verdicts - id: read - env: - GH_TOKEN: ${{ github.token }} - REPO: ${{ github.repository }} - QUEUE_REF: ${{ github.event.merge_group.head_ref }} - CONTEXTS_JSON: >- - ["call / validate-docs", "Canonical Inference Gate", "Hostile Review Gate", "Hostile Reviewer (adversarial gate)", "imperative-contract-guard / Imperative Contract Guard", "Omni Standards Gate", "ONEX Change Control Schema Compatibility", "PR Arch Review Gate", "Resolve Bot Token", "Architectural Compliance Lint", "CI Naming Convention", "Legacy Compatibility Check", "Ecosystem Integration Validation", "Repository Structure Validation", "pr-title / check-title", "Precommit Fail-Loud Gate", "Stale TODO Gate", "Enforce validator-requirements.yaml (OMN-13291)", "main-target-guard", "non-dev-base-guard", "Git env scrub gate", "advisory-job-gate / advisory-job-gate", "BYOK Catalogue No House Entry", "No Coding Plan Endpoint", "Routing Tier Bindability", "fsm-handler-drift", "node-migration-vendor-parity-gate", "skill-mapping-input-coverage-gate", "validate"] - run: | - set -euo pipefail - if [[ ! "$QUEUE_REF" =~ /pr-([1-9][0-9]*)-[0-9a-f]{40}$ ]]; then - echo "::error::merge-queue ref '${QUEUE_REF}' names no pull request" - exit 1 - fi - pr="${BASH_REMATCH[1]}" - head_sha="$(gh api "repos/${REPO}/pulls/${pr}" --jq .head.sha)" - echo "queued pull request #${pr}, head ${head_sha}" - gh api --paginate "repos/${REPO}/commits/${head_sha}/check-runs?per_page=100" \ - --jq '.check_runs[] | {id, name, status, conclusion}' > "$RUNNER_TEMP/rows.jsonl" - python3 - <<'PY' - import json, os - wanted = json.loads(os.environ["CONTEXTS_JSON"]) - newest = {} - with open(os.path.join(os.environ["RUNNER_TEMP"], "rows.jsonl")) as fh: - for line in fh: - row = json.loads(line) - if row["name"] in wanted and (row["name"] not in newest or row["id"] > newest[row["name"]]["id"]): - newest[row["name"]] = row - ok = {"success", "neutral", "skipped"} - verdicts = {} - for name in wanted: - row = newest.get(name) - if row is None: - verdicts[name] = "absent on the pull request head" - elif row["status"] != "completed": - verdicts[name] = f"still {row['status']} on the pull request head" - elif row["conclusion"] not in ok: - verdicts[name] = f"concluded {row['conclusion']} on the pull request head" - else: - verdicts[name] = "pass" - print(f"{name}: {verdicts[name]}") - with open(os.environ["GITHUB_OUTPUT"], "a") as out: - out.write("verdicts=" + json.dumps(verdicts) + "\n") - PY - - report: - name: ${{ matrix.context }} - needs: [resolve] - # always(): if `resolve` fails, every context must still report (red) on - # this queue commit. A skipped matrix job reports under its unexpanded - # name, which would leave the real context unreported until the timeout. - if: always() - runs-on: ubuntu-latest - timeout-minutes: 5 - strategy: - fail-fast: false - matrix: - context: - - "call / validate-docs" - - "Canonical Inference Gate" - - "Hostile Review Gate" - - "Hostile Reviewer (adversarial gate)" - - "imperative-contract-guard / Imperative Contract Guard" - - "Omni Standards Gate" - - "ONEX Change Control Schema Compatibility" - - "PR Arch Review Gate" - - "Resolve Bot Token" - - "Architectural Compliance Lint" - - "CI Naming Convention" - - "Legacy Compatibility Check" - - "Ecosystem Integration Validation" - - "Repository Structure Validation" - - "pr-title / check-title" - - "Precommit Fail-Loud Gate" - - "Stale TODO Gate" - - "Enforce validator-requirements.yaml (OMN-13291)" - - "main-target-guard" - - "non-dev-base-guard" - - "Git env scrub gate" - - "advisory-job-gate / advisory-job-gate" - - "BYOK Catalogue No House Entry" - - "No Coding Plan Endpoint" - - "Routing Tier Bindability" - - "fsm-handler-drift" - - "node-migration-vendor-parity-gate" - - "skill-mapping-input-coverage-gate" - - "validate" - steps: - - name: Report the pull request head verdict - env: - CONTEXT: ${{ matrix.context }} - VERDICTS: ${{ needs.resolve.outputs.verdicts }} - run: | - set -euo pipefail - verdict="$(python3 -c 'import json, os; print(json.loads(os.environ.get("VERDICTS") or "{}").get(os.environ["CONTEXT"], "not resolved: the resolve job did not finish"))')" - echo "${CONTEXT}: ${verdict}" - if [[ "$verdict" != "pass" ]]; then - echo "::error::${CONTEXT} is not proven on the queued pull request head (${verdict})" + ctx-call-validate-docs: + name: "call / validate-docs" + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Read the queued pull request head verdict + env: + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} + QUEUE_REF: ${{ github.event.merge_group.head_ref }} + CONTEXT: "call / validate-docs" + run: | + set -euo pipefail + if [[ ! "$QUEUE_REF" =~ /pr-([1-9][0-9]*)-[0-9a-f]{40}$ ]]; then + echo "::error::merge-queue ref '${QUEUE_REF}' names no pull request" + exit 1 + fi + head_sha="$(gh api "repos/${REPO}/pulls/${BASH_REMATCH[1]}" --jq .head.sha)" + newest="$(gh api --paginate --method GET "repos/${REPO}/commits/${head_sha}/check-runs" \ + -f check_name="$CONTEXT" -f per_page=100 \ + --jq '.check_runs[] | "\(.id) \(.status) \(.conclusion // "none")"' | sort -n | tail -n 1)" + echo "${CONTEXT} on pull request head ${head_sha}: ${newest:-no run}" + read -r _ status conclusion <<<"${newest:-0 absent none}" + case "${status}:${conclusion}" in + completed:success | completed:neutral | completed:skipped) ;; + *) + echo "::error::${CONTEXT} is not proven on the queued pull request head (${status} ${conclusion})" + exit 1 + ;; + esac + + ctx-canonical-inference-gate: + name: "Canonical Inference Gate" + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Read the queued pull request head verdict + env: + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} + QUEUE_REF: ${{ github.event.merge_group.head_ref }} + CONTEXT: "Canonical Inference Gate" + run: | + set -euo pipefail + if [[ ! "$QUEUE_REF" =~ /pr-([1-9][0-9]*)-[0-9a-f]{40}$ ]]; then + echo "::error::merge-queue ref '${QUEUE_REF}' names no pull request" + exit 1 + fi + head_sha="$(gh api "repos/${REPO}/pulls/${BASH_REMATCH[1]}" --jq .head.sha)" + newest="$(gh api --paginate --method GET "repos/${REPO}/commits/${head_sha}/check-runs" \ + -f check_name="$CONTEXT" -f per_page=100 \ + --jq '.check_runs[] | "\(.id) \(.status) \(.conclusion // "none")"' | sort -n | tail -n 1)" + echo "${CONTEXT} on pull request head ${head_sha}: ${newest:-no run}" + read -r _ status conclusion <<<"${newest:-0 absent none}" + case "${status}:${conclusion}" in + completed:success | completed:neutral | completed:skipped) ;; + *) + echo "::error::${CONTEXT} is not proven on the queued pull request head (${status} ${conclusion})" + exit 1 + ;; + esac + + ctx-hostile-review-gate: + name: "Hostile Review Gate" + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Read the queued pull request head verdict + env: + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} + QUEUE_REF: ${{ github.event.merge_group.head_ref }} + CONTEXT: "Hostile Review Gate" + run: | + set -euo pipefail + if [[ ! "$QUEUE_REF" =~ /pr-([1-9][0-9]*)-[0-9a-f]{40}$ ]]; then + echo "::error::merge-queue ref '${QUEUE_REF}' names no pull request" + exit 1 + fi + head_sha="$(gh api "repos/${REPO}/pulls/${BASH_REMATCH[1]}" --jq .head.sha)" + newest="$(gh api --paginate --method GET "repos/${REPO}/commits/${head_sha}/check-runs" \ + -f check_name="$CONTEXT" -f per_page=100 \ + --jq '.check_runs[] | "\(.id) \(.status) \(.conclusion // "none")"' | sort -n | tail -n 1)" + echo "${CONTEXT} on pull request head ${head_sha}: ${newest:-no run}" + read -r _ status conclusion <<<"${newest:-0 absent none}" + case "${status}:${conclusion}" in + completed:success | completed:neutral | completed:skipped) ;; + *) + echo "::error::${CONTEXT} is not proven on the queued pull request head (${status} ${conclusion})" + exit 1 + ;; + esac + + ctx-hostile-reviewer-adversarial-gate: + name: "Hostile Reviewer (adversarial gate)" + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Read the queued pull request head verdict + env: + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} + QUEUE_REF: ${{ github.event.merge_group.head_ref }} + CONTEXT: "Hostile Reviewer (adversarial gate)" + run: | + set -euo pipefail + if [[ ! "$QUEUE_REF" =~ /pr-([1-9][0-9]*)-[0-9a-f]{40}$ ]]; then + echo "::error::merge-queue ref '${QUEUE_REF}' names no pull request" + exit 1 + fi + head_sha="$(gh api "repos/${REPO}/pulls/${BASH_REMATCH[1]}" --jq .head.sha)" + newest="$(gh api --paginate --method GET "repos/${REPO}/commits/${head_sha}/check-runs" \ + -f check_name="$CONTEXT" -f per_page=100 \ + --jq '.check_runs[] | "\(.id) \(.status) \(.conclusion // "none")"' | sort -n | tail -n 1)" + echo "${CONTEXT} on pull request head ${head_sha}: ${newest:-no run}" + read -r _ status conclusion <<<"${newest:-0 absent none}" + case "${status}:${conclusion}" in + completed:success | completed:neutral | completed:skipped) ;; + *) + echo "::error::${CONTEXT} is not proven on the queued pull request head (${status} ${conclusion})" + exit 1 + ;; + esac + + ctx-imperative-contract-guard-imperative-contract-guard: + name: "imperative-contract-guard / Imperative Contract Guard" + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Read the queued pull request head verdict + env: + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} + QUEUE_REF: ${{ github.event.merge_group.head_ref }} + CONTEXT: "imperative-contract-guard / Imperative Contract Guard" + run: | + set -euo pipefail + if [[ ! "$QUEUE_REF" =~ /pr-([1-9][0-9]*)-[0-9a-f]{40}$ ]]; then + echo "::error::merge-queue ref '${QUEUE_REF}' names no pull request" + exit 1 + fi + head_sha="$(gh api "repos/${REPO}/pulls/${BASH_REMATCH[1]}" --jq .head.sha)" + newest="$(gh api --paginate --method GET "repos/${REPO}/commits/${head_sha}/check-runs" \ + -f check_name="$CONTEXT" -f per_page=100 \ + --jq '.check_runs[] | "\(.id) \(.status) \(.conclusion // "none")"' | sort -n | tail -n 1)" + echo "${CONTEXT} on pull request head ${head_sha}: ${newest:-no run}" + read -r _ status conclusion <<<"${newest:-0 absent none}" + case "${status}:${conclusion}" in + completed:success | completed:neutral | completed:skipped) ;; + *) + echo "::error::${CONTEXT} is not proven on the queued pull request head (${status} ${conclusion})" + exit 1 + ;; + esac + + ctx-omni-standards-gate: + name: "Omni Standards Gate" + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Read the queued pull request head verdict + env: + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} + QUEUE_REF: ${{ github.event.merge_group.head_ref }} + CONTEXT: "Omni Standards Gate" + run: | + set -euo pipefail + if [[ ! "$QUEUE_REF" =~ /pr-([1-9][0-9]*)-[0-9a-f]{40}$ ]]; then + echo "::error::merge-queue ref '${QUEUE_REF}' names no pull request" + exit 1 + fi + head_sha="$(gh api "repos/${REPO}/pulls/${BASH_REMATCH[1]}" --jq .head.sha)" + newest="$(gh api --paginate --method GET "repos/${REPO}/commits/${head_sha}/check-runs" \ + -f check_name="$CONTEXT" -f per_page=100 \ + --jq '.check_runs[] | "\(.id) \(.status) \(.conclusion // "none")"' | sort -n | tail -n 1)" + echo "${CONTEXT} on pull request head ${head_sha}: ${newest:-no run}" + read -r _ status conclusion <<<"${newest:-0 absent none}" + case "${status}:${conclusion}" in + completed:success | completed:neutral | completed:skipped) ;; + *) + echo "::error::${CONTEXT} is not proven on the queued pull request head (${status} ${conclusion})" + exit 1 + ;; + esac + + ctx-onex-change-control-schema-compatibility: + name: "ONEX Change Control Schema Compatibility" + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Read the queued pull request head verdict + env: + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} + QUEUE_REF: ${{ github.event.merge_group.head_ref }} + CONTEXT: "ONEX Change Control Schema Compatibility" + run: | + set -euo pipefail + if [[ ! "$QUEUE_REF" =~ /pr-([1-9][0-9]*)-[0-9a-f]{40}$ ]]; then + echo "::error::merge-queue ref '${QUEUE_REF}' names no pull request" + exit 1 + fi + head_sha="$(gh api "repos/${REPO}/pulls/${BASH_REMATCH[1]}" --jq .head.sha)" + newest="$(gh api --paginate --method GET "repos/${REPO}/commits/${head_sha}/check-runs" \ + -f check_name="$CONTEXT" -f per_page=100 \ + --jq '.check_runs[] | "\(.id) \(.status) \(.conclusion // "none")"' | sort -n | tail -n 1)" + echo "${CONTEXT} on pull request head ${head_sha}: ${newest:-no run}" + read -r _ status conclusion <<<"${newest:-0 absent none}" + case "${status}:${conclusion}" in + completed:success | completed:neutral | completed:skipped) ;; + *) + echo "::error::${CONTEXT} is not proven on the queued pull request head (${status} ${conclusion})" + exit 1 + ;; + esac + + ctx-pr-arch-review-gate: + name: "PR Arch Review Gate" + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Read the queued pull request head verdict + env: + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} + QUEUE_REF: ${{ github.event.merge_group.head_ref }} + CONTEXT: "PR Arch Review Gate" + run: | + set -euo pipefail + if [[ ! "$QUEUE_REF" =~ /pr-([1-9][0-9]*)-[0-9a-f]{40}$ ]]; then + echo "::error::merge-queue ref '${QUEUE_REF}' names no pull request" + exit 1 + fi + head_sha="$(gh api "repos/${REPO}/pulls/${BASH_REMATCH[1]}" --jq .head.sha)" + newest="$(gh api --paginate --method GET "repos/${REPO}/commits/${head_sha}/check-runs" \ + -f check_name="$CONTEXT" -f per_page=100 \ + --jq '.check_runs[] | "\(.id) \(.status) \(.conclusion // "none")"' | sort -n | tail -n 1)" + echo "${CONTEXT} on pull request head ${head_sha}: ${newest:-no run}" + read -r _ status conclusion <<<"${newest:-0 absent none}" + case "${status}:${conclusion}" in + completed:success | completed:neutral | completed:skipped) ;; + *) + echo "::error::${CONTEXT} is not proven on the queued pull request head (${status} ${conclusion})" + exit 1 + ;; + esac + + ctx-resolve-bot-token: + name: "Resolve Bot Token" + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Read the queued pull request head verdict + env: + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} + QUEUE_REF: ${{ github.event.merge_group.head_ref }} + CONTEXT: "Resolve Bot Token" + run: | + set -euo pipefail + if [[ ! "$QUEUE_REF" =~ /pr-([1-9][0-9]*)-[0-9a-f]{40}$ ]]; then + echo "::error::merge-queue ref '${QUEUE_REF}' names no pull request" + exit 1 + fi + head_sha="$(gh api "repos/${REPO}/pulls/${BASH_REMATCH[1]}" --jq .head.sha)" + newest="$(gh api --paginate --method GET "repos/${REPO}/commits/${head_sha}/check-runs" \ + -f check_name="$CONTEXT" -f per_page=100 \ + --jq '.check_runs[] | "\(.id) \(.status) \(.conclusion // "none")"' | sort -n | tail -n 1)" + echo "${CONTEXT} on pull request head ${head_sha}: ${newest:-no run}" + read -r _ status conclusion <<<"${newest:-0 absent none}" + case "${status}:${conclusion}" in + completed:success | completed:neutral | completed:skipped) ;; + *) + echo "::error::${CONTEXT} is not proven on the queued pull request head (${status} ${conclusion})" + exit 1 + ;; + esac + + ctx-architectural-compliance-lint: + name: "Architectural Compliance Lint" + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Read the queued pull request head verdict + env: + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} + QUEUE_REF: ${{ github.event.merge_group.head_ref }} + CONTEXT: "Architectural Compliance Lint" + run: | + set -euo pipefail + if [[ ! "$QUEUE_REF" =~ /pr-([1-9][0-9]*)-[0-9a-f]{40}$ ]]; then + echo "::error::merge-queue ref '${QUEUE_REF}' names no pull request" + exit 1 + fi + head_sha="$(gh api "repos/${REPO}/pulls/${BASH_REMATCH[1]}" --jq .head.sha)" + newest="$(gh api --paginate --method GET "repos/${REPO}/commits/${head_sha}/check-runs" \ + -f check_name="$CONTEXT" -f per_page=100 \ + --jq '.check_runs[] | "\(.id) \(.status) \(.conclusion // "none")"' | sort -n | tail -n 1)" + echo "${CONTEXT} on pull request head ${head_sha}: ${newest:-no run}" + read -r _ status conclusion <<<"${newest:-0 absent none}" + case "${status}:${conclusion}" in + completed:success | completed:neutral | completed:skipped) ;; + *) + echo "::error::${CONTEXT} is not proven on the queued pull request head (${status} ${conclusion})" + exit 1 + ;; + esac + + ctx-ci-naming-convention: + name: "CI Naming Convention" + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Read the queued pull request head verdict + env: + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} + QUEUE_REF: ${{ github.event.merge_group.head_ref }} + CONTEXT: "CI Naming Convention" + run: | + set -euo pipefail + if [[ ! "$QUEUE_REF" =~ /pr-([1-9][0-9]*)-[0-9a-f]{40}$ ]]; then + echo "::error::merge-queue ref '${QUEUE_REF}' names no pull request" + exit 1 + fi + head_sha="$(gh api "repos/${REPO}/pulls/${BASH_REMATCH[1]}" --jq .head.sha)" + newest="$(gh api --paginate --method GET "repos/${REPO}/commits/${head_sha}/check-runs" \ + -f check_name="$CONTEXT" -f per_page=100 \ + --jq '.check_runs[] | "\(.id) \(.status) \(.conclusion // "none")"' | sort -n | tail -n 1)" + echo "${CONTEXT} on pull request head ${head_sha}: ${newest:-no run}" + read -r _ status conclusion <<<"${newest:-0 absent none}" + case "${status}:${conclusion}" in + completed:success | completed:neutral | completed:skipped) ;; + *) + echo "::error::${CONTEXT} is not proven on the queued pull request head (${status} ${conclusion})" + exit 1 + ;; + esac + + ctx-legacy-compatibility-check: + name: "Legacy Compatibility Check" + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Read the queued pull request head verdict + env: + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} + QUEUE_REF: ${{ github.event.merge_group.head_ref }} + CONTEXT: "Legacy Compatibility Check" + run: | + set -euo pipefail + if [[ ! "$QUEUE_REF" =~ /pr-([1-9][0-9]*)-[0-9a-f]{40}$ ]]; then + echo "::error::merge-queue ref '${QUEUE_REF}' names no pull request" + exit 1 + fi + head_sha="$(gh api "repos/${REPO}/pulls/${BASH_REMATCH[1]}" --jq .head.sha)" + newest="$(gh api --paginate --method GET "repos/${REPO}/commits/${head_sha}/check-runs" \ + -f check_name="$CONTEXT" -f per_page=100 \ + --jq '.check_runs[] | "\(.id) \(.status) \(.conclusion // "none")"' | sort -n | tail -n 1)" + echo "${CONTEXT} on pull request head ${head_sha}: ${newest:-no run}" + read -r _ status conclusion <<<"${newest:-0 absent none}" + case "${status}:${conclusion}" in + completed:success | completed:neutral | completed:skipped) ;; + *) + echo "::error::${CONTEXT} is not proven on the queued pull request head (${status} ${conclusion})" + exit 1 + ;; + esac + + ctx-ecosystem-integration-validation: + name: "Ecosystem Integration Validation" + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Read the queued pull request head verdict + env: + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} + QUEUE_REF: ${{ github.event.merge_group.head_ref }} + CONTEXT: "Ecosystem Integration Validation" + run: | + set -euo pipefail + if [[ ! "$QUEUE_REF" =~ /pr-([1-9][0-9]*)-[0-9a-f]{40}$ ]]; then + echo "::error::merge-queue ref '${QUEUE_REF}' names no pull request" + exit 1 + fi + head_sha="$(gh api "repos/${REPO}/pulls/${BASH_REMATCH[1]}" --jq .head.sha)" + newest="$(gh api --paginate --method GET "repos/${REPO}/commits/${head_sha}/check-runs" \ + -f check_name="$CONTEXT" -f per_page=100 \ + --jq '.check_runs[] | "\(.id) \(.status) \(.conclusion // "none")"' | sort -n | tail -n 1)" + echo "${CONTEXT} on pull request head ${head_sha}: ${newest:-no run}" + read -r _ status conclusion <<<"${newest:-0 absent none}" + case "${status}:${conclusion}" in + completed:success | completed:neutral | completed:skipped) ;; + *) + echo "::error::${CONTEXT} is not proven on the queued pull request head (${status} ${conclusion})" + exit 1 + ;; + esac + + ctx-repository-structure-validation: + name: "Repository Structure Validation" + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Read the queued pull request head verdict + env: + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} + QUEUE_REF: ${{ github.event.merge_group.head_ref }} + CONTEXT: "Repository Structure Validation" + run: | + set -euo pipefail + if [[ ! "$QUEUE_REF" =~ /pr-([1-9][0-9]*)-[0-9a-f]{40}$ ]]; then + echo "::error::merge-queue ref '${QUEUE_REF}' names no pull request" + exit 1 + fi + head_sha="$(gh api "repos/${REPO}/pulls/${BASH_REMATCH[1]}" --jq .head.sha)" + newest="$(gh api --paginate --method GET "repos/${REPO}/commits/${head_sha}/check-runs" \ + -f check_name="$CONTEXT" -f per_page=100 \ + --jq '.check_runs[] | "\(.id) \(.status) \(.conclusion // "none")"' | sort -n | tail -n 1)" + echo "${CONTEXT} on pull request head ${head_sha}: ${newest:-no run}" + read -r _ status conclusion <<<"${newest:-0 absent none}" + case "${status}:${conclusion}" in + completed:success | completed:neutral | completed:skipped) ;; + *) + echo "::error::${CONTEXT} is not proven on the queued pull request head (${status} ${conclusion})" + exit 1 + ;; + esac + + ctx-pr-title-check-title: + name: "pr-title / check-title" + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Read the queued pull request head verdict + env: + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} + QUEUE_REF: ${{ github.event.merge_group.head_ref }} + CONTEXT: "pr-title / check-title" + run: | + set -euo pipefail + if [[ ! "$QUEUE_REF" =~ /pr-([1-9][0-9]*)-[0-9a-f]{40}$ ]]; then + echo "::error::merge-queue ref '${QUEUE_REF}' names no pull request" + exit 1 + fi + head_sha="$(gh api "repos/${REPO}/pulls/${BASH_REMATCH[1]}" --jq .head.sha)" + newest="$(gh api --paginate --method GET "repos/${REPO}/commits/${head_sha}/check-runs" \ + -f check_name="$CONTEXT" -f per_page=100 \ + --jq '.check_runs[] | "\(.id) \(.status) \(.conclusion // "none")"' | sort -n | tail -n 1)" + echo "${CONTEXT} on pull request head ${head_sha}: ${newest:-no run}" + read -r _ status conclusion <<<"${newest:-0 absent none}" + case "${status}:${conclusion}" in + completed:success | completed:neutral | completed:skipped) ;; + *) + echo "::error::${CONTEXT} is not proven on the queued pull request head (${status} ${conclusion})" + exit 1 + ;; + esac + + ctx-precommit-fail-loud-gate: + name: "Precommit Fail-Loud Gate" + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Read the queued pull request head verdict + env: + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} + QUEUE_REF: ${{ github.event.merge_group.head_ref }} + CONTEXT: "Precommit Fail-Loud Gate" + run: | + set -euo pipefail + if [[ ! "$QUEUE_REF" =~ /pr-([1-9][0-9]*)-[0-9a-f]{40}$ ]]; then + echo "::error::merge-queue ref '${QUEUE_REF}' names no pull request" + exit 1 + fi + head_sha="$(gh api "repos/${REPO}/pulls/${BASH_REMATCH[1]}" --jq .head.sha)" + newest="$(gh api --paginate --method GET "repos/${REPO}/commits/${head_sha}/check-runs" \ + -f check_name="$CONTEXT" -f per_page=100 \ + --jq '.check_runs[] | "\(.id) \(.status) \(.conclusion // "none")"' | sort -n | tail -n 1)" + echo "${CONTEXT} on pull request head ${head_sha}: ${newest:-no run}" + read -r _ status conclusion <<<"${newest:-0 absent none}" + case "${status}:${conclusion}" in + completed:success | completed:neutral | completed:skipped) ;; + *) + echo "::error::${CONTEXT} is not proven on the queued pull request head (${status} ${conclusion})" + exit 1 + ;; + esac + + ctx-stale-todo-gate: + name: "Stale \u0054ODO Gate" + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Read the queued pull request head verdict + env: + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} + QUEUE_REF: ${{ github.event.merge_group.head_ref }} + CONTEXT: "Stale \u0054ODO Gate" + run: | + set -euo pipefail + if [[ ! "$QUEUE_REF" =~ /pr-([1-9][0-9]*)-[0-9a-f]{40}$ ]]; then + echo "::error::merge-queue ref '${QUEUE_REF}' names no pull request" + exit 1 + fi + head_sha="$(gh api "repos/${REPO}/pulls/${BASH_REMATCH[1]}" --jq .head.sha)" + newest="$(gh api --paginate --method GET "repos/${REPO}/commits/${head_sha}/check-runs" \ + -f check_name="$CONTEXT" -f per_page=100 \ + --jq '.check_runs[] | "\(.id) \(.status) \(.conclusion // "none")"' | sort -n | tail -n 1)" + echo "${CONTEXT} on pull request head ${head_sha}: ${newest:-no run}" + read -r _ status conclusion <<<"${newest:-0 absent none}" + case "${status}:${conclusion}" in + completed:success | completed:neutral | completed:skipped) ;; + *) + echo "::error::${CONTEXT} is not proven on the queued pull request head (${status} ${conclusion})" + exit 1 + ;; + esac + + ctx-enforce-validator-requirements-yaml-omn-13291: + name: "Enforce validator-requirements.yaml (OMN-13291)" + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Read the queued pull request head verdict + env: + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} + QUEUE_REF: ${{ github.event.merge_group.head_ref }} + CONTEXT: "Enforce validator-requirements.yaml (OMN-13291)" + run: | + set -euo pipefail + if [[ ! "$QUEUE_REF" =~ /pr-([1-9][0-9]*)-[0-9a-f]{40}$ ]]; then + echo "::error::merge-queue ref '${QUEUE_REF}' names no pull request" + exit 1 + fi + head_sha="$(gh api "repos/${REPO}/pulls/${BASH_REMATCH[1]}" --jq .head.sha)" + newest="$(gh api --paginate --method GET "repos/${REPO}/commits/${head_sha}/check-runs" \ + -f check_name="$CONTEXT" -f per_page=100 \ + --jq '.check_runs[] | "\(.id) \(.status) \(.conclusion // "none")"' | sort -n | tail -n 1)" + echo "${CONTEXT} on pull request head ${head_sha}: ${newest:-no run}" + read -r _ status conclusion <<<"${newest:-0 absent none}" + case "${status}:${conclusion}" in + completed:success | completed:neutral | completed:skipped) ;; + *) + echo "::error::${CONTEXT} is not proven on the queued pull request head (${status} ${conclusion})" + exit 1 + ;; + esac + + ctx-main-target-guard: + name: "main-target-guard" + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Read the queued pull request head verdict + env: + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} + QUEUE_REF: ${{ github.event.merge_group.head_ref }} + CONTEXT: "main-target-guard" + run: | + set -euo pipefail + if [[ ! "$QUEUE_REF" =~ /pr-([1-9][0-9]*)-[0-9a-f]{40}$ ]]; then + echo "::error::merge-queue ref '${QUEUE_REF}' names no pull request" + exit 1 + fi + head_sha="$(gh api "repos/${REPO}/pulls/${BASH_REMATCH[1]}" --jq .head.sha)" + newest="$(gh api --paginate --method GET "repos/${REPO}/commits/${head_sha}/check-runs" \ + -f check_name="$CONTEXT" -f per_page=100 \ + --jq '.check_runs[] | "\(.id) \(.status) \(.conclusion // "none")"' | sort -n | tail -n 1)" + echo "${CONTEXT} on pull request head ${head_sha}: ${newest:-no run}" + read -r _ status conclusion <<<"${newest:-0 absent none}" + case "${status}:${conclusion}" in + completed:success | completed:neutral | completed:skipped) ;; + *) + echo "::error::${CONTEXT} is not proven on the queued pull request head (${status} ${conclusion})" + exit 1 + ;; + esac + + ctx-non-dev-base-guard: + name: "non-dev-base-guard" + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Read the queued pull request head verdict + env: + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} + QUEUE_REF: ${{ github.event.merge_group.head_ref }} + CONTEXT: "non-dev-base-guard" + run: | + set -euo pipefail + if [[ ! "$QUEUE_REF" =~ /pr-([1-9][0-9]*)-[0-9a-f]{40}$ ]]; then + echo "::error::merge-queue ref '${QUEUE_REF}' names no pull request" + exit 1 + fi + head_sha="$(gh api "repos/${REPO}/pulls/${BASH_REMATCH[1]}" --jq .head.sha)" + newest="$(gh api --paginate --method GET "repos/${REPO}/commits/${head_sha}/check-runs" \ + -f check_name="$CONTEXT" -f per_page=100 \ + --jq '.check_runs[] | "\(.id) \(.status) \(.conclusion // "none")"' | sort -n | tail -n 1)" + echo "${CONTEXT} on pull request head ${head_sha}: ${newest:-no run}" + read -r _ status conclusion <<<"${newest:-0 absent none}" + case "${status}:${conclusion}" in + completed:success | completed:neutral | completed:skipped) ;; + *) + echo "::error::${CONTEXT} is not proven on the queued pull request head (${status} ${conclusion})" + exit 1 + ;; + esac + + ctx-git-env-scrub-gate: + name: "Git env scrub gate" + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Read the queued pull request head verdict + env: + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} + QUEUE_REF: ${{ github.event.merge_group.head_ref }} + CONTEXT: "Git env scrub gate" + run: | + set -euo pipefail + if [[ ! "$QUEUE_REF" =~ /pr-([1-9][0-9]*)-[0-9a-f]{40}$ ]]; then + echo "::error::merge-queue ref '${QUEUE_REF}' names no pull request" + exit 1 + fi + head_sha="$(gh api "repos/${REPO}/pulls/${BASH_REMATCH[1]}" --jq .head.sha)" + newest="$(gh api --paginate --method GET "repos/${REPO}/commits/${head_sha}/check-runs" \ + -f check_name="$CONTEXT" -f per_page=100 \ + --jq '.check_runs[] | "\(.id) \(.status) \(.conclusion // "none")"' | sort -n | tail -n 1)" + echo "${CONTEXT} on pull request head ${head_sha}: ${newest:-no run}" + read -r _ status conclusion <<<"${newest:-0 absent none}" + case "${status}:${conclusion}" in + completed:success | completed:neutral | completed:skipped) ;; + *) + echo "::error::${CONTEXT} is not proven on the queued pull request head (${status} ${conclusion})" + exit 1 + ;; + esac + + ctx-advisory-job-gate-advisory-job-gate: + name: "advisory-job-gate / advisory-job-gate" + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Read the queued pull request head verdict + env: + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} + QUEUE_REF: ${{ github.event.merge_group.head_ref }} + CONTEXT: "advisory-job-gate / advisory-job-gate" + run: | + set -euo pipefail + if [[ ! "$QUEUE_REF" =~ /pr-([1-9][0-9]*)-[0-9a-f]{40}$ ]]; then + echo "::error::merge-queue ref '${QUEUE_REF}' names no pull request" + exit 1 + fi + head_sha="$(gh api "repos/${REPO}/pulls/${BASH_REMATCH[1]}" --jq .head.sha)" + newest="$(gh api --paginate --method GET "repos/${REPO}/commits/${head_sha}/check-runs" \ + -f check_name="$CONTEXT" -f per_page=100 \ + --jq '.check_runs[] | "\(.id) \(.status) \(.conclusion // "none")"' | sort -n | tail -n 1)" + echo "${CONTEXT} on pull request head ${head_sha}: ${newest:-no run}" + read -r _ status conclusion <<<"${newest:-0 absent none}" + case "${status}:${conclusion}" in + completed:success | completed:neutral | completed:skipped) ;; + *) + echo "::error::${CONTEXT} is not proven on the queued pull request head (${status} ${conclusion})" + exit 1 + ;; + esac + + ctx-byok-catalogue-no-house-entry: + name: "BYOK Catalogue No House Entry" + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Read the queued pull request head verdict + env: + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} + QUEUE_REF: ${{ github.event.merge_group.head_ref }} + CONTEXT: "BYOK Catalogue No House Entry" + run: | + set -euo pipefail + if [[ ! "$QUEUE_REF" =~ /pr-([1-9][0-9]*)-[0-9a-f]{40}$ ]]; then + echo "::error::merge-queue ref '${QUEUE_REF}' names no pull request" + exit 1 + fi + head_sha="$(gh api "repos/${REPO}/pulls/${BASH_REMATCH[1]}" --jq .head.sha)" + newest="$(gh api --paginate --method GET "repos/${REPO}/commits/${head_sha}/check-runs" \ + -f check_name="$CONTEXT" -f per_page=100 \ + --jq '.check_runs[] | "\(.id) \(.status) \(.conclusion // "none")"' | sort -n | tail -n 1)" + echo "${CONTEXT} on pull request head ${head_sha}: ${newest:-no run}" + read -r _ status conclusion <<<"${newest:-0 absent none}" + case "${status}:${conclusion}" in + completed:success | completed:neutral | completed:skipped) ;; + *) + echo "::error::${CONTEXT} is not proven on the queued pull request head (${status} ${conclusion})" + exit 1 + ;; + esac + + ctx-no-coding-plan-endpoint: + name: "No Coding Plan Endpoint" + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Read the queued pull request head verdict + env: + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} + QUEUE_REF: ${{ github.event.merge_group.head_ref }} + CONTEXT: "No Coding Plan Endpoint" + run: | + set -euo pipefail + if [[ ! "$QUEUE_REF" =~ /pr-([1-9][0-9]*)-[0-9a-f]{40}$ ]]; then + echo "::error::merge-queue ref '${QUEUE_REF}' names no pull request" + exit 1 + fi + head_sha="$(gh api "repos/${REPO}/pulls/${BASH_REMATCH[1]}" --jq .head.sha)" + newest="$(gh api --paginate --method GET "repos/${REPO}/commits/${head_sha}/check-runs" \ + -f check_name="$CONTEXT" -f per_page=100 \ + --jq '.check_runs[] | "\(.id) \(.status) \(.conclusion // "none")"' | sort -n | tail -n 1)" + echo "${CONTEXT} on pull request head ${head_sha}: ${newest:-no run}" + read -r _ status conclusion <<<"${newest:-0 absent none}" + case "${status}:${conclusion}" in + completed:success | completed:neutral | completed:skipped) ;; + *) + echo "::error::${CONTEXT} is not proven on the queued pull request head (${status} ${conclusion})" + exit 1 + ;; + esac + + ctx-routing-tier-bindability: + name: "Routing Tier Bindability" + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Read the queued pull request head verdict + env: + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} + QUEUE_REF: ${{ github.event.merge_group.head_ref }} + CONTEXT: "Routing Tier Bindability" + run: | + set -euo pipefail + if [[ ! "$QUEUE_REF" =~ /pr-([1-9][0-9]*)-[0-9a-f]{40}$ ]]; then + echo "::error::merge-queue ref '${QUEUE_REF}' names no pull request" + exit 1 + fi + head_sha="$(gh api "repos/${REPO}/pulls/${BASH_REMATCH[1]}" --jq .head.sha)" + newest="$(gh api --paginate --method GET "repos/${REPO}/commits/${head_sha}/check-runs" \ + -f check_name="$CONTEXT" -f per_page=100 \ + --jq '.check_runs[] | "\(.id) \(.status) \(.conclusion // "none")"' | sort -n | tail -n 1)" + echo "${CONTEXT} on pull request head ${head_sha}: ${newest:-no run}" + read -r _ status conclusion <<<"${newest:-0 absent none}" + case "${status}:${conclusion}" in + completed:success | completed:neutral | completed:skipped) ;; + *) + echo "::error::${CONTEXT} is not proven on the queued pull request head (${status} ${conclusion})" + exit 1 + ;; + esac + + ctx-fsm-handler-drift: + name: "fsm-handler-drift" + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Read the queued pull request head verdict + env: + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} + QUEUE_REF: ${{ github.event.merge_group.head_ref }} + CONTEXT: "fsm-handler-drift" + run: | + set -euo pipefail + if [[ ! "$QUEUE_REF" =~ /pr-([1-9][0-9]*)-[0-9a-f]{40}$ ]]; then + echo "::error::merge-queue ref '${QUEUE_REF}' names no pull request" + exit 1 + fi + head_sha="$(gh api "repos/${REPO}/pulls/${BASH_REMATCH[1]}" --jq .head.sha)" + newest="$(gh api --paginate --method GET "repos/${REPO}/commits/${head_sha}/check-runs" \ + -f check_name="$CONTEXT" -f per_page=100 \ + --jq '.check_runs[] | "\(.id) \(.status) \(.conclusion // "none")"' | sort -n | tail -n 1)" + echo "${CONTEXT} on pull request head ${head_sha}: ${newest:-no run}" + read -r _ status conclusion <<<"${newest:-0 absent none}" + case "${status}:${conclusion}" in + completed:success | completed:neutral | completed:skipped) ;; + *) + echo "::error::${CONTEXT} is not proven on the queued pull request head (${status} ${conclusion})" + exit 1 + ;; + esac + + ctx-node-migration-vendor-parity-gate: + name: "node-migration-vendor-parity-gate" + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Read the queued pull request head verdict + env: + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} + QUEUE_REF: ${{ github.event.merge_group.head_ref }} + CONTEXT: "node-migration-vendor-parity-gate" + run: | + set -euo pipefail + if [[ ! "$QUEUE_REF" =~ /pr-([1-9][0-9]*)-[0-9a-f]{40}$ ]]; then + echo "::error::merge-queue ref '${QUEUE_REF}' names no pull request" + exit 1 + fi + head_sha="$(gh api "repos/${REPO}/pulls/${BASH_REMATCH[1]}" --jq .head.sha)" + newest="$(gh api --paginate --method GET "repos/${REPO}/commits/${head_sha}/check-runs" \ + -f check_name="$CONTEXT" -f per_page=100 \ + --jq '.check_runs[] | "\(.id) \(.status) \(.conclusion // "none")"' | sort -n | tail -n 1)" + echo "${CONTEXT} on pull request head ${head_sha}: ${newest:-no run}" + read -r _ status conclusion <<<"${newest:-0 absent none}" + case "${status}:${conclusion}" in + completed:success | completed:neutral | completed:skipped) ;; + *) + echo "::error::${CONTEXT} is not proven on the queued pull request head (${status} ${conclusion})" + exit 1 + ;; + esac + + ctx-skill-mapping-input-coverage-gate: + name: "skill-mapping-input-coverage-gate" + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Read the queued pull request head verdict + env: + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} + QUEUE_REF: ${{ github.event.merge_group.head_ref }} + CONTEXT: "skill-mapping-input-coverage-gate" + run: | + set -euo pipefail + if [[ ! "$QUEUE_REF" =~ /pr-([1-9][0-9]*)-[0-9a-f]{40}$ ]]; then + echo "::error::merge-queue ref '${QUEUE_REF}' names no pull request" + exit 1 + fi + head_sha="$(gh api "repos/${REPO}/pulls/${BASH_REMATCH[1]}" --jq .head.sha)" + newest="$(gh api --paginate --method GET "repos/${REPO}/commits/${head_sha}/check-runs" \ + -f check_name="$CONTEXT" -f per_page=100 \ + --jq '.check_runs[] | "\(.id) \(.status) \(.conclusion // "none")"' | sort -n | tail -n 1)" + echo "${CONTEXT} on pull request head ${head_sha}: ${newest:-no run}" + read -r _ status conclusion <<<"${newest:-0 absent none}" + case "${status}:${conclusion}" in + completed:success | completed:neutral | completed:skipped) ;; + *) + echo "::error::${CONTEXT} is not proven on the queued pull request head (${status} ${conclusion})" + exit 1 + ;; + esac + + ctx-validate: + name: "validate" + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Read the queued pull request head verdict + env: + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} + QUEUE_REF: ${{ github.event.merge_group.head_ref }} + CONTEXT: "validate" + run: | + set -euo pipefail + if [[ ! "$QUEUE_REF" =~ /pr-([1-9][0-9]*)-[0-9a-f]{40}$ ]]; then + echo "::error::merge-queue ref '${QUEUE_REF}' names no pull request" exit 1 fi + head_sha="$(gh api "repos/${REPO}/pulls/${BASH_REMATCH[1]}" --jq .head.sha)" + newest="$(gh api --paginate --method GET "repos/${REPO}/commits/${head_sha}/check-runs" \ + -f check_name="$CONTEXT" -f per_page=100 \ + --jq '.check_runs[] | "\(.id) \(.status) \(.conclusion // "none")"' | sort -n | tail -n 1)" + echo "${CONTEXT} on pull request head ${head_sha}: ${newest:-no run}" + read -r _ status conclusion <<<"${newest:-0 absent none}" + case "${status}:${conclusion}" in + completed:success | completed:neutral | completed:skipped) ;; + *) + echo "::error::${CONTEXT} is not proven on the queued pull request head (${status} ${conclusion})" + exit 1 + ;; + esac