Skip to content

chore(deps): bump pdfkit from 0.19.1 to 0.20.1 (#125) #315

chore(deps): bump pdfkit from 0.19.1 to 0.20.1 (#125)

chore(deps): bump pdfkit from 0.19.1 to 0.20.1 (#125) #315

Workflow file for this run

name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
# Superseded runs are cancelled. Pushing three times to a PR used to run three
# full suites to completion; only the newest tells you anything.
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
# Tags are the baseline for the migration-immutability check below.
fetch-depth: 0
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- run: bun install --frozen-lockfile
- run: bun run test
working-directory: packages/grc-data-model
# Root unit tests under lib/ and server/. These existed and passed but
# nothing ran them: the step above is scoped to a single package, so a
# test file added at the root was never executed by CI. Kept to the two
# directories with no database dependency; e2e/ runs in its own workflow.
- run: bun run test:unit
# A .sql file that is not in its journal never runs. drizzle/ carried
# one for months: 0016_aberrant_devos, a duplicate of DDL that had moved
# into the isms-schema chain. Harmless there, but the next one might be
# a migration somebody believes is live.
- name: migration journals match their .sql files
run: bun run check:migrations
# A migration that has already run somewhere will never run again there.
# Editing it afterwards therefore changes only the databases that have
# not seen it yet, leaving two schemas that both claim the same version.
# Nothing at runtime notices, so it is caught here instead.
- name: shipped migrations are unchanged
run: bun run check:migration-immutability
# Rule 3 in one command. A constraint added in one step passes CI here by
# construction, because this schema is built from scratch and has no rows
# to violate it, then fails on a self-hoster's database. Also catches
# `-- migrate:no-transaction` on a migration that has no CONCURRENTLY in
# it, which is the only thing that marker is for.
- name: migrations are safe against existing data
run: bun run check:migration-safety
# Shell is where this repo does its riskiest work — the release gates,
# the failure drill, the self-host install path — and it is the one
# language here with no compiler. A `[ x ] && y || z` in a script whose
# job is reporting pass/fail is the kind of thing that reads correct and
# is not.
- name: shell scripts pass shellcheck
run: |
docker run --rm -v "$PWD:/mnt" -w /mnt koalaman/shellcheck:v0.10.0 \
install.sh scripts/ci/*.sh scripts/*.sh e2e/*.sh
# db/framework-seed.sql is what a self-hoster runs to fill a fresh
# database, and what drizzle/seed.ts applies for the satisfaction pairs.
# Generated from the same emitters as the sync migrations, so a framework
# change that skips regenerating it would hand new installs stale
# reference data while every existing instance got the correction.
- name: db/framework-seed.sql is up to date with the framework data
run: |
bun run check:framework-seed \
|| { echo "::error::db/framework-seed.sql is stale. Run 'bun run db:seed:file' and commit."; exit 1; }
# REFERENCE.md is generated from the framework data and is published as
# the public reference. It silently went stale after a correction pass,
# leaving it citing CIR Annex points that do not exist in the OJ text.
- name: REFERENCE.md is up to date with the framework data
run: |
bun run docs:reference
git diff --exit-code -- REFERENCE.md \
|| { echo "::error::REFERENCE.md is stale. Run 'bun run docs:reference' in packages/grc-data-model and commit."; exit 1; }
working-directory: packages/grc-data-model
- run: bun run typecheck
- run: bun run build
env:
# lib/env.ts:68 short-circuits on this; the rest are here so the
# block still describes reality if that escape hatch ever goes away.
# lib/env.ts validates DATABASE_URL and AUTH_SECRET (min 32 chars),
# and nothing named NEXTAUTH_*.
SKIP_ENV_VALIDATION: "1"
DATABASE_URL: "postgres://dummy:dummy@localhost:5432/dummy"
AUTH_SECRET: "ci_build_dummy_value_not_a_real_secret_0000"
RESEND_API_KEY: "re_dummy_for_ci_build"
# What happens to a customer's database when a migration fails. Every other
# migration test asks whether the good path works; this one deliberately
# breaks it, because "your data is untouched" is a promise docs/updating.md
# makes to people storing audit evidence, and it was untested until now.
migration-failure:
runs-on: ubuntu-latest
timeout-minutes: 10
services:
postgres:
image: postgres:17-alpine
env:
POSTGRES_USER: drill
POSTGRES_PASSWORD: drill
POSTGRES_DB: drill
options: >-
--health-cmd "pg_isready -U drill"
--health-interval 5s
--health-timeout 5s
--health-retries 10
ports:
- 5432:5432
steps:
- uses: actions/checkout@v7
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- run: bun install --frozen-lockfile
- name: a failing migration leaves the database untouched
run: bash scripts/ci/migration-failure-drill.sh
env:
DATABASE_URL: postgres://drill:drill@localhost:5432/drill
# The published self-host stack has to stay parseable and internally
# consistent. `docker compose config` resolves every variable reference and
# profile, so a typo in a service name or an unbalanced ${...} fails here
# rather than on somebody's server.
compose:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v7
- name: self-host compose file is valid
run: |
cp .env.self-host.example .env
# Placeholders for the values the file deliberately refuses to
# default, so validation exercises the required-variable syntax.
{
echo "POSTGRES_PASSWORD=ci"
echo "AUTH_SECRET=ci"
echo "AWS_SECRET_ACCESS_KEY=ci-secret"
echo "MINIO_KMS_KEY=$(openssl rand -base64 32)"
echo "UPDATE_API_TOKEN=ci"
} >> .env
for profiles in "" "minio" "proxy" "updater" "backup" "minio,proxy,updater,backup"; do
echo "--- profiles: ${profiles:-none}"
COMPOSE_PROFILES="$profiles" docker compose -f compose.self-host.yml config --quiet
done
# The proxy config ships to self-hosters too. Caddy can check it without
# starting, so a typo fails here instead of taking down the one service
# that terminates TLS.
- name: proxy config is valid
run: |
docker run --rm \
-v "$PWD/Caddyfile.self-host.example":/etc/caddy/Caddyfile:ro \
-e APP_DOMAIN=isms.example.com \
-e STORAGE_DOMAIN=storage.example.com \
caddy:2-alpine caddy validate --config /etc/caddy/Caddyfile