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>
108 lines
2.9 KiB
YAML
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
|