bytelyst-devops-tools/dashboard/.gitea/workflows/ci.yml
Hermes VM 18180aab78 test(dashboard): Phase 5 P1 — auth/csrf/health/orchestrator tests + coverage gate
Closes the Phase 5 P1 testing checkbox. Adds 35 new unit tests across the
modules called out in the roadmap and wires a v8 coverage gate into CI.

Coverage of newly-tested files (lines / branches):
  lib/auth.ts                          94.4% / 100%
  lib/csrf.ts                          95.1% /  90%
  modules/health/repository.ts          100% /  92%
  modules/deployments/orchestrator.ts  95.2% /  74%
  modules/services/repository.ts        100% / 100%
  modules/hermes-ops/repository.ts     95.2% /  68%

Threshold (lines/funcs/stmts ≥85%, branches ≥65%) is scoped to those six
files via `coverage.include` so untested legacy modules (vm, system,
audit, route handlers) report but don't gate. Add files there as they
gain real tests — ratchet up, never relax.

Test approach mirrors the existing services/hermes-ops suites: hoisted
mocks for I/O (fetch, child_process, fs/promises, cosmos-init), real
JOSE-signed JWTs for the auth path, fake timers for cache TTL and CSRF
expiry assertions.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-05-30 06:56:16 +00:00

108 lines
2.9 KiB
YAML

name: CI — DevOps Dashboard
on:
push:
branches: [main]
paths:
- 'backend/**'
- 'web/**'
- 'shared/**'
- 'package.json'
- 'pnpm-lock.yaml'
- 'pnpm-workspace.yaml'
- '.pnpmfile.cjs'
- '.gitea/workflows/ci.yml'
pull_request:
paths:
- 'backend/**'
- 'web/**'
- 'shared/**'
- 'package.json'
- 'pnpm-lock.yaml'
- 'pnpm-workspace.yaml'
- '.pnpmfile.cjs'
- '.gitea/workflows/ci.yml'
concurrency:
group: ci-devops-dashboard-${{ github.ref }}
cancel-in-progress: true
env:
# Self-contained CI: resolve @bytelyst/* deps from the local Gitea registry
# rather than a sibling learning_ai_common_plat checkout on the runner.
BYTELYST_PACKAGE_SOURCE: gitea
jobs:
build-and-test:
name: Build, Test & Typecheck
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
# Check out into the runner workspace (${{ gitea.workspace }}) instead of
# cd-ing into a hard-coded host path and `git reset --hard` on the live
# checkout. CI must never mutate an operator's working tree.
- name: Checkout
uses: actions/checkout@v4
- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: 22
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@10.6.5 --activate
- name: Secret scan
run: pnpm secret-scan
- name: Install dependencies
run: pnpm install:gitea
- name: Lint
run: pnpm lint
- name: Typecheck
run: pnpm typecheck
- name: Build
run: pnpm build
- name: Unit tests
run: pnpm test:run
# Coverage gate for the backend's tested modules (auth, csrf, health,
# hermes-ops, deployments/orchestrator, services). Thresholds live in
# `backend/vitest.config.ts`. Add files there as they gain real tests
# — ratchet up, never relax.
- name: Coverage gate (backend)
run: pnpm --filter @bytelyst/devops-backend test:coverage
# TODO(ci-e2e-hardening): Playwright E2E needs a started stack + ops-API
# interception before it can run deterministically in CI. Tracked in
# docs/prompts/ci-e2e-hardening.md (Phase 5 P2). Re-enable once wired.
# - name: E2E tests
# run: pnpm --filter @bytelyst/devops-web test:e2e
docker-build:
name: Build Docker Images
runs-on: ubuntu-latest
needs: [build-and-test]
timeout-minutes: 20
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build backend Docker image
run: docker build -f backend/Dockerfile -t devops-backend:latest .
- name: Build web Docker image
run: docker build -f web/Dockerfile -t devops-web:latest .
- name: Test Docker Compose
run: |
docker compose up -d
sleep 10
docker compose down