# .gitea/workflows/gate.yml — the ENFORCED PR merge gate (Phase 6, WS-GITOSS). # # This is the LIVE gate wired to the in-cluster Gitea Actions runner (ns gitea-actions, # Docker executor + DinD). It runs the STATIC layers of the conformance gate — the ones # docs/14 says run "without a cluster": spec-immutability (best-effort), lint, Kyverno L0, # and L1 offline render checks. It is the single required status check on `main` # (see branch protection). `make -C ci lint l0 l1` here is byte-identical to a laptop run # (R-TEST-02) — the runner just installs the pinned tools from ci/versions.env first. # # The L2/L3 CONFORMANCE layer (behavioural + fault-injection, needs a live cluster) is # NOT wired yet — it is a deliberate design decision (a CI toolchain image + a scoped # in-cluster kubeconfig/RBAC for the runner). It is present below as an `if: false` # placeholder so the shape is visible and the wiring is a one-line flip once decided. # The full pipeline blueprint (spec-checkout, per-layer jobs, decision job) is retained # dormant in merge-gate.yaml. --- name: gate on: pull_request: branches: [main] push: branches: - main - 'feature/**' - 'fix/**' - 'docs/**' - 'chore/**' concurrency: group: gate-${{ github.ref }} cancel-in-progress: true jobs: # Single required status check: the static merge gate. gate: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 # full history so ci/touched-requirements.sh can diff vs main - name: Install pinned CI toolchain (ci/versions.env) run: | ./.gitea/workflows/scripts/install-tools.sh l0 ./.gitea/workflows/scripts/install-tools.sh l1 # R-TEST-06: the spec is read-only to agents. The spec repo is NOT checked out into # CI here (it is a separate repo; SPEC_REPO_SLUG is not wired into this runner), so # the guard honestly SKIPS (exit 3) rather than faking green. A real drift/edit of a # co-located spec would exit 1 and fail. Tolerated: exit 3 only. - name: Spec immutability (R-TEST-06, skips if spec repo absent) run: make -C ci spec-immutability || [ "$?" -eq 3 ] - name: Static gate — lint + Kyverno L0 + L1 render run: make -C ci lint l0 l1 - name: Upload gate artifacts if: always() uses: actions/upload-artifact@v4 with: name: gate-junit-coverage path: | results/junit/*.xml reports/coverage/** if-no-files-found: ignore # ─────────────────────────────────────────────────────────────────────────── # PLACEHOLDER — NOT WIRED (STOP-and-report item, WS-GITOSS Phase 6). # L2/L3 conformance (Chainsaw behavioural + fault-injection) needs a LIVE cluster. # Turning this on is a design decision with two open sub-decisions: # 1. Toolchain: build+push a pinned CI image to the Gitea container registry and # reference it as the job image, vs. install-in-job from ci/versions.env (slower). # 2. Cluster creds: how the runner reaches the cluster — the intended model is an # in-cluster Chainsaw Job driven by its OWN scoped ServiceAccount (CI holds only a # narrow trigger credential; the runner mounts NO SA token today). That SA + RBAC # + the trigger secret do not exist yet. # Kept `if: false` so it never runs (shows skipped, never fakes green — HARD RULE 4). # ─────────────────────────────────────────────────────────────────────────── conformance: runs-on: ubuntu-latest needs: [gate] if: false steps: - name: Placeholder run: | echo "L2/L3 conformance not wired — see gate.yml header + WS-GITOSS report." >&2 exit 1