#!/usr/bin/env bash # scripts/run_ci.sh - reproduce the CI pipeline locally. # # Mirrors the central pipeline contract (pipelines/ci.yaml) which both # .gitea/workflows/ci.yml (Gitea Actions, dev) and # .github/workflows/ci.yml (GitHub Actions, production) implement. # # Runs the same three stages in the same order: # 1. lint — py_compile all Python files # 2. test — pytest test suite (offline) # 3. check-only — run_platform.sh --check-only (offline, no AWS) # # Fails on the first stage that errors. Exits 0 with "CI PIPELINE OK" # when all stages pass. # # Usage: # bash scripts/run_ci.sh # run all stages # bash scripts/run_ci.sh --quiet # suppress per-stage banners set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" cd "$ROOT" QUIET=0 for arg in "$@"; do case "$arg" in --quiet) QUIET=1 ;; *) echo "FAIL: unknown argument: $arg" >&2; exit 1 ;; esac done banner() { [ "$QUIET" = "1" ] || echo "" echo "── $1 ──" [ "$QUIET" = "1" ] || echo "" } fail() { echo "FAIL: $*" >&2; exit 1; } echo "=== ACDL CI Pipeline (local reproduction) ===" echo "contract: pipelines/ci.yaml (3 stages)" echo "" banner "Stage 1/3: lint (py_compile)" python3 -m py_compile \ core/confidence_signal.py \ core/outbox_writer.py \ core/output_publisher.py \ core/contract_resolver.py \ core/lambda/contract_ingestor.py \ adapters/terraform/adapter.py \ adapters/terraform/policy/checkov_adapter.py \ adapters/terraform/policy/custom_rules/acdl_tagging.py \ adapters/wiz/wiz_adapter.py \ adapters/kyverno/kyverno_adapter.py \ scripts/push_consumer_image.py \ || fail "lint: py_compile failed" echo "lint: OK" banner "Stage 2/3: test (pytest)" python3 -m pytest tests/ -v --tb=short || fail "test: pytest failed" echo "test: OK" banner "Stage 3/3: check-only (run_platform.sh --check-only)" bash scripts/run_platform.sh --check-only || fail "check-only: run_platform.sh failed" echo "check-only: OK" echo "" echo "=== CI PIPELINE OK ===" echo "3 stages passed: lint, test, check-only" exit 0