name: CI # Test gate for every push to main. The deploy story: main must be green here # before the stack is rebuilt (deploy workflow enforces it once SSH transport # secrets land). Jobs run in the runner's bare node:20-bullseye container — # toolchains bootstrap per-run. on: push: branches: [main] pull_request: jobs: backend-types: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Type-check NestJS backend run: | cd backend-nest npm ci --no-audit --no-fund 2>&1 | tail -2 npx tsc --noEmit frontend-build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Build frontend (vue-tsc gate + vite) run: | cd frontend npm ci --no-audit --no-fund 2>&1 | tail -2 npm run build agent-tests: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Cache cargo uses: actions/cache@v4 with: path: | ~/.cargo/registry ~/.cargo/git corrosion-host-agent/target key: cargo-${{ hashFiles('corrosion-host-agent/Cargo.lock') }} - name: Install Rust run: | apt-get update -qq && apt-get install -y -qq build-essential curl curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal echo "$HOME/.cargo/bin" >> $GITHUB_PATH - name: Test agent run: | cd corrosion-host-agent cargo test - name: Upload agent binary for integration uses: actions/upload-artifact@v3 with: name: agent-debug path: corrosion-host-agent/target/debug/corrosion-host-agent integration: runs-on: ubuntu-latest needs: agent-tests services: postgres: image: postgres:16 env: POSTGRES_USER: corrosion POSTGRES_PASSWORD: citest POSTGRES_DB: corrosion nats: image: nats:2.10-alpine steps: - uses: actions/checkout@v4 - name: Download agent binary uses: actions/download-artifact@v3 with: name: agent-debug path: agent-bin - name: Apply migrations to fresh DB run: | apt-get update -qq && apt-get install -y -qq postgresql-client until PGPASSWORD=citest psql -h postgres -U corrosion -d corrosion -c 'SELECT 1' >/dev/null 2>&1; do sleep 1; done for f in $(ls backend/migrations/*.sql | sort); do echo "applying $f" PGPASSWORD=citest psql -h postgres -U corrosion -d corrosion -v ON_ERROR_STOP=1 -q -f "$f" done - name: Build + boot backend run: | cd backend-nest npm ci --no-audit --no-fund 2>&1 | tail -2 npm run build DATABASE_URL=postgres://corrosion:citest@postgres:5432/corrosion \ NATS_URL=nats://nats:4222 \ JWT_SECRET=ci-secret ENCRYPTION_KEY=ci-encryption-key \ ADMIN_EMAIL=ci@corrosion.test ADMIN_PASSWORD=ci-password-123 ADMIN_USERNAME=CI \ nohup node dist/main.js > /tmp/backend.log 2>&1 & for i in $(seq 1 30); do code=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:3000/api/auth/login -X POST -H 'Content-Type: application/json' -d '{}' || true) [ "$code" = "400" ] && echo "backend up" && exit 0 sleep 2 done echo "backend failed to come up"; cat /tmp/backend.log; exit 1 - name: Run agent↔backend contract suite run: | chmod +x agent-bin/corrosion-host-agent LICENSE_ID=$(PGPASSWORD=citest psql -h postgres -U corrosion -d corrosion -t -A -c 'SELECT id FROM licenses LIMIT 1') echo "license under test: $LICENSE_ID" [ -n "$LICENSE_ID" ] || { echo "admin seed did not create a license"; cat /tmp/backend.log; exit 1; } LICENSE_ID="$LICENSE_ID" \ DATABASE_URL=postgres://corrosion:citest@postgres:5432/corrosion \ NATS_URL=nats://nats:4222 \ AGENT_BIN=$PWD/agent-bin/corrosion-host-agent \ node contract-tests/agent-backend.contract.mjs - name: Backend log on failure if: failure() run: cat /tmp/backend.log || true