Replace the per-branch PR-checks trigger ([master, feat/crewing-foundations]) with [master, "feat/crewing-*"] so every branch in the stacked crewing series (foundations → requisitions → candidates → …) runs the same hard gates without adding each one by hand. The workflow is evaluated from the branch under test, so the glob is propagated down the stack.
108 lines
4.6 KiB
YAML
108 lines
4.6 KiB
YAML
name: PR checks
|
|
|
|
# Enforces the contribution policy on every PR into master — plus the crewing
|
|
# stack branches (feat/crewing-*), which collect the stacked, feature-flagged
|
|
# crewing phases (foundations → requisitions → candidates → …) before they merge
|
|
# to master. Same hard gates:
|
|
# - code changes must ship with tests (docs/config/automation are exempt)
|
|
# - type-check is clean across the whole project (tests included)
|
|
# - unit tests pass
|
|
# - integration tests pass against an ephemeral Postgres (migrate + seed)
|
|
# Runs on the pms1 host runner. See automation/README.md > "Contribution policy".
|
|
#
|
|
# Note: the workflow is evaluated from the branch under test, so the trigger list
|
|
# must match it. The feat/crewing-* glob covers every branch in the stack so each
|
|
# stacked phase PR is checked without further edits to this file.
|
|
|
|
on:
|
|
pull_request:
|
|
branches: [master, "feat/crewing-*"]
|
|
|
|
jobs:
|
|
checks:
|
|
runs-on: host
|
|
steps:
|
|
- name: Checkout PR
|
|
uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Policy — code changes must include tests
|
|
run: |
|
|
set -uo pipefail
|
|
base="${GITHUB_BASE_REF:-master}"
|
|
git fetch origin "$base" --depth=200 -q
|
|
changed=$(git diff --name-only "origin/$base...HEAD")
|
|
printf 'Changed files:\n%s\n\n' "$changed"
|
|
|
|
# "Code" = app source (pages, API routes, lib, components, hooks).
|
|
# Tests, prisma, config, docs, automation and .forgejo are exempt.
|
|
code=$(printf '%s\n' "$changed" | grep -E '^App/(app|lib|components|hooks)/' \
|
|
| grep -vE '(\.test\.|\.spec\.|/tests/)' || true)
|
|
tests=$(printf '%s\n' "$changed" | grep -E '(\.test\.|\.spec\.|/tests/)' || true)
|
|
|
|
if [ -n "$code" ] && [ -z "$tests" ]; then
|
|
echo "::error::Code changed but no test files changed."
|
|
echo "Every code PR must add or update tests (model: the claude/issue-12 integration test)."
|
|
echo "If a test is genuinely not applicable, say why in the PR description so a reviewer can override."
|
|
printf '\nCode files without accompanying tests:\n%s\n' "$code"
|
|
exit 1
|
|
fi
|
|
echo "OK — test-presence policy satisfied."
|
|
|
|
- name: Type-check (no errors)
|
|
run: |
|
|
set -e
|
|
export NVM_DIR="$HOME/.nvm"; . "$NVM_DIR/nvm.sh"
|
|
cd App
|
|
pnpm install --frozen-lockfile
|
|
pnpm db:generate # prisma client types (no DB connection needed)
|
|
pnpm type-check # whole project, tests included — must be clean
|
|
|
|
- name: Unit tests
|
|
run: |
|
|
set -e
|
|
export NVM_DIR="$HOME/.nvm"; . "$NVM_DIR/nvm.sh"
|
|
cd App && pnpm test # jsdom unit tests, no DB — must pass
|
|
|
|
integration:
|
|
runs-on: host
|
|
steps:
|
|
- name: Checkout PR
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Integration tests (ephemeral Postgres)
|
|
run: |
|
|
set -euo pipefail
|
|
export NVM_DIR="$HOME/.nvm"; . "$NVM_DIR/nvm.sh"
|
|
|
|
# Throwaway Postgres per run — isolated from prod / pelagia_test / staging.
|
|
# A random host port avoids collisions with the host DB and concurrent runs.
|
|
PG="ci-pg-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT:-1}"
|
|
cleanup() { docker rm -f "$PG" >/dev/null 2>&1 || true; }
|
|
trap cleanup EXIT
|
|
docker rm -f "$PG" >/dev/null 2>&1 || true
|
|
docker run -d --name "$PG" \
|
|
-e POSTGRES_USER=ci -e POSTGRES_PASSWORD=ci -e POSTGRES_DB=pelagia_ci \
|
|
-p 127.0.0.1::5432 postgres:16 >/dev/null
|
|
|
|
for i in $(seq 1 30); do
|
|
docker exec "$PG" pg_isready -U ci -d pelagia_ci >/dev/null 2>&1 && break
|
|
sleep 1
|
|
done
|
|
|
|
PORT=$(docker inspect --format '{{ (index (index .NetworkSettings.Ports "5432/tcp") 0).HostPort }}' "$PG")
|
|
export DATABASE_URL="postgresql://ci:ci@127.0.0.1:${PORT}/pelagia_ci"
|
|
# Non-secret placeholders so auth.ts (reads these at module load) boots in dev mode.
|
|
export NEXTAUTH_SECRET="ci-secret"
|
|
export NEXTAUTH_URL="http://localhost:3000"
|
|
export AZURE_AD_CLIENT_ID="placeholder"
|
|
export AZURE_AD_CLIENT_SECRET="placeholder"
|
|
export AZURE_AD_TENANT_ID="placeholder"
|
|
|
|
cd App
|
|
pnpm install --frozen-lockfile
|
|
pnpm db:generate
|
|
pnpm db:migrate:deploy # apply migrations to the fresh DB
|
|
pnpm db:seed # dev seed — integration tests rely on it
|
|
pnpm test:integration # node + real DB — must pass
|