#!/usr/bin/env bash # ci/l1.sh — Stage 4: L1 rendering checks. Runs in CI WITHOUT a cluster # (docs/14: "L1 rendering assertions run in CI without a cluster"). # # L1 asserts ServiceDefinition -> rendered resources match golden expectations # (e.g. `egress: vpn` renders the kill-switched egress path). The actual render # + assert is Chainsaw's L1 layer, owned by the conformance harness (T-0.4). # CI just invokes the runner filtered to the L1 layer and the touched subset. set -euo pipefail CI_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # shellcheck disable=SC1091 source "${CI_DIR}/lib.sh" log "Stage: L1 rendering checks (no cluster)" mkartifacts if ! entrypoint_ready "$CONFORMANCE_CMD"; then skip "conformance runner not present at '${CONFORMANCE_CMD}' (T-0.4 / conformance/ not delivered yet) — UNWIRED, not green" summary "- l1-render: **SKIPPED** (conformance runner missing — T-0.4)" exit 3 fi # Touched-requirement subset (R-TEST-03). Empty subset => run all L1 as a sanity net. mapfile -t reqs < <("${CI_DIR}/touched-requirements.sh" || true) req_args=() if [ "${#reqs[@]}" -gt 0 ]; then log "touched requirements: ${reqs[*]}" req_args=(--requirements "$(IFS=,; echo "${reqs[*]}")") fi # Contract we ASSUME of conformance/run.sh (flag for PM to reconcile): # --layer l1 select the L1 rendering layer (no cluster) # --requirements R-A,R-B filter to the touched subset # --junit write JUnit XML # --coverage write the requirement-coverage report "$CONFORMANCE_CMD" \ --layer l1 \ "${req_args[@]}" \ --junit "${JUNIT_DIR}/l1.junit.xml" \ --coverage "${COVERAGE_DIR}" ok "L1 rendering checks passed" summary "- l1-render: **passed**"