The dev branch has been removed (trunk-based workflow: push to main, use
short-lived feature branches + PRs for risky/reviewable changes). These three
workflows still listed 'dev' as a push trigger — a dead reference now that the
branch is gone. Removed so the CI config matches reality.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Every container now has an explicit --memory limit so the OOM killer
has clean boundaries to work with instead of letting any single job
consume all available RAM:
test-fast: 800m (build Eigen+GTest, run 26 tests)
test-cgal: 2000m (LOW_MEMORY_BUILD, was already set)
quality-gates: 600m (apt install + 4 script checks)
doc-build: 800m (Doxygen HTML generation)
markdown-links: 400m (pure Python, very lightweight)
memory-swap = 1.5× memory in each case (150% total) so the OOM
killer fires cleanly without exhausting the SD card.
⚠ This is workflow-side protection only. The runner-side fix
(capacity: 1 in act-runner config) prevents parallel containers
entirely and is the more reliable protection — see CLAUDE.md.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The Pi runner (3-4 GB RAM, swap heavily loaded) OOMs when /ci-all
triggers test-cgal + quality-gates + doc-build + links simultaneously:
four Docker containers start at once after test-fast completes, each
consuming 150-400 MB, exhausting available RAM.
Fix: /ci-all removed from all three workflow files. Each keyword
now triggers exactly one job — no parallel container competition.
Safe workflow: one keyword per commit.
Typical sequence:
git commit -m 'fix: ... /test-cgal' → CGAL tests (~5 min)
git commit -m 'chore: /quality-gates' → style checks (~30 s)
CLAUDE.md: CI table updated with Pi-runner warning note.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
issue_comment triggers had two problems: Gitea did not reliably fire
them, and the refs/pull/N/head checkout was fragile. Commit-message
keywords are simpler and guaranteed to work on any push event.
Trigger keywords (add anywhere in the commit message):
/test-cgal → CGAL test suite (277 tests, LOW_MEMORY_BUILD)
/quality-gates → license/codespell/shellcheck/cgal-conventions
/docs → Doxygen build + warning summary
/links → Markdown internal link check
test-fast still runs on every push (no keyword needed).
All `issue_comment` event handlers and `refs/pull/N/head` checkouts
removed from all three workflow files. review/** added to push branch
filters so this PR branch triggers normally.
CLAUDE.md CI table updated.
/test-cgal /quality-gates
Every CI job except test-fast and mirror-to-codeberg now runs only
when explicitly requested via a PR comment, instead of on every push
or PR sync. This keeps the Pi runner idle during WIP commits and lets
the author decide when to pay each job's cost.
Trigger commands:
/test-cgal → CGAL test suite (277 tests, ~5 min build + 31 s run)
/quality-gates → license/codespell/shellcheck/cgal-conventions (~30 s)
/docs → Doxygen build + warning summary (~2 min)
/links → Markdown internal link check (~10 s)
All comment-triggered jobs check:
event is issue_comment
AND comment is on a PR (issue.pull_request != null)
AND comment body contains the trigger word
AND checkout uses refs/pull/N/head (not the default branch)
Jobs that stay automatic:
test-fast — runs on every push (26 pure-math tests, < 5 s)
mirror-to-codeberg — unchanged
Jobs that keep additional triggers:
markdown-links — weekly cron (Mon 05:00 UTC) + workflow_dispatch
doc-build — workflow_dispatch (for manual runs outside a PR)
quality-gates drops `needs: test-fast` — it now runs independently
when comment-triggered (caller decides whether test-fast passed first).
CLAUDE.md CI pipeline table updated with all five jobs and their new
trigger descriptions.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CI gates (active on every PR via .gitea/workflows/)
───────────────────────────────────────────────────
1. test-count consistency
cpp-tests.yml gains a step after test-cgal that runs
`scripts/check-test-counts.sh` against the just-built ./build dir
(reuse via new BUILD_DIR env var, ~5 s overhead). Drift between
`doc/api/tests.md` and ctest reality now fails the PR.
2. End-to-end smoke
`scripts/try_it.sh` (the documented user quick-start) is now part of
the CGAL job, so README quick-start regressions fail the PR rather
than silently breaking when users land.
3. Internal markdown link checker
New `.gitea/workflows/markdown-links.yml` + `scripts/check-markdown
-links.py`. PRs that touch any *.md file run the check; main pushes
trigger it too; a weekly cron catches external link rot. Pure
Python, no third-party action. Validated against the current tree:
122 internal links across 37 *.md files, 0 broken.
Local quality scripts (`scripts/quality/`, not in CI)
─────────────────────────────────────────────────────
* `license-headers.sh` — `SPDX-License-Identifier: MIT` audit over
code/{include,src,tests}/. Currently
reports 60/66 files missing it — that's
a follow-up; the script captures the
structural gap.
* `sanitizers.sh` — ASan + UBSan over the fast test suite.
* `coverage.sh` — gcov/lcov line + branch coverage of
code/include/, HTML report under
build-coverage/lcov-html/.
* `clang-tidy.sh` — runs the curated `.clang-tidy` policy over
every public header.
* `multi-compiler.sh` — sequential build + test against every
detected g++/clang++ (auto-discovery or
explicit list).
* `cgal-version-matrix.sh`— sequential build + CGAL test suite against
every CGAL tree under `~/cgal/<ver>/` (or
via `CGAL_ROOTS=...` env var).
* `reproducible-build.sh`— two `Release -j1` builds, fail if any test
executable byte-differs.
* `run-all.sh` — driver: `--fast` for the ~5-min subset,
no arg for the ~25–40 min full sweep;
captures per-gate logs to
build-quality-logs/.
+ `.clang-tidy` — curated, deliberately-small policy (only
checks that fire on OUR code, never on
transitive CGAL/Eigen/Boost headers).
+ `scripts/quality/README.md` — explains the structure, lists each
gate's wall-time + prereqs, and codifies
the promotion path: a gate moves into CI
only when it's green on the dev machine
AND has a recovery-instructions paragraph
in `doc/release-policy.md`.
Doc updates
───────────
`doc/architecture/locked-vs-flexible.md` (reviewer-facing) gains 4
"closed" rows in the limitations table — the 3 CI gates above and the
local quality-script suite.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>