From fb4677bcd63fa3c82c083817712caeccc6d42bb5 Mon Sep 17 00:00:00 2001 From: Roland Date: Thu, 30 Jul 2026 17:05:53 -0600 Subject: [PATCH] ci: a named check for fixture drift, and run jest on pull requests again Two gaps, one of them wide. The contract tests added in c349e15c already ran inside `pytest -nauto`, but fixture drift is silent by nature -- the frontend suite passes against a body the API stopped sending -- so it deserves a check whose name says what broke. `api-contract-tests` restores the same dependency cache as the other Python jobs, skips the ffmpeg/catdoc install it does not need (verified), and runs the one file, so it answers in under a minute instead of somewhere inside seventeen hundred results. The wide one: jest-tests.yml triggered on `pull_request: branches: [master]`, so a pull request into anything else ran neither jest nor the webpack build. The entire Semantic UI to Mantine migration went in that way -- seventy-five files across nine pull requests into feature/custom-theme, not one of which ran either. The build step is the one that matters most: jest and tsc both pass on a named import that does not exist and only webpack rejects it, which is exactly how a broken Archive.js survived a "clean" run earlier in this migration. The suite did run on the branch after each merge, which is the wrong side of the merge to learn about it. `pull_request` is now unfiltered rather than listing branches, so the next long-lived branch does not have to remember to add itself. It stays `pull_request`, not `pull_request_target`: a fork's run gets a read-only token and no secrets, and this workflow interpolates no event data, so widening the trigger adds no injection or exfiltration path. Worth knowing separately: none of this gates anything. master has no branch protection and the only ruleset covers `release` (deletion, non-fast-forward), so every check here is advisory. That is a repository setting, and Roland's to make. Co-Authored-By: Claude Opus 5 (1M context) --- .circleci/config.yml | 28 ++++++++++++++++++++++++++++ .github/workflows/jest-tests.yml | 8 +++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 174acc91..f3be267d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -33,6 +33,33 @@ jobs: command: './venv/bin/pytest -nauto --junitxml=test-results.xml' - store_test_results: path: test-results.xml + # Do the API and the frontend's test fixtures still agree? + # + # `api-tests` runs these too, as part of the whole suite. This job exists for the + # signal: fixture drift is silent by nature -- the frontend suite passes against a body the + # API stopped sending -- so it is worth a check whose name says what broke, failing in under a + # minute rather than somewhere inside seventeen hundred results. + # + # It needs no ffmpeg or catdoc (verified), and shares the dependency cache key with the other + # Python jobs, so it costs a venv restore and one test file. + api-contract-tests: + docker: + - image: cimg/python:3.11 + resource_class: medium + steps: + - checkout + - restore_cache: + key: deps-3.11-{{ checksum "requirements.txt" }}-5 + - run: + name: Install Requirements + command: | + python3 -m venv venv + . venv/bin/activate + pip install -r requirements.txt + - run: + name: Fixtures match the OpenAPI spec, and the spec matches the handlers + command: './venv/bin/pytest wrolpi/test/test_api_fixtures.py -v' + api-alembic-migrations: docker: - image: cimg/python:3.13 @@ -167,6 +194,7 @@ workflows: jobs: - sanic-api-start - api-tests + - api-contract-tests - api-alembic-migrations wrolpi-app-test: jobs: diff --git a/.github/workflows/jest-tests.yml b/.github/workflows/jest-tests.yml index 68bfd7aa..8a8eadba 100644 --- a/.github/workflows/jest-tests.yml +++ b/.github/workflows/jest-tests.yml @@ -1,10 +1,16 @@ name: Jest Tests +# `pull_request` is deliberately unfiltered. It was `branches: [master]`, which meant a pull +# request into anything else ran no jest and no webpack build -- so the entire Semantic UI to +# Mantine migration, seventy-five files of it, was reviewed and merged across nine pull requests +# into `feature/custom-theme` without either ever running on a single one of them. The build +# step matters most of all here: jest and tsc both pass on a named import that does not exist, +# and only webpack rejects it. The suite did run on the branch afterwards, which is the wrong +# side of the merge to find out. on: push: branches: [master, feature/*] pull_request: - branches: [master] jobs: jest-tests: