# Local CI Verification Pipeline # Manual-dispatch only — validates devops/ci-local/ scaffolding and CI image. # Triggers: workflow_dispatch (Gitea UI or API). name: Local CI Verification on: workflow_dispatch: inputs: workflow: description: 'Archived workflow file to dry-run (e.g. test-matrix.yml). Leave empty to skip.' required: false default: '' dry_run: description: 'Pass -n (dry-run) to act' required: false default: 'true' jobs: validate-scaffolding: name: Validate CI scaffolding runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Check devops/ci-local files exist run: | echo "::group::Checking required files" errors=0 for f in \ devops/ci-local/.env.local.template \ devops/ci-local/run-act.sh \ devops/ci-local/run-act.ps1 \ devops/ci-local/README.md \ devops/ci-local/events/push.json \ devops/ci-local/events/pull-request.json \ devops/docker/Dockerfile.ci \ .actrc; do if [ -f "$f" ]; then echo "✓ $f" else echo "✗ MISSING: $f" errors=$((errors + 1)) fi done echo "::endgroup::" if [ "$errors" -gt 0 ]; then echo "::error::$errors required file(s) missing" exit 1 fi - name: Lint event JSON files run: | echo "::group::Validating JSON payloads" for f in devops/ci-local/events/*.json; do if python3 -m json.tool "$f" > /dev/null 2>&1; then echo "✓ $f — valid JSON" else echo "✗ $f — invalid JSON" exit 1 fi done echo "::endgroup::" - name: Verify runner scripts are executable run: | if [ ! -x devops/ci-local/run-act.sh ]; then echo "::warning::run-act.sh is not executable (chmod +x recommended)" fi build-ci-image: name: Build stellaops-ci image runs-on: ubuntu-latest needs: validate-scaffolding steps: - name: Checkout uses: actions/checkout@v4 - name: Build CI image run: | docker build \ -t stellaops-ci:local \ -f devops/docker/Dockerfile.ci \ . - name: Verify image exists run: | docker image inspect stellaops-ci:local > /dev/null 2>&1 echo "stellaops-ci:local built successfully" docker image ls stellaops-ci:local dry-run-smoke: name: Dry-run smoke test runs-on: ubuntu-latest needs: build-ci-image steps: - name: Checkout uses: actions/checkout@v4 - name: Install act run: | curl -sSL https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash - name: List jobs from archived test-matrix run: | act -l -W .gitea/workflows-archived/test-matrix.yml \ -P ubuntu-latest=stellaops-ci:local \ --env-file devops/ci-local/.env.local.template - name: Dry-run archived test-matrix run: | act -W .gitea/workflows-archived/test-matrix.yml -n \ -P ubuntu-latest=stellaops-ci:local \ --env-file devops/ci-local/.env.local.template \ -e devops/ci-local/events/push.json - name: Dry-run user-specified workflow if: ${{ github.event.inputs.workflow != '' }} run: | WORKFLOW="${{ github.event.inputs.workflow }}" ARCHIVE_PATH=".gitea/workflows-archived/${WORKFLOW}" if [ ! -f "$ARCHIVE_PATH" ]; then echo "::error::Workflow not found: $ARCHIVE_PATH" exit 1 fi ACT_ARGS="-W $ARCHIVE_PATH -P ubuntu-latest=stellaops-ci:local --env-file devops/ci-local/.env.local.template -e devops/ci-local/events/push.json" if [ "${{ github.event.inputs.dry_run }}" = "true" ]; then ACT_ARGS="$ACT_ARGS -n" fi echo "Running: act $ACT_ARGS" act $ACT_ARGS