{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://acdl.cloudinit.dev/schemas/pipeline.schema.json", "title": "ACDL Central Pipeline Contract", "description": "Declarative contract for a CI/CD pipeline. Both Gitea Actions (.gitea/workflows/ci.yml, dev) and GitHub Actions (.github/workflows/ci.yml, production) implement the stages, commands, triggers, and runner declared here. The shell script scripts/run_ci.sh mirrors the same stages for local reproducibility. The contract is the single source of truth; the workflow YAMLs and run_ci.sh are generated/validated against it.", "$comment": "The pipeline contract does not replace workflow YAML syntax — it declares the *intent* (stages, commands, triggers, runner) that both Gitea and GitHub workflows implement. A test (tests/test_pipeline_contract.py) validates conformance: the workflow YAMLs must declare the same jobs/stages/commands as the contract, and run_ci.sh must run the same commands in the same order.", "type": "object", "required": ["name", "triggers", "runner", "stages"], "properties": { "name": { "type": "string", "description": "Pipeline name (matches the workflow 'name:' field)." }, "environment": { "type": "string", "enum": ["dev", "production"], "description": "Declared environment. dev = Gitea Actions; production = GitHub Actions. Does not change job commands — only documents which forge runs this instance." }, "triggers": { "type": "object", "required": ["push", "pull_request"], "properties": { "push": { "type": "array", "items": {"type": "string"}, "description": "Branches that trigger the pipeline on push." }, "pull_request": { "type": "array", "items": {"type": "string"}, "description": "Branches that trigger the pipeline on PR." } } }, "runner": { "type": "string", "description": "Runner image (e.g. 'ubuntu-latest'). Both Gitea and GitHub use the same runner label." }, "python_version": { "type": "string", "description": "Python version for setup-python action." }, "stages": { "type": "array", "minItems": 1, "items": {"$ref": "#/$defs/stage"} } }, "$defs": { "stage": { "type": "object", "required": ["name", "command", "required"], "properties": { "name": { "type": "string", "description": "Stage name (maps to the workflow job name)." }, "command": { "type": "string", "description": "The shell command to run for this stage. Must be identical in the workflow YAML 'run:' block and in scripts/run_ci.sh." }, "required": { "type": "boolean", "description": "If true, a non-zero exit code fails the pipeline." }, "install": { "type": "string", "description": "Optional: pip install command to run before the stage command." }, "description": { "type": "string", "description": "Optional: human-readable description of what this stage does." } } } } }