Feat/emergency sweep #146
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: [main, "feat/**", "fix/**"] | |
| pull_request: | |
| env: | |
| CARGO_TERM_COLOR: always | |
| jobs: | |
| # ── Smart contract ──────────────────────────────────────────────────────── | |
| contract: | |
| name: Contract (Rust / Soroban) | |
| runs-on: ubuntu-latest | |
| env: | |
| RUSTFLAGS: "-D warnings" | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: wasm32-unknown-unknown | |
| components: rustfmt, clippy | |
| - uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| target | |
| key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} | |
| - run: cargo fmt --all -- --check | |
| - run: cargo clippy --target wasm32-unknown-unknown --release -- -D warnings | |
| - run: cargo test | |
| - run: cargo build --target wasm32-unknown-unknown --release | |
| - name: Record wasm SHA-256 | |
| run: sha256sum target/wasm32-unknown-unknown/release/niffyinsure.wasm | tee niffyinsure.wasm.sha256 | |
| - name: Simulate wasm drift (staging acceptance test) | |
| run: | | |
| ACTUAL=$(cat niffyinsure.wasm.sha256 | awk '{print $1}') | |
| EXPECTED=$(jq -r '.contracts[0].expectedWasmHash' contracts/deployment-registry.json) | |
| # In CI the registry holds a placeholder; drift is detected when they differ. | |
| # In staging, set NIFFYINSURE_EXPECTED_WASM_HASH to a known-wrong value to | |
| # verify the alert path fires. Exit 0 here — alerting is runtime, not build-time. | |
| if [ "$EXPECTED" = "\${NIFFYINSURE_EXPECTED_WASM_HASH}" ]; then | |
| echo "Registry uses env placeholder — skipping drift comparison in CI" | |
| elif [ "$ACTUAL" != "$EXPECTED" ]; then | |
| echo "::warning::Wasm drift detected: expected=$EXPECTED actual=$ACTUAL" | |
| else | |
| echo "Wasm hash matches registry: $ACTUAL" | |
| fi | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: niffyinsure-wasm-${{ github.sha }} | |
| path: | | |
| target/wasm32-unknown-unknown/release/niffyinsure.wasm | |
| niffyinsure.wasm.sha256 | |
| retention-days: 30 | |
| # ── Backend ─────────────────────────────────────────────────────────────── | |
| backend: | |
| name: Backend (Node / TypeScript) | |
| runs-on: ubuntu-latest | |
| defaults: | |
| run: | |
| working-directory: backend | |
| services: | |
| redis: | |
| image: redis:7-alpine | |
| ports: | |
| - 6379:6379 | |
| options: >- | |
| --health-cmd "redis-cli ping" | |
| --health-interval 5s | |
| --health-timeout 3s | |
| --health-retries 5 | |
| --health-start-period 5s | |
| env: | |
| REDIS_HOST: 127.0.0.1 | |
| REDIS_PORT: 6379 | |
| NODE_ENV: test | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 22 | |
| - run: npm install | |
| - run: npm run lint | |
| - run: npm run build | |
| - run: npm test | |
| # ── Dependency audit / supply-chain ───────────────────────────────────── | |
| # Policy: CRITICAL CVEs fail the build. HIGH CVEs produce a warning and | |
| # must be triaged within 7 days. Accepted risks require a signed-off entry | |
| # in docs/ops/audit-exceptions.md before the override label is applied. | |
| # Override process: | |
| # 1. Engineer opens a PR adding the CVE to audit-exceptions.md with | |
| # justification, mitigations, and a review-by date. | |
| # 2. A second engineer approves the PR. | |
| # 3. Add the GitHub label `audit-exception-approved` to the failing PR. | |
| # 4. Re-run this job — it will pass once the exception is documented. | |
| dependency-audit: | |
| name: Dependency Audit (npm / SBOM) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 22 | |
| - name: Audit backend dependencies | |
| working-directory: backend | |
| run: | | |
| npm install --ignore-scripts | |
| # Fail on critical; warn on high (exit 0 so we can capture output) | |
| npm audit --audit-level=critical | |
| npm audit --audit-level=high || echo "::warning::High-severity advisories found — triage within 7 days per audit policy" | |
| - name: Audit frontend dependencies | |
| working-directory: frontend | |
| run: | | |
| npm ci --ignore-scripts | |
| npm audit --audit-level=critical | |
| npm audit --audit-level=high || echo "::warning::High-severity advisories found — triage within 7 days per audit policy" | |
| - name: Generate SBOM (backend) | |
| working-directory: backend | |
| run: npx --yes @cyclonedx/cyclonedx-npm --output-format JSON --output-file ../sbom-backend.json | |
| - name: Generate SBOM (frontend) | |
| working-directory: frontend | |
| run: npx --yes @cyclonedx/cyclonedx-npm --output-format JSON --output-file ../sbom-frontend.json | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: sbom-${{ github.sha }} | |
| path: | | |
| sbom-backend.json | |
| sbom-frontend.json | |
| retention-days: 90 | |
| # ── Frontend ────────────────────────────────────────────────────────────── | |
| frontend: | |
| name: Frontend (Next.js / TypeScript) | |
| runs-on: ubuntu-latest | |
| defaults: | |
| run: | |
| working-directory: frontend | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 22 | |
| cache: npm | |
| cache-dependency-path: frontend/package-lock.json | |
| - run: npm ci | |
| - run: npm run lint | |
| - run: npm run build | |
| - run: npm test |