name: CI

on:
  push:
    branches: [main]
  pull_request:

env:
  CARGO_TERM_COLOR: always
  # Matches what docker-compose produces locally; the schema-snapshot
  # guardrail and any other DB-backed tests run against this service.
  DATABASE_URL: postgres://picloud:picloud@localhost:5432/picloud
  # The DB-backed suites skip themselves when DATABASE_URL is unset. In CI it is
  # always set, so this makes that skip a hard error: if the database ever goes
  # missing (a broken service container, a lost env), the build goes RED instead
  # of green-but-empty. Honored by picloud_test_support::abort_if_db_required.
  PICLOUD_REQUIRE_DB: "1"

jobs:
  rust:
    name: Rust — fmt, clippy, test
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:15
        env:
          POSTGRES_USER: picloud
          POSTGRES_PASSWORD: picloud
          POSTGRES_DB: picloud
        ports:
          - 5432:5432
        options: >-
          --health-cmd "pg_isready -U picloud"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
    steps:
      - uses: actions/checkout@v4

      # rust-toolchain.toml pins the channel; this action honors it.
      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@stable
        with:
          components: rustfmt, clippy

      - name: Cache cargo
        uses: Swatinem/rust-cache@v2

      - name: Format check
        run: cargo fmt --all -- --check

      - name: Clippy
        run: cargo clippy --all-targets --all-features -- -D warnings

      # `--include-ignored` is load-bearing. Every DB-backed integration test is
      # `#[ignore = "needs DATABASE_URL..."]`, and CI omitted the flag — so CI ran
      # 927 tests and silently skipped 237, among them ALL of authz.rs and api.rs
      # and the entire CLI journey suite. The isolation and RBAC tests existed but
      # never executed (AUDIT.md F-Q-014). CI does provide Postgres, so run them.
      #
      # `--all-targets` (not a bare `cargo test`) is deliberate: it runs the lib,
      # bins, and integration tests but NOT doctests. `-- --include-ignored`
      # un-ignores not just `#[ignore]` tests but also ` ```ignore ` DOCTESTS,
      # which are illustrative pseudocode that does not compile — so a bare
      # `cargo test ... -- --include-ignored` fails on them. Doctests run in their
      # own step below, without the flag. (Clippy already uses `--all-targets` for
      # the same doctest-excluding reason.)
      #
      # The CLI journeys are a SEPARATE step, and deliberately not part of the
      # workspace run: they spawn a real picloud whose dispatcher/orchestrator
      # claim loops are global by design (one instance owns one database). Run
      # concurrently with the manager-core suites — which share this database —
      # it would claim their outbox and workflow rows out from under them. Keeping
      # the steps sequential keeps that live server off the shared DB while the
      # other suites are using it.
      - name: Test (workspace, including DB-backed tests)
        run: cargo test --workspace --exclude picloud-cli --all-targets -- --include-ignored

      # Doctests, run WITHOUT --include-ignored so ` ```ignore ` snippets stay
      # ignored. `--all-targets` above skips these, so nothing else covers them.
      - name: Doctests
        run: cargo test --workspace --doc

      # The journey harness execs the prebuilt target/debug/picloud and does NOT
      # rebuild it, so a stale binary would silently test old server code.
      - name: Build picloud (the journey harness execs this binary)
        run: cargo build -p picloud

      # The spawned server inherits this env; without a secret key it aborts at
      # startup and every journey fails as "/healthz never returned 200".
      # `--all-targets` for the same reason as above (the journeys are `#[ignore]`
      # integration tests; picloud-cli's doctests, if any, run in the Doctests step).
      - name: Test (CLI journeys)
        env:
          PICLOUD_DEV_MODE: "true"
          PICLOUD_DEV_INSECURE_KEY: i-understand-this-is-insecure
        run: cargo test -p picloud-cli --all-targets -- --include-ignored

  dashboard:
    name: Dashboard — check
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: dashboard
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm
          cache-dependency-path: dashboard/package-lock.json
      - name: Install deps
        run: npm ci
      - name: Svelte check
        run: npm run check
