d1c582396a
Apply shared session, permission, ownership and lifecycle checks across gallery access, media grants and session restoration. Validate mutation origins, pin webhook DNS resolution and redact token-bearing request URLs. Consolidate gallery creation and queries, extract frontend state hooks, fix hook ordering and resource cleanup, and repair the fresh event schema. Update affected dependencies and restore excluded CI suites with regression and cross-database coverage.
145 lines
5.0 KiB
YAML
145 lines
5.0 KiB
YAML
name: Tests
|
|
|
|
# Runs the backend Jest suite and the frontend Vitest suite on every PR.
|
|
# Both suites already exist and cover the CRM service layer (quoteService,
|
|
# contractService, invoiceService.*, customerHoursService, eventService.
|
|
# calendar) plus the photo / settings / OG / auth surface — wiring them
|
|
# into CI makes regressions visible at PR time instead of post-merge.
|
|
#
|
|
# Triggers on any change that could affect either suite. The backend
|
|
# job intentionally omits frontend paths and vice versa so unrelated
|
|
# PRs don't pay both build costs.
|
|
|
|
on:
|
|
push:
|
|
branches: [main, beta, stable]
|
|
pull_request:
|
|
branches: [main, beta, stable]
|
|
workflow_dispatch:
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
backend:
|
|
runs-on: ubuntu-latest
|
|
# 20, not 10. This job normally finishes in ~3 minutes, but it is the only
|
|
# one that boots Postgres and runs the full integration suite, so it is the
|
|
# only one exposed to runner contention — observed spread has reached 9.2
|
|
# minutes, and a release PR (#1088) was cancelled at 10.3 with every test
|
|
# passing and jest still running. A cancelled job reads as a red X on a
|
|
# green branch, which costs a re-run and a diagnosis every time it happens.
|
|
#
|
|
# The cap is a runaway guard, not a performance budget; 20 leaves real
|
|
# headroom over the worst observed run while still killing a hung suite
|
|
# well inside the hour GitHub would otherwise allow. frontend and ml keep
|
|
# 10 — they take seconds and have never come close.
|
|
timeout-minutes: 20
|
|
|
|
# The .picpeak restore suites gate their real-Postgres cases behind
|
|
# PICPEAK_PG_TEST_URL and `describe.skip` themselves out when it is
|
|
# unset — so until now they never ran here. That hid the half that
|
|
# matters: sequence resync, operator/role preservation across a
|
|
# cross-instance restore, and (with #1041) whether a SQLite-shaped
|
|
# row actually lands in Postgres with the right STORED VALUES rather
|
|
# than merely not throwing. Everything else in the suite still runs
|
|
# on SQLite; this service only un-gates those cases.
|
|
services:
|
|
postgres:
|
|
image: postgres:15-alpine
|
|
env:
|
|
POSTGRES_USER: picpeak
|
|
POSTGRES_PASSWORD: testpass
|
|
POSTGRES_DB: picpeak_test
|
|
options: >-
|
|
--health-cmd "pg_isready -U picpeak -d picpeak_test"
|
|
--health-interval 2s
|
|
--health-timeout 2s
|
|
--health-retries 30
|
|
ports:
|
|
- 5432:5432
|
|
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set up Node.js
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: '22'
|
|
cache: 'npm'
|
|
cache-dependency-path: backend/package-lock.json
|
|
|
|
- name: Install backend deps
|
|
working-directory: ./backend
|
|
run: npm ci
|
|
|
|
- name: Run Jest suite
|
|
working-directory: ./backend
|
|
env:
|
|
# backupService tests would otherwise try a real S3 round-trip.
|
|
# The S3 path itself is covered separately by the integration
|
|
# suite when MinIO is provisioned.
|
|
SKIP_S3_TESTS: 'true'
|
|
# Un-gates the real-Postgres cases in the .picpeak restore suites
|
|
# (see the `services:` note above). Absent it they silently skip.
|
|
PICPEAK_PG_TEST_URL: 'postgres://picpeak:testpass@127.0.0.1:5432/picpeak_test'
|
|
run: npx jest --ci
|
|
|
|
frontend:
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 10
|
|
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set up Node.js
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: '22'
|
|
cache: 'npm'
|
|
cache-dependency-path: frontend/package-lock.json
|
|
|
|
- name: Install frontend deps
|
|
working-directory: ./frontend
|
|
run: npm ci
|
|
|
|
- name: Lint frontend (including Rules of Hooks)
|
|
working-directory: ./frontend
|
|
run: npm run lint
|
|
|
|
- name: Run Vitest suite
|
|
working-directory: ./frontend
|
|
run: npm test -- --run
|
|
|
|
# Optional face-detection sidecar (#1074). Runs on every PR regardless of
|
|
# whether the feature is enabled anywhere — these tests need no model
|
|
# weights (they stub the pipeline out) and cover the auth boundary, the
|
|
# request guards and the alignment geometry, which is where a mistake is a
|
|
# security problem or a silent accuracy problem rather than a visible bug.
|
|
ml:
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 10
|
|
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set up Python
|
|
uses: actions/setup-python@v5
|
|
with:
|
|
# Matches ml/Dockerfile's base image, so a wheel that resolves here
|
|
# resolves in the image too.
|
|
python-version: '3.12'
|
|
cache: 'pip'
|
|
cache-dependency-path: ml/requirements.txt
|
|
|
|
- name: Install ml deps
|
|
working-directory: ./ml
|
|
run: pip install -r requirements.txt pytest httpx
|
|
|
|
- name: Run pytest suite
|
|
working-directory: ./ml
|
|
run: python -m pytest tests/ -q
|