CI / Frozen lockfile install (pull_request) Successful in 54s
CI / Secrets not embedded (E00-S02-T08) (pull_request) Successful in 34s
CI / Database-postgres import isolation (E00-S03-T02) (pull_request) Successful in 30s
CI / Migration ledger (E00-S03-T03) (pull_request) Successful in 1m16s
CI / Migration advisory lock (E00-S03-T04) (pull_request) Successful in 54s
CI / Migration failure diagnostic (E00-S03-T05) (pull_request) Successful in 46s
CI / App readiness after migrations (E00-S03-T06) (pull_request) Successful in 1m6s
CI / Field-specific startup errors (E00-S04-T02) (pull_request) Successful in 1m2s
CI / Secret redaction from logs (E00-S04-T03) (pull_request) Successful in 1m1s
CI / TypeBox/Ajv config schema (E00-S04-T01) (pull_request) Successful in 50s
CI / Env adapter owns process.env (E00-S04-T04) (pull_request) Successful in 1m5s
CI / Compose config (E00-S03-T01) (pull_request) Successful in 26s
The non-container guide now notes that HOST is validated at the adapter boundary as a hostname/IP (invalid values fail startup naming the field) and that the server passes config.host to server.listen, so a configured HOST binds exactly that interface and the startup log reflects the actual bind. The config-env-adapter CI job comment is refreshed to describe the extended suite (HOST validation + loopback-only boot probe).
306 lines
15 KiB
YAML
306 lines
15 KiB
YAML
name: CI
|
|
|
|
on:
|
|
pull_request:
|
|
push:
|
|
branches: [main]
|
|
|
|
jobs:
|
|
frozen-install:
|
|
name: Frozen lockfile install
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- name: Install Node.js 24
|
|
uses: actions/setup-node@v4
|
|
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
|
|
|
|
# E00-S02-T08: the static assertions of tests/secrets-not-embedded.test.mjs
|
|
# gate every PR (the docker-gated layer-scan probe inside the same file runs
|
|
# where a Docker daemon is available and skips cleanly otherwise).
|
|
secrets-not-embedded:
|
|
name: Secrets not embedded (E00-S02-T08)
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- name: Install Node.js 24
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: '24'
|
|
- name: Run secrets-not-embedded test suite
|
|
run: node --test tests/secrets-not-embedded.test.mjs
|
|
|
|
# E00-S03-T02: the static assertions of tests/database-postgres-imports.test.mjs
|
|
# gate every PR — the scan proves pg/Kysely imports live only in
|
|
# packages/database-postgres and the mutation probes prove the scan catches
|
|
# a driver import injected into any other package.
|
|
database-postgres-imports:
|
|
name: Database-postgres import isolation (E00-S03-T02)
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- name: Install Node.js 24
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: '24'
|
|
- name: Run database-postgres import isolation suite
|
|
run: node --test tests/database-postgres-imports.test.mjs
|
|
|
|
# E00-S03-T03: the static assertions of tests/database-postgres-ledger.test.mjs
|
|
# gate every PR — the suite locks in the migration ledger (schema_migrations
|
|
# table DDL, idempotent parameterized record, driver-boundary re-export)
|
|
# with mutation probes, and the docker-gated real-stack probe (migrate an
|
|
# empty database and confirm the ledger exists) runs where a Docker daemon
|
|
# is available and skips cleanly otherwise. The job installs the frozen
|
|
# workspace because the real-stack probe executes the committed ledger
|
|
# module from the host (it imports `pg` through the package's own links).
|
|
database-postgres-ledger:
|
|
name: Migration ledger (E00-S03-T03)
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- name: Install Node.js 24
|
|
uses: actions/setup-node@v4
|
|
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 migration ledger test suite
|
|
run: node --test tests/database-postgres-ledger.test.mjs
|
|
|
|
# E00-S03-T04: the static assertions of tests/database-postgres-lock.test.mjs
|
|
# gate every PR — the suite locks in the migration advisory lock (session-
|
|
# scoped pg_advisory_lock/pg_try_advisory_lock over a stable keyed hash on a
|
|
# dedicated connection, re-entrant-safe in-flight acquire so concurrent
|
|
# acquire() calls share one connection, driver-boundary re-export) with
|
|
# mutation probes, and the docker-gated real-stack concurrent probe (a
|
|
# second runner waits or fails while the first holds the lock; concurrent
|
|
# acquire() checks out exactly one connection; the lock releases when the
|
|
# holding session ends) runs where a Docker daemon is available and skips
|
|
# cleanly otherwise. The job installs the frozen workspace because the
|
|
# real-stack probe executes the committed lock module from the host (it
|
|
# imports `pg` through the package's own links).
|
|
database-postgres-lock:
|
|
name: Migration advisory lock (E00-S03-T04)
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- name: Install Node.js 24
|
|
uses: actions/setup-node@v4
|
|
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 migration advisory lock test suite
|
|
run: node --test tests/database-postgres-lock.test.mjs
|
|
|
|
# E00-S03-T05: the static assertions of tests/database-postgres-diagnostic.test.mjs
|
|
# gate every PR — the suite locks in the migration failure diagnostic (a
|
|
# structured MigrationFailedError whose diagnostic identifies the failing
|
|
# migration, the failure phase, the underlying cause, and the applied/pending
|
|
# ledger state, serializable via toJSON) with mutation probes, and a
|
|
# deterministic stub-pool behavioral probe (intentionally failing migration
|
|
# fixture -> structured diagnostic naming the failing migration) runs on
|
|
# Node 24; the docker-gated real-stack probe (the issue's test plan: "run an
|
|
# intentionally failing migration fixture and confirm the diagnostic") runs
|
|
# where a Docker daemon is available and skips cleanly otherwise. The job
|
|
# installs the frozen workspace because the probes execute the committed
|
|
# runner module from the host (it imports `pg` through the package's own
|
|
# links).
|
|
database-postgres-diagnostic:
|
|
name: Migration failure diagnostic (E00-S03-T05)
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- name: Install Node.js 24
|
|
uses: actions/setup-node@v4
|
|
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 migration failure diagnostic test suite
|
|
run: node --test tests/database-postgres-diagnostic.test.mjs
|
|
|
|
# E00-S03-T06: the static assertions of tests/app-readiness.test.mjs gate
|
|
# every PR — the suite locks in the readiness gate (the app answers
|
|
# GET /health with 503 {"status":"not ready"} until the startup migration
|
|
# run completes, then 200 {"status":"ok"}) with mutation probes, the
|
|
# deterministic probes (boot the committed server: no DATABASE_URL ->
|
|
# ready immediately; unreachable DATABASE_URL -> stays not-ready) run on
|
|
# Node 24, and the docker-gated real-stack probe (the issue's test plan:
|
|
# "start with pending migrations and confirm readiness waits" — the app's
|
|
# migration run is blocked behind a held ACCESS EXCLUSIVE lock on the
|
|
# migration ledger, /health stays not-ready, then flips ready once the lock
|
|
# releases) runs where a Docker daemon is available and skips cleanly
|
|
# otherwise. The job installs the frozen workspace and builds the config
|
|
# and database-postgres packages because the probes boot the committed
|
|
# server from the host (it imports @personal-blog/config and
|
|
# @personal-blog/database-postgres through the packages' own links; the
|
|
# required EPPP_SESSION_SECRET is provided by the probe's boot env).
|
|
app-readiness:
|
|
name: App readiness after migrations (E00-S03-T06)
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- name: Install Node.js 24
|
|
uses: actions/setup-node@v4
|
|
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 app readiness test suite
|
|
run: node --test tests/app-readiness.test.mjs
|
|
|
|
# E00-S04-T02: the static assertions of tests/config-startup-error.test.mjs
|
|
# gate every PR — the suite locks in the field-specific startup error (a
|
|
# missing required setting fails startup with an error naming the missing
|
|
# field: packages/config's MissingRequiredSettingError/assertValidConfig,
|
|
# wired into the committed server before it binds) with mutation probes, and
|
|
# the deterministic probes execute the issue's test plan ("start with a
|
|
# missing required field and confirm the error names it"): booting the
|
|
# committed server without EPPP_SESSION_SECRET exits non-zero naming
|
|
# sessionSecret, while a valid secret boots to GET /health 200. The job
|
|
# installs the frozen workspace and builds the config and database-postgres
|
|
# packages because the probes boot the committed server which imports them.
|
|
config-startup-error:
|
|
name: Field-specific startup errors (E00-S04-T02)
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- name: Install Node.js 24
|
|
uses: actions/setup-node@v4
|
|
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 config startup error test suite
|
|
run: node --test tests/config-startup-error.test.mjs
|
|
|
|
# E00-S04-T03: the static assertions of tests/config-log-redaction.test.mjs
|
|
# gate every PR — the suite locks in automatic secret redaction from logs
|
|
# (packages/config's redactConfig/redactText + the server's redacting
|
|
# logger: every log line is scrubbed of the config's secret values) with
|
|
# mutation probes, and the deterministic probes execute the issue's test
|
|
# plan ("log configuration and confirm secret values are redacted"):
|
|
# booting the committed server logs its resolved configuration with the
|
|
# secret values replaced by [REDACTED], and no secret value appears in the
|
|
# log output. The job installs the frozen workspace and builds the config
|
|
# and database-postgres packages because the probes boot the committed
|
|
# server which imports them.
|
|
config-log-redaction:
|
|
name: Secret redaction from logs (E00-S04-T03)
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- name: Install Node.js 24
|
|
uses: actions/setup-node@v4
|
|
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 config log redaction test suite
|
|
run: node --test tests/config-log-redaction.test.mjs
|
|
|
|
# E00-S04-T04: the static assertions of tests/config-env-adapter.test.mjs
|
|
# gate every PR — the suite locks in the environment adapter (packages/config
|
|
# is the single owner of process.env reads; the server and every other module
|
|
# read no process.env, all settings flow through loadConfigFromEnv into the
|
|
# validated config) with a comment-stripped workspace scan, mutation probes
|
|
# (injecting a direct process.env read into any other module fails the scan),
|
|
# a deterministic boundary probe (full env mapping, defaults, bad-PORT
|
|
# fallback, HOST validated as hostname/IP with invalid values throwing a
|
|
# field-specific startup error, missing required secret ->
|
|
# MissingRequiredSettingError) and server-boot probes (a PORT/HOST override
|
|
# shows up in the resolved configuration; HOST=127.0.0.1 binds loopback only
|
|
# and the startup log reflects the actual bind; an invalid HOST fails startup
|
|
# naming the field without echoing the raw value; a missing required secret
|
|
# still fails startup). The job installs the frozen workspace and builds the
|
|
# config and database-postgres packages because the probes boot the committed
|
|
# server which imports them.
|
|
config-env-adapter:
|
|
name: Env adapter owns process.env (E00-S04-T04)
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- name: Install Node.js 24
|
|
uses: actions/setup-node@v4
|
|
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 config env adapter test suite
|
|
run: node --test tests/config-env-adapter.test.mjs
|
|
|
|
# E00-S04-T01: the static assertions of tests/config-schema.test.mjs gate
|
|
# every PR — the suite locks in the TypeBox/Ajv configuration schema
|
|
# (packages/config, golden-tuple pins @sinclair/typebox@0.34.52 +
|
|
# ajv@8.20.0) with mutation probes, and the deterministic probe executes
|
|
# the issue's test plan ("validate a full config against the TypeBox/Ajv
|
|
# schema") against the committed schema through Ajv. The job installs the
|
|
# frozen workspace and builds the config package because the probe also
|
|
# exercises the compiled package boundary (@personal-blog/config) exactly
|
|
# as the later configuration adapter will consume it.
|
|
config-schema:
|
|
name: TypeBox/Ajv config schema (E00-S04-T01)
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- name: Install Node.js 24
|
|
uses: actions/setup-node@v4
|
|
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 package (the probe exercises the compiled package boundary)
|
|
run: pnpm --filter @personal-blog/config build
|
|
- name: Run config schema test suite
|
|
run: node --test tests/config-schema.test.mjs
|
|
|
|
# E00-S03-T01: the static assertions of tests/compose-config.test.mjs (db
|
|
# image pinned to postgres:18.6-bookworm, health gate, volume persistence,
|
|
# build platforms) gate every PR (the docker-gated real-stack probes inside
|
|
# the same file run where a Docker daemon is available and skip cleanly
|
|
# otherwise).
|
|
compose-config:
|
|
name: Compose config (E00-S03-T01)
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- name: Install Node.js 24
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: '24'
|
|
- name: Run compose-config test suite
|
|
run: node --test tests/compose-config.test.mjs
|