T-0.2 CI merge-gate pipeline + portable local runners (R-TEST-02/03, R-GITOPS-01)
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
1 parent
de56c55dcc
commit
0d86630271
15 files changed
+1022
-2
No files matched your search
@@ -0,0 +1,84 @@
|
||||
# `ci/` — portable merge gate (runnable today, without Gitea)
|
||||
|
||||
**Task T-0.2 · R-TEST-02 (reproducible, single-command) · Owner WS-GITOPS (CI).**
|
||||
|
||||
The same merge gate the Gitea Actions workflow runs
|
||||
([`.gitea/workflows/`](../.gitea/workflows/README.md)), as plain scripts + a Makefile so the gates are
|
||||
runnable **now**, before any Gitea host or cluster exists. CI and a laptop call the *identical*
|
||||
scripts, so `make -C ci gate` == the CI merge gate.
|
||||
|
||||
## Quick start
|
||||
|
||||
```bash
|
||||
make -C ci gate # the single command: run every stage + the R-TEST-03 decision
|
||||
make -C ci help # list targets
|
||||
make -C ci tools # which pinned tools are installed locally
|
||||
make -C ci touched # print the touched-requirement subset for this branch vs main
|
||||
```
|
||||
|
||||
Individual stages:
|
||||
|
||||
```bash
|
||||
make -C ci lint # yaml/lint (no cluster; live now)
|
||||
make -C ci l0 # ServiceDefinition schema + Kyverno (no cluster; live now)
|
||||
make -C ci l1 # L1 rendering checks (no cluster; live now)
|
||||
make -C ci conformance # L2/L3 in-cluster Chainsaw Job (SKIPS unless CLUSTER_AVAILABLE=true)
|
||||
```
|
||||
|
||||
## Exit-code contract
|
||||
|
||||
Every stage script uses: **`0` = pass · `1` = fail (blocks merge) · `3` = SKIPPED** (cluster-gated
|
||||
with no cluster, or an unwired seam / missing tool). A `3` is **never** counted as green — that is how
|
||||
the gate stays honest in Phase 0 (no fake green).
|
||||
|
||||
## Reproducibility (R-TEST-02)
|
||||
|
||||
- **Version-pinned:** all tool versions live in [`versions.env`](versions.env) — the single source of
|
||||
truth shared by the local scripts and the CI installer. Bumping a version is a normal
|
||||
feature-branch → main change.
|
||||
- **Single command, environment-agnostic:** `make -C ci gate` on any machine with the pinned tools.
|
||||
- **Deterministic:** no cluster state is assumed; L2/L3 SKIP unless a cluster is explicitly declared.
|
||||
|
||||
## Files
|
||||
|
||||
```
|
||||
ci/
|
||||
Makefile targets: lint · l0 · l1 · conformance · gate · touched · tools · versions
|
||||
versions.env PINNED tool versions (R-TEST-02) — single source of truth
|
||||
lib.sh shared helpers: logging, tool checks, cluster detection, artifact paths
|
||||
yamllint.yaml lint config for the yaml/lint stage
|
||||
lint.sh Stage: yaml/lint
|
||||
l0.sh Stage: ServiceDefinition schema validation + Kyverno L0 policy gate
|
||||
l1.sh Stage: L1 rendering checks (Chainsaw L1 via the conformance runner)
|
||||
conformance.sh Stage: L2/L3 in-cluster Chainsaw Job (trigger + collect)
|
||||
touched-requirements.sh compute the R-* subset a change touches (drives the R-TEST-03 filter)
|
||||
gate.sh run all stages + the merge decision (the single command)
|
||||
README.md this file
|
||||
```
|
||||
|
||||
## Integration seams — entrypoints owned by OTHER agents
|
||||
|
||||
This gate is an **orchestrator**. It does not implement schema validation, Kyverno policies, or the
|
||||
conformance runner — those are other workstreams' deliverables. Each seam is **env-overridable** so
|
||||
the owning agent / PM can reconcile the real entrypoint **without editing these scripts**. Defaults
|
||||
below are this workstream's **assumptions** — flagged for the PM to verify at integration.
|
||||
|
||||
| Seam | Owner / task | Env override | Assumed default | Assumed interface |
|
||||
|---|---|---|---|---|
|
||||
| ServiceDefinition schema validator | WS-GITOPS · **T-0.3** (`schemas/`) | `SCHEMA_VALIDATE_CMD` | `schemas/validate.sh` | `validate.sh catalog/*.yaml` → exit 0/1; `--version` supported |
|
||||
| Kyverno L0 policies + tests | WS-TEST · **T-0.5** (`platform/kyverno/`) | `KYVERNO_POLICY_DIR` | `platform/kyverno` | contains `kyverno-test.yaml` files discoverable by `kyverno test <dir>` |
|
||||
| Conformance runner (Chainsaw) | WS-TEST · **T-0.4** (`conformance/`) | `CONFORMANCE_CMD` | `conformance/run.sh` | `run.sh --layer <l1\|l2,l3> [--requirements R-A,R-B] [--trigger in-cluster-job] --junit <file> --coverage <dir>` |
|
||||
| Catalog (ServiceDefinitions) | WS-APPS | `CATALOG_DIR` | `catalog` | `*.yaml` ServiceDefinition files |
|
||||
|
||||
Artifact locations (git-ignored): JUnit → `results/junit/*.xml`; coverage → `reports/coverage/**`.
|
||||
Override with `JUNIT_DIR` / `COVERAGE_DIR` if the runner writes elsewhere.
|
||||
|
||||
**A seam that is missing or not executable reports SKIPPED (exit 3), not a false pass** — so during
|
||||
parallel Phase 0 development the gate is green-honest, and each seam goes live automatically the moment
|
||||
its owner delivers a runnable entrypoint.
|
||||
|
||||
## Cluster gating
|
||||
|
||||
`CLUSTER_AVAILABLE=true` (env locally, `vars.CLUSTER_AVAILABLE` in Gitea) makes the L2/L3 stage run and
|
||||
be **required**; anything else makes it **SKIP** (Phase 0). `REQUIRE_CLUSTER_TESTS=true` (Phase 1+)
|
||||
turns any unverified cluster-needing touched requirement into a hard block.
|
||||
Reference in new issue
Block a user