feat: adding taint analysis #35
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: ["**"] | |
| pull_request: | |
| permissions: | |
| contents: read | |
| security-events: write | |
| checks: write | |
| pull-requests: write | |
| env: | |
| CARGO_TERM_COLOR: always | |
| jobs: | |
| # ── 1. Compile-check (fast feedback) ──────────────────────────────────────── | |
| check: | |
| name: Check | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Cache Rust dependencies | |
| uses: Swatinem/rust-cache@v2 | |
| - name: cargo check | |
| run: cargo check --all-targets | |
| # ── 2. Unit + integration tests ───────────────────────────────────────────── | |
| test: | |
| name: Test | |
| runs-on: ubuntu-latest | |
| needs: check | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Cache Rust dependencies | |
| uses: Swatinem/rust-cache@v2 | |
| - name: Run all tests | |
| run: cargo test --verbose | |
| # ── 3. Dogfood — oxide-ci scans itself ────────────────────────────────────── | |
| self-scan: | |
| name: Self-Scan | |
| runs-on: ubuntu-latest | |
| needs: test | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 # full history needed for --history and --blame | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Cache Rust dependencies | |
| uses: Swatinem/rust-cache@v2 | |
| - name: Build oxide-ci | |
| run: cargo build --release | |
| # ── Config validation ──────────────────────────────────────────────────── | |
| - name: Validate .oxideci.toml | |
| run: ./target/release/oxide-ci check-config | |
| # ── Secret + SAST scan (JS/TS/Python/Go AST) — human-readable ─────────── | |
| # Reads .oxideci.toml to exclude test fixtures and docs that | |
| # intentionally contain example/fake patterns. | |
| - name: Scan for secrets, PII and dangerous patterns | |
| run: ./target/release/oxide-ci scan | |
| # ── Incremental scan — only staged/changed files ───────────────────────── | |
| - name: Scan files changed since last commit | |
| run: ./target/release/oxide-ci scan --since HEAD~1 || true | |
| # ── git blame enrichment ───────────────────────────────────────────────── | |
| - name: Scan with blame enrichment | |
| run: ./target/release/oxide-ci scan --blame || true | |
| # ── Multi-format output validation ─────────────────────────────────────── | |
| - name: Generate SARIF report | |
| if: always() | |
| continue-on-error: true | |
| run: ./target/release/oxide-ci scan --format sarif > oxide-ci-results.sarif 2>/dev/null || true | |
| - name: Generate JSON report | |
| if: always() | |
| continue-on-error: true | |
| run: ./target/release/oxide-ci scan --format json > oxide-ci-results.json 2>/dev/null || true | |
| - name: Generate JUnit XML report | |
| if: always() | |
| continue-on-error: true | |
| run: ./target/release/oxide-ci scan --format junit > oxide-ci-results.xml 2>/dev/null || true | |
| - name: Generate GitLab SAST report | |
| if: always() | |
| continue-on-error: true | |
| run: ./target/release/oxide-ci scan --format gitlab > gl-sast-report.json 2>/dev/null || true | |
| # ── Upload scan artifacts ──────────────────────────────────────────────── | |
| - name: Upload SARIF to GitHub Security tab | |
| if: always() | |
| uses: github/codeql-action/upload-sarif@v3 | |
| with: | |
| sarif_file: oxide-ci-results.sarif | |
| continue-on-error: true | |
| - name: Upload JUnit XML | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: junit-report | |
| path: oxide-ci-results.xml | |
| continue-on-error: true | |
| - name: Upload GitLab SAST report | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: gitlab-sast-report | |
| path: gl-sast-report.json | |
| continue-on-error: true | |
| - name: Upload JSON report | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: json-report | |
| path: oxide-ci-results.json | |
| continue-on-error: true | |
| # ── GitHub Check Run annotations + PR summary comment ──────────────────── | |
| # Posts per-line annotations to the Checks tab and a rich summary comment | |
| # on the PR. Only meaningful on pull_request events. | |
| - name: Post GitHub Check Run annotations and PR summary | |
| if: github.event_name == 'pull_request' | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| GITHUB_REPOSITORY: ${{ github.repository }} | |
| GITHUB_SHA: ${{ github.sha }} | |
| run: ./target/release/oxide-ci scan --annotate || true | |
| # ── Baseline workflow ──────────────────────────────────────────────────── | |
| - name: Save scan baseline (main branch only) | |
| if: github.ref == 'refs/heads/main' | |
| run: | | |
| ./target/release/oxide-ci scan --update-baseline || true | |
| git diff --quiet .oxide-baseline.json 2>/dev/null || echo "Baseline updated" | |
| - name: Gate on new findings only (PRs) | |
| if: github.event_name == 'pull_request' && hashFiles('.oxide-baseline.json') != '' | |
| run: ./target/release/oxide-ci scan --since-baseline | |
| # ── Kubernetes lint — exits 0 when no YAML manifests are present ───────── | |
| - name: Lint Kubernetes manifests | |
| run: ./target/release/oxide-ci lint | |
| # ── Dependency audit — queries OSV database for known CVEs ─────────────── | |
| - name: Audit dependencies (OSV) | |
| run: ./target/release/oxide-ci audit | |
| # ── SBOM generation (CycloneDX 1.5) ───────────────────────────────────── | |
| - name: Generate SBOM | |
| run: ./target/release/oxide-ci sbom --output sbom.json | |
| - name: Upload SBOM artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: sbom | |
| path: sbom.json | |
| # Validate SBOM structure | |
| - name: Validate SBOM has expected fields | |
| run: | | |
| jq -e '.bomFormat == "CycloneDX" and .specVersion == "1.5" and (.components | length > 0)' sbom.json | |
| # ── 4. Performance audit (Lighthouse + Reassure) ───────────────────────────── | |
| perf: | |
| name: Performance | |
| runs-on: ubuntu-latest | |
| needs: test | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Cache Rust dependencies | |
| uses: Swatinem/rust-cache@v2 | |
| - name: Build oxide-ci | |
| run: cargo build --release | |
| # Lighthouse — gates on PageSpeed Insights scores for a deployed URL. | |
| # Set LIGHTHOUSE_URL as a repository variable (Settings → Variables) to activate. | |
| # Set PAGESPEED_API_KEY as a repository secret for higher API quota. | |
| - name: Lighthouse audit | |
| if: ${{ vars.LIGHTHOUSE_URL != '' }} | |
| env: | |
| PAGESPEED_API_KEY: ${{ secrets.PAGESPEED_API_KEY }} | |
| run: | | |
| ./target/release/oxide-ci lighthouse \ | |
| --url "${{ vars.LIGHTHOUSE_URL }}" \ | |
| --strategy mobile | |
| continue-on-error: true # informational until thresholds are tuned | |
| # Reassure — gates on React component render regressions. | |
| # Only runs when output/current.perf is present (produced by a prior | |
| # frontend job that runs `reassure measure` and uploads the artifact). | |
| - name: Reassure performance gate | |
| if: hashFiles('output/current.perf') != '' | |
| run: ./target/release/oxide-ci reassure | |
| continue-on-error: true # informational until baseline is established | |
| # ── 5. Formatting + lints ─────────────────────────────────────────────────── | |
| lint: | |
| name: Lint | |
| runs-on: ubuntu-latest | |
| needs: check | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Rust toolchain (with rustfmt + clippy) | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| components: rustfmt, clippy | |
| - name: Cache Rust dependencies | |
| uses: Swatinem/rust-cache@v2 | |
| - name: Check formatting | |
| run: cargo fmt --check | |
| - name: Run Clippy | |
| run: cargo clippy --all-targets -- -D warnings |