- actions/checkout pinned to 11bd71901bbe5b1630ceea73d27597364c9af683 (v4.2.2) - actions/setup-node pinned to 1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a (v4.2.0) - workflow-level permissions: contents: read (the pipeline only reads the repo) - no floating @v4 tags remain anywhere in the workflow
241 lines
12 KiB
YAML
241 lines
12 KiB
YAML
name: CI
|
|
|
|
on:
|
|
pull_request:
|
|
push:
|
|
branches: [main]
|
|
|
|
# Minimal workflow token: the pipeline only reads repository contents
|
|
# (checkout, frozen install, typecheck, lint, tests, build) — nothing writes
|
|
# back, so the token is scoped to contents: read (E00-S05-T01).
|
|
permissions:
|
|
contents: read
|
|
|
|
# E00-S05-T01 — CI quality baseline (required PR stages).
|
|
#
|
|
# Every pull request runs the required quality stages in order, each gated on
|
|
# the previous stage through `needs`:
|
|
#
|
|
# 1. frozen-install — the committed lockfile installs cleanly
|
|
# 2. typecheck — every workspace package passes `tsc --noEmit`
|
|
# 3. formatting-lint — the dependency-free formatting/lint policy (`pnpm lint`)
|
|
# 4. unit — deterministic unit suites (health, config, env example…)
|
|
# 5. architecture — static workspace/container structure and policy suites
|
|
# 6. postgres-integration — PostgreSQL adapter suites (docker-gated real-stack
|
|
# probes run where a Docker daemon is available and
|
|
# skip cleanly otherwise)
|
|
# 7. build-apps — builds the workspace applications (apps/*: server
|
|
# today, admin when E06-S01 lands) and verifies the
|
|
# compiled artifact
|
|
#
|
|
# The stage order, the `needs` chain and the tests/ coverage are locked in by
|
|
# tests/ci-stages.test.mjs (architecture stage). Third-party actions
|
|
# (actions/checkout, actions/setup-node) are pinned to full commit SHAs — no
|
|
# floating tags — and the workflow token is scoped to `contents: read`
|
|
# (E00-S05-T01 hardening). Container/Compose smoke on main/release branches
|
|
# and the Docker Compose baseline stack (E00-S02) stay out of scope for this
|
|
# stage list.
|
|
|
|
jobs:
|
|
# Stage 1 — frozen install (E00-S05-T01). Runs before every later stage: the
|
|
# committed lockfile must install cleanly and be up to date with the
|
|
# manifests before any stage proceeds.
|
|
frozen-install:
|
|
name: Stage 1 — Frozen lockfile install (E00-S05-T01)
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
- name: Install Node.js 24
|
|
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
|
|
with:
|
|
node-version: '24'
|
|
- name: Enable pnpm (corepack, pinned to 11.23.0 via packageManager)
|
|
run: corepack enable
|
|
- name: Install dependencies (frozen lockfile)
|
|
run: pnpm install --frozen-lockfile
|
|
- name: Verify workspace groups
|
|
run: pnpm -r list --depth -1
|
|
|
|
# Stage 2 — typecheck (E00-S05-T01).
|
|
typecheck:
|
|
name: Stage 2 — Typecheck (E00-S05-T01)
|
|
needs: frozen-install
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
- name: Install Node.js 24
|
|
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
|
|
with:
|
|
node-version: '24'
|
|
- name: Enable pnpm (corepack, pinned to 11.23.0 via packageManager)
|
|
run: corepack enable
|
|
- name: Install dependencies (frozen lockfile)
|
|
run: pnpm install --frozen-lockfile
|
|
- name: Typecheck every workspace package
|
|
run: pnpm typecheck
|
|
|
|
# Stage 3 — formatting/lint policy (E00-S05-T01). `pnpm lint` runs the
|
|
# dependency-free formatting-policy suite (tests/formatting-policy.test.mjs):
|
|
# LF line endings, no BOM, no trailing whitespace, no tab indentation, final
|
|
# newline, and valid JSON with 2-space indentation and no duplicate keys.
|
|
formatting-lint:
|
|
name: Stage 3 — Formatting/lint policy (E00-S05-T01)
|
|
needs: typecheck
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
- name: Install Node.js 24
|
|
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
|
|
with:
|
|
node-version: '24'
|
|
- name: Enable pnpm (corepack, pinned to 11.23.0 via packageManager)
|
|
run: corepack enable
|
|
- name: Install dependencies (frozen lockfile)
|
|
run: pnpm install --frozen-lockfile
|
|
- name: Run the formatting/lint policy
|
|
run: pnpm lint
|
|
|
|
# Stage 4 — unit tests (E00-S05-T01). Deterministic suites that gate every
|
|
# PR without external services: the app health endpoint, the secrets scan
|
|
# and the configuration service suites (schema, startup error, log
|
|
# redaction, env adapter, .env.example). The config suites boot the
|
|
# committed server, so the config and database-postgres packages are built
|
|
# first.
|
|
unit:
|
|
name: Stage 4 — Unit tests (E00-S05-T01)
|
|
needs: formatting-lint
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
- name: Install Node.js 24
|
|
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
|
|
with:
|
|
node-version: '24'
|
|
- name: Enable pnpm (corepack, pinned to 11.23.0 via packageManager)
|
|
run: corepack enable
|
|
- name: Install dependencies (frozen lockfile)
|
|
run: pnpm install --frozen-lockfile
|
|
- name: Build the config and database-postgres packages (the probes boot the committed server which imports them)
|
|
run: pnpm --filter @personal-blog/config build && pnpm --filter @personal-blog/database-postgres build
|
|
- name: Run the health-endpoint unit suite
|
|
run: node --test tests/health-endpoint.test.mjs
|
|
- name: Run the secrets-not-embedded unit suite
|
|
run: node --test tests/secrets-not-embedded.test.mjs
|
|
- name: Run the config-schema unit suite
|
|
run: node --test tests/config-schema.test.mjs
|
|
- name: Run the config-startup-error unit suite
|
|
run: node --test tests/config-startup-error.test.mjs
|
|
- name: Run the config-log-redaction unit suite
|
|
run: node --test tests/config-log-redaction.test.mjs
|
|
- name: Run the config-env-adapter unit suite
|
|
run: node --test tests/config-env-adapter.test.mjs
|
|
- name: Run the env-example unit suite
|
|
run: node --test tests/env-example.test.mjs
|
|
|
|
# Stage 5 — architecture tests (E00-S05-T01). Static structure and policy
|
|
# suites: dependency boundaries, workspace layout/configuration, strict
|
|
# TypeScript base, engine/TypeScript pins, root commands, frozen-install
|
|
# clean clone, container definition structure, and the CI baseline itself.
|
|
architecture:
|
|
name: Stage 5 — Architecture tests (E00-S05-T01)
|
|
needs: unit
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
- name: Install Node.js 24
|
|
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
|
|
with:
|
|
node-version: '24'
|
|
- name: Enable pnpm (corepack, pinned to 11.23.0 via packageManager)
|
|
run: corepack enable
|
|
- name: Install dependencies (frozen lockfile)
|
|
run: pnpm install --frozen-lockfile
|
|
- name: Build the config and database-postgres packages (strict-tsconfig typechecks apps/server which imports them)
|
|
run: pnpm --filter @personal-blog/config build && pnpm --filter @personal-blog/database-postgres build
|
|
- name: Run the architecture-import suite
|
|
run: node --test tests/architecture-import.test.mjs
|
|
- name: Run the no-core-extension-imports suite
|
|
run: node --test tests/no-core-extension-imports.test.mjs
|
|
- name: Run the workspace-layout suite
|
|
run: node --test tests/workspace-layout.test.mjs
|
|
- name: Run the workspace-config suite
|
|
run: node --test tests/workspace-config.test.mjs
|
|
- name: Run the strict-tsconfig suite
|
|
run: node --test tests/strict-tsconfig.test.mjs
|
|
- name: Run the typescript-pin suite
|
|
run: node --test tests/typescript-pin.test.mjs
|
|
- name: Run the node-engine suite
|
|
run: node --test tests/node-engine.test.mjs
|
|
- name: Run the frozen-install suite
|
|
run: node --test tests/frozen-install.test.mjs
|
|
- name: Run the root-commands suite
|
|
run: node --test tests/root-commands.test.mjs
|
|
- name: Run the compose-config suite
|
|
run: node --test tests/compose-config.test.mjs
|
|
- name: Run the build-targets suite
|
|
run: node --test tests/build-targets.test.mjs
|
|
- name: Run the non-root-user suite
|
|
run: node --test tests/non-root-user.test.mjs
|
|
- name: Run the readonly-rootfs suite
|
|
run: node --test tests/readonly-rootfs.test.mjs
|
|
- name: Run the database-postgres-imports suite
|
|
run: node --test tests/database-postgres-imports.test.mjs
|
|
- name: Run the ci-stages baseline suite
|
|
run: node --test tests/ci-stages.test.mjs
|
|
|
|
# Stage 6 — PostgreSQL integration tests (E00-S05-T01). The PostgreSQL
|
|
# adapter suites (migration ledger, advisory lock, failure diagnostic) and
|
|
# the app readiness suite: their docker-gated real-stack probes (migrate an
|
|
# empty database, hold/release the advisory lock, readiness waits on the
|
|
# startup migration run) run where a Docker daemon is available and skip
|
|
# cleanly otherwise; the static and deterministic probes always gate. The
|
|
# app-readiness probes boot the committed server, so the config and
|
|
# database-postgres packages are built first.
|
|
postgres-integration:
|
|
name: Stage 6 — PostgreSQL integration tests (E00-S05-T01)
|
|
needs: architecture
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
- name: Install Node.js 24
|
|
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
|
|
with:
|
|
node-version: '24'
|
|
- name: Enable pnpm (corepack, pinned to 11.23.0 via packageManager)
|
|
run: corepack enable
|
|
- name: Install dependencies (frozen lockfile)
|
|
run: pnpm install --frozen-lockfile
|
|
- name: Build the config and database-postgres packages (the probes boot the committed server which imports them)
|
|
run: pnpm --filter @personal-blog/config build && pnpm --filter @personal-blog/database-postgres build
|
|
- name: Run the database-postgres-ledger suite
|
|
run: node --test tests/database-postgres-ledger.test.mjs
|
|
- name: Run the database-postgres-lock suite
|
|
run: node --test tests/database-postgres-lock.test.mjs
|
|
- name: Run the database-postgres-diagnostic suite
|
|
run: node --test tests/database-postgres-diagnostic.test.mjs
|
|
- name: Run the app-readiness suite
|
|
run: node --test tests/app-readiness.test.mjs
|
|
|
|
# Stage 7 — build the applications (E00-S05-T01). Builds every workspace
|
|
# application under apps/ (apps/server today; apps/admin when E06-S01 lands
|
|
# — the pnpm apps-group glob picks it up automatically) and verifies the
|
|
# compiled server artifact.
|
|
build-apps:
|
|
name: Stage 7 — Build the admin and server applications (E00-S05-T01)
|
|
needs: postgres-integration
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
- name: Install Node.js 24
|
|
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
|
|
with:
|
|
node-version: '24'
|
|
- name: Enable pnpm (corepack, pinned to 11.23.0 via packageManager)
|
|
run: corepack enable
|
|
- name: Install dependencies (frozen lockfile)
|
|
run: pnpm install --frozen-lockfile
|
|
- name: Build the workspace applications (apps/* — server today, admin when E06-S01 lands)
|
|
run: pnpm --filter "./apps/**" run build
|
|
- name: Verify the compiled server application artifact
|
|
run: test -f apps/server/dist/index.js
|