Files
git.stella-ops.org/docs/modules/devops/console-ci-contract.md
StellaOps Bot c13355923f
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Console CI / console-ci (push) Has been cancelled
blocked 4
2025-11-23 17:53:41 +02:00

4.1 KiB

Console CI Contract (DEVOPS-CONSOLE-23-001)

Scope

Define a deterministic, offline-friendly CI pipeline for the Console web app covering lint, type-check, unit, Storybook a11y, Playwright smoke, Lighthouse perf/a11y, and artifact retention.

Stages & Gates

  1. Setup
    • Node 20.x, pnpm 9.x from cached tarball (tools/cache/node20.tgz, tools/cache/pnpm-9.tgz).
    • Restore node_modules from .pnpm-store cache key console-${{ hashFiles('pnpm-lock.yaml') }}; fallback to offline tarball local-npm-cache.tar.zst.
    • Export PLAYWRIGHT_BROWSERS_PATH=./.playwright and hydrate from tools/cache/playwright-browsers.tar.zst.
  2. Lint/Format/Types (fail-fast)
    • pnpm lint
    • pnpm format:check
    • pnpm typecheck
  3. Unit Tests
    • pnpm test -- --runInBand --reporter=junit --outputFile=.artifacts/junit.xml
    • Collect coverage to .artifacts/coverage (lcov + summary).
  4. Storybook a11y
    • pnpm storybook:build (static export)
    • pnpm storybook:a11y --ci --output .artifacts/storybook-a11y.json
  5. Playwright Smoke
    • pnpm playwright test --config=playwright.config.ci.ts --reporter=list,junit=.artifacts/playwright.xml
    • Upload playwright-report/ and .artifacts/playwright.xml.
  6. Lighthouse (CI mode)
    • Serve built app with pnpm serve --port 4173 and run pnpm lhci autorun --config=lighthouserc.ci.js --upload.target=filesystem --upload.outputDir=.artifacts/lhci
    • Enforce budgets: performance >= 0.80, accessibility >= 0.90, best-practices >= 0.90, seo >= 0.85.
  7. SBOM/Provenance
    • pnpm exec syft packages dir:dist --output=spdx-json=.artifacts/console.spdx.json
    • Attach .artifacts/console.spdx.json and provenance attestation from release job.

Determinism & Offline

  • No network fetches after cache hydrate; fail if pnpm install hits the network (set PNPM_FETCH_RETRIES=0, PNPM_OFFLINE=1).
  • All artifacts written under .artifacts/ and uploaded as CI artifacts.
  • Timestamps normalized via SOURCE_DATE_EPOCH=${{ github.run_id }} for reproducible Storybook/LH builds.

Inputs/Secrets

  • Required only for Playwright auth flows: CONSOLE_E2E_USER, CONSOLE_E2E_PASS (scoped to non-prod tenant). Pipeline must soft-skip auth tests when unset.
  • No signing keys required in CI; release handles signing separately.

Outputs

  • .artifacts/junit.xml (unit)
  • .artifacts/playwright.xml, playwright-report/
  • .artifacts/storybook-a11y.json
  • .artifacts/lhci/ (Lighthouse reports)
  • .artifacts/coverage/
  • .artifacts/console.spdx.json

Example Gitea workflow snippet

- name: Console CI (DEVOPS-CONSOLE-23-001)
  uses: actions/setup-node@v4
  with:
    node-version: '20'

- name: Prep pnpm
  run: |
    corepack enable
    corepack prepare pnpm@9 --activate

- name: Cache pnpm store
  uses: actions/cache@v4
  with:
    path: |
      ~/.pnpm-store
      ./node_modules
    key: console-${{ hashFiles('pnpm-lock.yaml') }}

- name: Install (offline)
  env:
    PNPM_FETCH_RETRIES: 0
    PNPM_OFFLINE: 1
  run: pnpm install --frozen-lockfile

- name: Lint/Types
  run: pnpm lint && pnpm format:check && pnpm typecheck

- name: Unit
  run: pnpm test -- --runInBand --reporter=junit --outputFile=.artifacts/junit.xml

- name: Storybook a11y
  run: pnpm storybook:build && pnpm storybook:a11y --ci --output .artifacts/storybook-a11y.json

- name: Playwright
  run: pnpm playwright test --config=playwright.config.ci.ts --reporter=list,junit=.artifacts/playwright.xml

- name: Lighthouse
  run: pnpm serve --port 4173 & pnpm lhci autorun --config=lighthouserc.ci.js --upload.target=filesystem --upload.outputDir=.artifacts/lhci

- name: SBOM
  run: pnpm exec syft packages dir:dist --output=spdx-json=.artifacts/console.spdx.json

- name: Upload artifacts
  uses: actions/upload-artifact@v4
  with:
    name: console-ci-artifacts
    path: .artifacts

Acceptance to mark blocker cleared

  • Pipeline executes fully in a clean runner with network blocked after cache hydrate.
  • All artefacts uploaded and budgets enforced; failing budgets fail the job.
  • Soft-skip auth-dependent tests when secrets are absent, without failing the pipeline.