0.6.0 fixes, bunch 1: CI and workflows #1223

Merged
tiagoagueda merged 7 commits from b1-ci into main 2026-11-10 11:06:40 +00:00
Owner

Bunch 1 of the 0.6.0 fixes: CI and workflows. One signed commit per issue; merge fast-forward-only so each keeps its own.

  • Closes #1166: the Security job audits the lock files without installing the project (pip-audit 3 s rather than 60 locally, same answer).
  • Closes #1159: the monthly dependency run's propose job is guarded per step, so a month with nothing to upgrade ends green.
  • Closes #1160: the unit suite keeps Django's async-safety guard; the browser suite switches it off only when a browser test is selected.
  • Closes #1135: UV_NO_SYNC in the jobs that leave the browser group out; the unit jobs take Playwright through the chromium extra.
  • Closes #1136: weekly.yml holds the weekly audit and ESCO check; ci.yml has no schedule.
  • Closes #1137 and closes #1189: Every Python starts on a push to main that changes the version or the lock file; the gate and CONTRIBUTING stop asking for a hand-started run.
  • Closes #1138: a time limit on every set-up step that reaches the network, and retries on the uv installer download.

Tested locally: lint, migration and catalogue checks, the full unit suite (21,207 passed), zizmor over the workflows, and two browser test files. The workflow changes are proven by this pull request's own CI run, then by the next weekly, monthly and release runs.

🤖 Generated with Claude Code

Bunch 1 of the 0.6.0 fixes: CI and workflows. One signed commit per issue; merge fast-forward-only so each keeps its own. - Closes #1166: the Security job audits the lock files without installing the project (pip-audit 3 s rather than 60 locally, same answer). - Closes #1159: the monthly dependency run's `propose` job is guarded per step, so a month with nothing to upgrade ends green. - Closes #1160: the unit suite keeps Django's async-safety guard; the browser suite switches it off only when a browser test is selected. - Closes #1135: `UV_NO_SYNC` in the jobs that leave the browser group out; the unit jobs take Playwright through the `chromium` extra. - Closes #1136: `weekly.yml` holds the weekly audit and ESCO check; `ci.yml` has no schedule. - Closes #1137 and closes #1189: Every Python starts on a push to `main` that changes the version or the lock file; the gate and CONTRIBUTING stop asking for a hand-started run. - Closes #1138: a time limit on every set-up step that reaches the network, and retries on the uv installer download. Tested locally: lint, migration and catalogue checks, the full unit suite (21,207 passed), zizmor over the workflows, and two browser test files. The workflow changes are proven by this pull request's own CI run, then by the next weekly, monthly and release runs. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
The Security job ran pip-audit through `uv run --with`, which first built the
project's whole environment (a managed Python, every locked package, Postulo
itself) for a tool that reads only the exported requirements file, and ran
`npm ci` so that `npm audit` could read a lock it reads by itself.

pip-audit now runs through `uvx`, with `--disable-pip --no-deps`: the export
already pins every package, so there is nothing to resolve. Measured locally,
3 s rather than 60, with the same answer. `npm audit --package-lock-only`
replaces the install. Both steps get a time limit.

Closes #1166

Co-Authored-By: Claude <noreply@anthropic.com>
This runner fails a job whose `if` is false instead of skipping it. The
monthly dependency run's `propose` job had a job-level `if`, so a month in
which the lock did not move would have ended red, with nothing wrong.

The condition moves to each step, as the `upgrade` job's steps already have
it, and a first step says in the run's summary when nothing moved. A test
holds every workflow to the rule, with the one exception that can never be
false named.

Closes #1159

Co-Authored-By: Claude <noreply@anthropic.com>
The browser suite's conftest switched DJANGO_ALLOW_ASYNC_UNSAFE on as it was
imported. A unit run imports that file too, since it collects tests/e2e and
deselects by marker afterwards, so every unit worker ran with the guard that
catches a synchronous database call from async code switched off.

The variable is now set in `pytest_collection_finish`, and only when the run
selected a browser test. Not in an autouse fixture, which was tried: a
conftest's autouse fixtures are set up alphabetically, and the ones that start
the browser and the database came first.

Closes #1160

Co-Authored-By: Claude <noreply@anthropic.com>
Several jobs sync with `--no-group e2e` and then call plain `uv run`, which
brings the environment back to the default groups first, and the browser group
is one of them. So each of those jobs downloaded Playwright (45 MB) on its
first `uv run`, under a comment saying it never did.

Those jobs now set UV_NO_SYNC, so `uv run` uses what the sync step built. The
jobs that run the unit suite install Playwright the library through the
`chromium` extra, because tests/test_documents.py imports it; the pytest
plugin and the browser stay out. Collection without the plugin was checked
locally: 21,382 tests collected.

Closes #1135

Co-Authored-By: Claude <noreply@anthropic.com>
The Monday schedule sat on ci.yml and started all five jobs, browser suite
included, about 50 runner-minutes, for the two things a week without a push
would miss: a vulnerability disclosed in a dependency, and a change in what
the ESCO service answers.

A `weekly.yml` now holds those two: a copy of the Security job, which a test
keeps equal to ci.yml's, and a job that downloads ESCO with no cache. ci.yml
loses its schedule, and the unit jobs no longer skip their ESCO cache on a
schedule. Every Python's own weekly run stays, as the maintainer decided.

Closes #1136

Co-Authored-By: Claude <noreply@anthropic.com>
The release gate asks for a passed unit leg on every supported Python, and it
reads commit statuses. The recipe said to start *Every Python* by hand on the
merged commit, but Forgejo records no commit status for a run started by hand,
so the gate could never see it: releasing 0.5.0 needed a release branch pushed
at the last minute to get statuses at all (#1189).

Every Python now starts on a push to `main` that changes the version file,
which a release's pull request always does, or the lock file, as the
maintainer decided. The release-branch trigger goes: one `push:` holds one
branches/paths pair, and every release goes through `main` since #940.

The gate's message, the workflow's header and CONTRIBUTING no longer tell
anyone to start it by hand, and say why that cannot work.

Closes #1137
Closes #1189

Co-Authored-By: Claude <noreply@anthropic.com>
Give every set-up step a time limit, and curl its retries
All checks were successful
CI / Unit tests and coverage (Python 3.14) (pull_request) Successful in 15m10s
CI / Checks: lint, migrations, catalogues, settings, built files (pull_request) Successful in 1m41s
CI / Database tests on PostgreSQL (pull_request) Successful in 4m15s
CI / Security audit (pull_request) Successful in 27s
CI / Browser tests (Chromium) (pull_request) Successful in 33m42s
CI / Unit tests and coverage (Python 3.14) (push) Successful in 15m39s
CI / Checks: lint, migrations, catalogues, settings, built files (push) Successful in 1m46s
CI / Database tests on PostgreSQL (push) Successful in 4m5s
CI / Security audit (push) Successful in 23s
CI / Browser tests (Chromium) (push) Successful in 34m58s
Dev image / Dev image: build, scan, push (push) Successful in 54m45s
ec705c9104
This runner ignores a job's `timeout-minutes` and honours a step's, and only
the steps that run tests had one. A mirror that stalled without failing, in
apt, the uv installer, `uv sync`, `npm ci`, the browser download, the ESCO
download or a cache restore, held one of the runner's two slots until the
runner's own limit, hours later.

Each of those steps now has a literal limit, 5 or 10 minutes, in every
workflow. The uv installer download retries three times and gives up after
two minutes; its checksum check is unchanged. uv and apt already retry by
themselves. Tests hold every workflow to both rules.

Closes #1138

Co-Authored-By: Claude <noreply@anthropic.com>
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Postulo/postulo!1223
No description provided.