PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m11s
PR Checks / Backend Smoke (pull_request) Successful in 9s
PR Checks / Build Backend (no push) (pull_request) Successful in 18s
PR Checks / Build Frontend (no push) (pull_request) Successful in 1m19s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 36s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 6m3s
Staging health polling asked only whether something answered HTTP 200 at the base URL. It could not tell the new deployment from the old one, so journeys could pass against the previous release, and concurrent merges could move the staging tags underneath a run in flight. Each staging run now mints a build ID and stamps all three images with the commit and that ID, as labels and — for frontend and backend — as a build-time JSON file that environment overrides cannot rewrite. /release.json reports both identities uncached, and scripts/ci/release.py polls for the expected pair before and after the journeys. Only then are the captured build digests tagged verified-<sha>. Promotion resolves those verified tags to immutable digests, revalidates their labels, and refuses a mixed or incomplete set before any :prod tag moves. The whole staging workflow shares one concurrency group with cancellation disabled, so releases serialise. The scripts are stdlib-only and unit-tested against mocked registry and HTTP behaviour; PR checks now run the pipeline and CI suites too. The runbook records what this cannot prove locally, and that the first rollout needs a commit built by this workflow. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
95 lines
3.8 KiB
Markdown
95 lines
3.8 KiB
Markdown
# Development and validation
|
|
|
|
## Prerequisites and environment boundaries
|
|
|
|
Use a feature branch. The deployed stack is the integration environment; do not
|
|
assume a local server can run from a fresh checkout. This cleanup did not start
|
|
local servers or provision databases. Unit tests use fixtures and mocks.
|
|
|
|
The current versions are not yet aligned:
|
|
|
|
| Component | Container | PR checks |
|
|
|---|---|---|
|
|
| Backend | Python 3.11 | Python 3.12 |
|
|
| Frontend | Node 24 | Node 22 |
|
|
| Pipeline | Python 3.13 | Pipeline image build |
|
|
|
|
Use the component's container version when reproducing deployment behaviour.
|
|
The backend dependency pins predate Python 3.14; do not assume the system Python
|
|
can install or run them. Version alignment is a separate maintenance task.
|
|
|
|
## Frontend checks
|
|
|
|
```sh
|
|
cd nextjs-app
|
|
npm ci
|
|
npm run typecheck
|
|
npm test -- --runInBand
|
|
```
|
|
|
|
`npm run build` is the production build check. There is no `lint` script.
|
|
Tests live in `__tests__/` and use Jest/React Testing Library. These checks do not
|
|
prove that live PostgreSQL queries, Typesense or a deployed proxy work.
|
|
|
|
The frontend `.env.example` documents runtime variables. Browser traffic normally
|
|
uses `/api`; `FASTAPI_URL` is an absolute server-side URL ending in `/api`.
|
|
Payload additionally needs `DATABASE_URL` and `PAYLOAD_SECRET` when used at runtime.
|
|
Never commit credentials or real `.env` files.
|
|
|
|
## Backend checks
|
|
|
|
From the repository root, using an available Python 3.11 or 3.12 interpreter:
|
|
|
|
```sh
|
|
python3.11 -m venv /tmp/schoolcompare-backend-venv
|
|
/tmp/schoolcompare-backend-venv/bin/python -m pip install -r requirements.txt pytest 'httpx<0.28' pyyaml
|
|
/tmp/schoolcompare-backend-venv/bin/python -m pytest backend/tests pipeline/tests scripts/ci/tests -q
|
|
```
|
|
|
|
Substitute `python3.12` if matching PR CI. The test dependencies above match the
|
|
current workflow; they are not yet captured in a dedicated development lockfile.
|
|
Backend configuration is defined in `backend/config.py`; `.env.example` documents
|
|
commonly used values. `ALLOWED_ORIGINS` uses a JSON array, not a comma-separated string.
|
|
|
|
## Data and pipeline work
|
|
|
|
The app needs populated `marts.*` tables. A new Postgres instance alone is not a
|
|
working school-data environment. Use the existing managed pipeline or an approved
|
|
snapshot; the removed CSV importer cannot build the current schema.
|
|
|
|
The pipeline container includes Meltano, dbt/Postgres, Airflow and the custom taps.
|
|
Airflow commands/selectors live in `pipeline/dags/`. Schema tests live in
|
|
`pipeline/transform/tests/` and model YAML files. Run the relevant `dbt build`
|
|
selector in an isolated data environment for model changes; it writes tables and
|
|
is not a read-only smoke test. Prefer `python -m dbt.cli.main` as the DAGs do.
|
|
|
|
GIAS dictionaries are generated together by
|
|
`pipeline/scripts/generate_gias_codes.py`. The backend and pipeline copies are
|
|
intentional; `backend/tests/test_gias_codes.py` checks that they stay identical.
|
|
|
|
For Payload collection/editor changes, run `npm run generate:importmap` in
|
|
`nextjs-app/` and include the generated map. Preserve CMS migrations and the
|
|
separate `payload` schema. See [publishing](../nextjs-app/docs/PUBLISHING.md).
|
|
|
|
## End-to-end checks
|
|
|
|
Against an existing, authorised test environment:
|
|
|
|
```sh
|
|
cd e2e
|
|
npm ci
|
|
npx playwright install chromium
|
|
BASE_URL=https://your-test-environment.example npx playwright test
|
|
```
|
|
|
|
The suite does not start a web server. CI installs Chromium with system dependencies
|
|
and runs against staging. Use the configured staging target: `docs/DEPLOY.md`
|
|
records the public staging proxy limitation. User-visible behaviour changes should
|
|
update the corresponding journeys.
|
|
|
|
## Before requesting review
|
|
|
|
Run checks relevant to the change, inspect `git diff --check`, and report checks
|
|
that could not run. Do not publish or promote as part of local validation.
|
|
[DEPLOY.md](DEPLOY.md) documents the PR and human promotion gates.
|