Skip to content

PR-CI #196

PR-CI #196 #811

Workflow file for this run

name: CI
run-name: >-
${{ github.event_name == 'pull_request' && format('PR-CI #{0}', github.event.pull_request.number)
|| github.event_name == 'merge_group' && 'MergeQueue-CI'
|| github.event_name == 'push' && 'Main-CI'
|| 'CI' }}
on:
push:
branches:
- main
pull_request:
types:
- opened
- reopened
- synchronize
- ready_for_review
merge_group:
permissions:
contents: read
# Cancel superseded runs for the same PR to save runner minutes. Never cancel
# in-progress runs for `push` (main) or `merge_group` — those must complete so
# the default branch and merge queue always have a definitive result.
concurrency:
group: ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
# ---------------------------------------------------------------------------
# LINT (gofmt via Go SDK, yamlfmt via go run)
# ---------------------------------------------------------------------------
lint:
name: Lint
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.draft == false }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
# This job executes untrusted PR code (make build/test/lint). Don't
# leave the GITHUB_TOKEN in the workspace git config while it runs.
persist-credentials: false
- uses: ./.github/actions/setup
- name: Run linters
run: make lint
# ---------------------------------------------------------------------------
# TIDY (module files + BUILD files in sync)
# ---------------------------------------------------------------------------
tidy:
name: Tidy
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.draft == false }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
# This job executes untrusted PR code (make build/test/lint). Don't
# leave the GITHUB_TOKEN in the workspace git config while it runs.
persist-credentials: false
- uses: ./.github/actions/setup
- name: Check module files are tidy
run: make check-tidy
- name: Check BUILD files are up to date
run: make check-gazelle
# ---------------------------------------------------------------------------
# BUILD AND UNIT TESTS
# ---------------------------------------------------------------------------
build-and-unit-test:
name: Build and Unit Test
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.draft == false }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
# This job executes untrusted PR code (make build/test/lint). Don't
# leave the GITHUB_TOKEN in the workspace git config while it runs.
persist-credentials: false
- uses: ./.github/actions/setup
- name: Build project
run: make build
- name: Run unit tests
run: make test
# ---------------------------------------------------------------------------
# INTEGRATION TESTS (e2e, gateway, orchestrator)
# ---------------------------------------------------------------------------
e2e:
name: E2E Integration Test
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.draft == false }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
# This job executes untrusted PR code (make build/test/lint). Don't
# leave the GITHUB_TOKEN in the workspace git config while it runs.
persist-credentials: false
- uses: ./.github/actions/setup
- name: Run E2E tests
run: make e2e-test
gateway-integration-test:
name: Gateway Integration Test
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.draft == false }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
# This job executes untrusted PR code (make build/test/lint). Don't
# leave the GITHUB_TOKEN in the workspace git config while it runs.
persist-credentials: false
- uses: ./.github/actions/setup
- name: Run Gateway integration tests
run: make integration-test-submitqueue-gateway
orchestrator-integration-test:
name: Orchestrator Integration Test
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.draft == false }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
# This job executes untrusted PR code (make build/test/lint). Don't
# leave the GITHUB_TOKEN in the workspace git config while it runs.
persist-credentials: false
- uses: ./.github/actions/setup
- name: Run Orchestrator integration tests
run: make integration-test-submitqueue-orchestrator
# ---------------------------------------------------------------------------
# EXTENSION TESTS
# ---------------------------------------------------------------------------
counter-integration-test:
name: Counter Extension Test
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.draft == false }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
# This job executes untrusted PR code (make build/test/lint). Don't
# leave the GITHUB_TOKEN in the workspace git config while it runs.
persist-credentials: false
- uses: ./.github/actions/setup
- uses: ./.github/actions/run-bazel-test
with:
target: //test/integration/extension/counter/...
queue-integration-test:
name: Queue Extension Test
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.draft == false }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
# This job executes untrusted PR code (make build/test/lint). Don't
# leave the GITHUB_TOKEN in the workspace git config while it runs.
persist-credentials: false
- uses: ./.github/actions/setup
- uses: ./.github/actions/run-bazel-test
with:
target: //test/integration/extension/messagequeue/...
storage-integration-test:
name: Storage Extension Test
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.draft == false }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
# This job executes untrusted PR code (make build/test/lint). Don't
# leave the GITHUB_TOKEN in the workspace git config while it runs.
persist-credentials: false
- uses: ./.github/actions/setup
- uses: ./.github/actions/run-bazel-test
with:
target: //test/integration/submitqueue/extension/storage/...
# ---------------------------------------------------------------------------
# CORE TESTS
# ---------------------------------------------------------------------------
consumer-integration-test:
name: Consumer Integration Test
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.draft == false }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
# This job executes untrusted PR code (make build/test/lint). Don't
# leave the GITHUB_TOKEN in the workspace git config while it runs.
persist-credentials: false
- uses: ./.github/actions/setup
- uses: ./.github/actions/run-bazel-test
with:
target: //test/integration/submitqueue/core/consumer/...
# ---------------------------------------------------------------------------
# WORKFLOW SECURITY LINT
#
# Guards against regressions in the workflows themselves: actionlint checks
# general validity; zizmor audits for GitHub Actions security smells
# (dangerous triggers, unpinned `uses:`, credential persistence, template
# injection). Keeps the pull_request_target / SHA-pinning hardening from
# silently eroding in future edits.
# ---------------------------------------------------------------------------
workflow-security:
name: Workflow Security Lint
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.draft == false }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
persist-credentials: false
- name: actionlint
uses: raven-actions/actionlint@205b530c5d9fa8f44ae9ed59f341a0db994aa6f8 # v2.1.2
- name: zizmor
uses: zizmorcore/zizmor-action@5f14fd08f7cf1cb1609c1e344975f152c7ee938d # v0.5.6
with:
# Pin the zizmor TOOL version (distinct from the action tag above) for
# reproducible audits matching local validation.
version: "1.25.2"
# Fail the job on findings without requiring GitHub Advanced Security
# / SARIF upload (which needs security-events: write and degrades on
# fork PRs). Keeps the gate self-contained.
advanced-security: false
# ci.yml and the composite actions it calls run untrusted PR code under
# the `pull_request` trigger. A repository secret referenced anywhere on
# that path is reachable by a malicious PR and can be exfiltrated on the
# PR run (before any review), so this path must stay secret-free — route
# any secret-bearing step through a SEPARATE trusted workflow
# (workflow_run / pull_request_target) that does not execute PR code.
#
# This guard catches ACCIDENTAL reintroduction by honest contributors; a
# malicious actor controlling ci.yml could delete the guard itself, so the
# real defenses remain (a) secrets scoped to a main-only Environment so a
# PR-triggered job cannot obtain them, and (b) CODEOWNERS review on
# .github/. GITHUB_TOKEN (least-privilege, read-only here) is allowlisted.
- name: Guard — no repository secrets on the untrusted-code path
run: |
hits="$(grep -rnE '\$\{\{[^}]*secrets\.' \
.github/workflows/ci.yml .github/actions \
| grep -vE 'secrets\.GITHUB_TOKEN' || true)"
if [ -n "$hits" ]; then
echo "::error::Repository secret referenced on the untrusted-code CI path (ci.yml / composite actions):" >&2
echo "$hits" >&2
echo "Move secret-bearing steps to a separate trusted workflow that does not run PR code." >&2
exit 1
fi
echo "OK: no repository secrets referenced in ci.yml or its composite actions."
# ---------------------------------------------------------------------------
# REQUIRED CHECKS GATE
#
# Fan-in aggregator that must turn RED when any required job fails or is
# cancelled. `if: always()` is critical: without it, this job is skipped
# when any `needs` dependency fails, and GitHub treats a skipped required
# status check as "not failed" — which let PR #151 merge through the
# merge queue despite failing e2e + orchestrator integration tests.
# ---------------------------------------------------------------------------
required-checks:
name: Required Checks
if: ${{ always() && (github.event_name != 'pull_request' || github.event.pull_request.draft == false) }}
runs-on: ubuntu-latest
needs:
- lint
- tidy
- build-and-unit-test
- e2e
- gateway-integration-test
- orchestrator-integration-test
- counter-integration-test
- queue-integration-test
- storage-integration-test
- consumer-integration-test
- workflow-security
steps:
- name: Fail if any required check did not succeed
if: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') || contains(needs.*.result, 'skipped') }}
# Pass the job-results context via env (not inline ${{ }} in the script)
# so there is no template expansion inside the run block.
env:
NEEDS_JSON: ${{ toJSON(needs) }}
run: |
echo "One or more required checks did not succeed:" >&2
echo "$NEEDS_JSON" >&2
exit 1
- name: All required checks passed
run: echo "All required checks passed!"