Files
atomic-design-poc/.github/workflows/ci.yml
T
ehoandClaude Opus 4.8 7d2a36ff22
CI / frontend (push) Successful in 2m11s
CI / storybook-a11y (push) Successful in 5m46s
CI / backend (push) Successful in 1m29s
CI / e2e (push) Successful in 2m55s
CI / semgrep (push) Successful in 1m1s
CI / api-client-drift (push) Successful in 2m5s
feat(arch): WP-38 — dependency graph + declarative boundaries (dependency-cruiser)
Adopt dependency-cruiser as the single declarative source for bounded-context +
atomic-layer boundaries, replacing the per-context no-restricted-imports blocks that
had to be hand-copied (and had left herregistratie uncovered). `.dependency-cruiser.js`
encodes context direction (everyone→shared, herregistratie→registratie, showcase→*),
domain-purity, contracts-import-nothing, ui↛infrastructure, ApiClient confinement, and
no-circular. `npm run dep:check` enforces (wired into ci-local.sh + the frontend CI job);
`npm run dep:graph` emits a committed mermaid context×layer graph. ESLint slimmed to
no-explicit-any + template a11y. Docs + new-context skill updated to the single source.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 13:51:04 +02:00

160 lines
6.2 KiB
YAML

name: CI
on:
push:
branches: [main]
tags: ['v*']
pull_request:
# Least privilege by default.
permissions:
contents: read
# A newer push to the same ref cancels the in-flight run.
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
jobs:
frontend:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24
cache: npm
- run: npm ci --prefer-offline --no-audit --no-fund
- run: npm run lint
# Bounded-context + atomic-layer boundaries (WP-38, dependency-cruiser).
- run: npm run dep:check
- run: npm run format:check
- run: npm run check:tokens
- run: npm test
# --localize builds every configured locale (nl + en, angular.json's i18n
# block) in one pass; i18nMissingTranslation:"error" (angular.json) fails
# this step if messages.en.xlf is missing a unit the source (WP-20) gains.
- run: npx ng build --localize
# The shipped bundle must stay clean; dev-only advisories are excluded.
- run: npm audit --omit=dev
storybook-a11y:
# Axe runs against every story in the static build; a violation fails the build.
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24
cache: npm
- run: npm ci --prefer-offline --no-audit --no-fund
# Cache the chromium download across runs; `install --with-deps` then only
# runs the (fast, idempotent) apt deps check on a hit.
- uses: actions/cache@v4
with:
path: ~/.cache/ms-playwright
key: playwright-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
- run: npx playwright install --with-deps chromium
- run: npm run build-storybook
- run: npm run test-storybook:ci
backend:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
dotnet-version: 10.0.x
- uses: actions/cache@v4
with:
path: ~/.nuget/packages
key: nuget-${{ runner.os }}-${{ hashFiles('**/*.csproj') }}
restore-keys: nuget-${{ runner.os }}-
- run: dotnet format backend/BigRegister.slnx --verify-no-changes
- run: dotnet test backend/BigRegister.slnx
e2e:
# Smoke-level Playwright run against the REAL FE+backend (WP-19) — a fresh
# runner checkout per run, so there's no bigregister.db (WP-22, gitignored)
# left over from a prior run to leak state in; the backend creates + migrates
# an empty one on this boot, same as a fresh clone always has.
# Playwright's `webServer` (playwright.config.ts) starts BOTH the backend and
# `ng serve`, waits for them, runs the suite, and tears them down — all in the
# one `npm run e2e` process. Do NOT background them as separate steps: a `&`
# process from one Actions step is dead by the next step, so `wait-on` hung
# forever (the 2-hour e2e hang).
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24
cache: npm
- uses: actions/setup-dotnet@v4
with:
dotnet-version: 10.0.x
- uses: actions/cache@v4
with:
path: ~/.nuget/packages
key: nuget-${{ runner.os }}-${{ hashFiles('**/*.csproj') }}
restore-keys: nuget-${{ runner.os }}-
- run: npm ci --prefer-offline --no-audit --no-fund
- uses: actions/cache@v4
with:
path: ~/.cache/ms-playwright
key: playwright-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
- run: npx playwright install --with-deps chromium
- run: npm run e2e
semgrep:
# SAST for both sides — replaces CodeQL, which is GitHub-only (its analyze step uploads
# SARIF to GitHub's code-scanning API) and can't run on this Gitea instance. Semgrep OSS
# is a plain CLI: no account, no external platform API. Findings print in the job log.
# Installed via the runner's preinstalled python3/pip — NOT `setup-python` (its Python
# download failed on this runner) and NOT a job `container:` (this act_runner times out
# pulling the base runner image for container jobs). `--break-system-packages` survives
# PEP-668; pip drops `semgrep` on PATH. `--ignore-installed` is required because some of
# semgrep's deps (e.g. PyJWT) are already present as apt-managed packages, which pip cannot
# uninstall ("RECORD file not found") — this flag installs fresh without uninstalling, so it
# never touches the Debian copies. Don't drop it.
# ponytail: report-only for now (no `--error`, so the job stays green while the initial
# findings are triaged); flip to `--error` to make it a blocking gate. See WP-30.
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- run: python3 -m pip install --break-system-packages --ignore-installed semgrep
# p/default = curated cross-language security (covers JS/TS); p/csharp = the backend.
# Anonymous registry fetch; --metrics=off disables telemetry (not `auto`, which uploads
# project metadata).
- run: semgrep scan --config p/default --config p/csharp --metrics=off
api-client-drift:
# The committed typed client must match the backend OpenAPI doc.
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24
cache: npm
- uses: actions/setup-dotnet@v4
with:
# 8.0 for the bundled NSwag runtime, 10.0 to build/emit the spec.
dotnet-version: |
8.0.x
10.0.x
- uses: actions/cache@v4
with:
path: ~/.nuget/packages
key: nuget-${{ runner.os }}-${{ hashFiles('**/*.csproj') }}
restore-keys: nuget-${{ runner.os }}-
- run: npm ci --prefer-offline --no-audit --no-fund
- run: npm run gen:api
- run: git diff --exit-code src/app/shared/infrastructure/api-client.ts backend/swagger.json