Files
ConformalLabpp/.gitea/workflows/cpp-tests.yml
Tarik Moussa 018484a94d ci: switch all non-fast jobs to comment triggers
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>
2026-05-31 01:17:27 +02:00

199 lines
9.0 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

name: C++ Tests
on:
push:
branches:
- main
- dev
- "claude/**"
- "feature/**"
pull_request:
# /test-cgal comment on any PR triggers the CGAL test suite manually.
issue_comment:
types: [created]
# ─────────────────────────────────────────────────────────────────────────────
# Job 1 — test-fast
# Pure-math tests (Clausen, ImLi₂, Hyper-ideal geometry).
# No CGAL, no Boost. Eigen + GTest only. Runs on ALL branches.
# ─────────────────────────────────────────────────────────────────────────────
jobs:
test-fast:
runs-on: eulernest
container:
image: git.eulernest.eu/conformallab/ci-cpp:latest
steps:
- uses: actions/checkout@v4
- name: Configure (tests-only)
run: cmake -S code -B build -DCMAKE_BUILD_TYPE=Release
- name: Build
run: nice -n 19 cmake --build build --target conformallab_tests -j$(nproc)
- name: Run tests
run: >
ctest --test-dir build
--output-on-failure
--output-junit test-results.xml
- name: Summary
if: always()
run: |
if [ -f test-results.xml ]; then
total=$(grep -o 'tests="[0-9]*"' test-results.xml | grep -o '[0-9]*' | head -1)
failed=$(grep -o 'failures="[0-9]*"' test-results.xml | grep -o '[0-9]*' | head -1)
skipped=$(grep -o 'skipped="[0-9]*"' test-results.xml | grep -o '[0-9]*' | head -1)
passed=$(( ${total:-0} - ${failed:-0} - ${skipped:-0} ))
echo "FAST ▸ TOTAL ${total:-0} | PASSED $passed | FAILED ${failed:-0} | SKIPPED ${skipped:-0}"
fi
# ─────────────────────────────────────────────────────────────────────────────
# Job 2 — test-cgal
# Full CGAL test suite (Phase 37, 158 tests).
# Runs ONLY on pull requests (not on direct pushes to dev/main).
# Starts only after test-fast succeeds.
#
# Uses -DWITH_CGAL_TESTS=ON (not -DWITH_CGAL=ON) to avoid building
# Viewer/GLFW — the CI container has no wayland-scanner.
#
# Boost (libboost-dev) is already present in the container since the image rebuild.
# ─────────────────────────────────────────────────────────────────────────────
# ─── CGAL tests: manual trigger via PR comment ───────────────────────────
#
# Trigger: write "/test-cgal" as a comment on any pull request.
#
# Why comment-triggered (not automatic on every PR push):
# The Pi runner has 3-4 GB RAM total with swap constantly loaded.
# Even with LOW_MEMORY_BUILD the CGAL build takes ~5 min and stresses
# the runner. Triggering on every push would queue builds faster than
# the Pi can drain them. A manual trigger gives full control: run the
# 277-test suite when a PR is ready for review, not on every WIP commit.
#
# How it works:
# - `issue_comment` fires on all PR + issue comments.
# - The `if:` condition checks:
# 1. Event is a comment (not a push or PR sync)
# 2. The comment is on a PR (issue.pull_request != null)
# 3. The comment body contains "/test-cgal"
# - The checkout uses refs/pull/N/head to get the PR branch, because
# `issue_comment` does not set GITHUB_REF to the PR branch by default.
#
# LOW_MEMORY_BUILD applies four RAM-saving measures so the build fits in
# 2000 MB: -O0, PCH off, unity batch 1, --no-keep-memory linker.
# See code/tests/cgal/CMakeLists.txt for the full explanation.
test-cgal:
needs: test-fast
if: |
github.event_name == 'issue_comment' &&
github.event.issue.pull_request != null &&
contains(github.event.comment.body, '/test-cgal')
runs-on: eulernest
container:
image: git.eulernest.eu/conformallab/ci-cpp:latest
# 2000 MB hard limit; 1000 MB swap headroom (memory-swap = RAM + swap).
# Uses ~half of the Pi's 3-4 GB, leaving margin for OS + runner daemon.
# With LOW_MEMORY_BUILD peak per TU is ~150-200 MB → well within limit.
options: "--memory=2000m --memory-swap=3000m"
steps:
# Check out the PR branch, not the default branch.
# issue_comment events set GITHUB_REF to the default branch; we need
# refs/pull/N/head to get the actual PR code.
- uses: actions/checkout@v4
with:
ref: refs/pull/${{ github.event.issue.number }}/head
- name: Configure (LOW_MEMORY_BUILD — -O0, no PCH, unity batch 1)
run: |
cmake -S code -B build \
-DWITH_CGAL_TESTS=ON \
-DCMAKE_BUILD_TYPE=Release \
-DCONFORMALLAB_LOW_MEMORY_BUILD=ON
- name: Build CGAL-Tests
run: nice -n 19 cmake --build build --target conformallab_cgal_tests -j1
- name: Run CGAL-Tests
run: >
ctest --test-dir build
-R "^cgal\."
--output-on-failure
--output-junit cgal-results.xml
- name: Summary
if: always()
run: |
if [ -f cgal-results.xml ]; then
total=$(grep -o 'tests="[0-9]*"' cgal-results.xml | grep -o '[0-9]*' | head -1)
failed=$(grep -o 'failures="[0-9]*"' cgal-results.xml | grep -o '[0-9]*' | head -1)
skipped=$(grep -o 'skipped="[0-9]*"' cgal-results.xml | grep -o '[0-9]*' | head -1)
passed=$(( ${total:-0} - ${failed:-0} - ${skipped:-0} ))
echo "CGAL ▸ TOTAL ${total:-0} | PASSED $passed | FAILED ${failed:-0} | SKIPPED ${skipped:-0}"
fi
# ── Structural gate: doc/api/tests.md totals match ctest reality ───
# Single source of truth for test counts (see doc/release-policy.md).
# Reuses the already-built ./build dir via BUILD_DIR env var, so this
# adds ~5 s on top of the existing CGAL job.
- name: Verify test-count consistency (doc/api/tests.md)
run: BUILD_DIR=build bash scripts/check-test-counts.sh
# ── Structural gate: end-to-end smoke (try_it.sh) ──────────────────
# The user-facing quick-start script: configure + build + run the
# full ctest + run the Euclidean example on a bundled mesh. If
# this regresses, README quick-start instructions are broken.
# try_it.sh creates its own build-try/ — accept the ~3 min cost as
# the price of guaranteeing the documented workflow stays working.
- name: End-to-end smoke test (scripts/try_it.sh)
run: bash scripts/try_it.sh
# ─────────────────────────────────────────────────────────────────────────────
# Job 3 — quality-gates (style + convention block)
#
# Trigger: write "/quality-gates" as a comment on any pull request.
#
# Cheap, deterministic checks (~30 s): license headers, CGAL conventions,
# codespell, shellcheck. Runs independently of test-fast when comment-
# triggered (no `needs:` — the caller decides when to invoke it).
# ─────────────────────────────────────────────────────────────────────────────
quality-gates:
if: |
github.event_name == 'issue_comment' &&
github.event.issue.pull_request != null &&
contains(github.event.comment.body, '/quality-gates')
runs-on: eulernest
container:
image: git.eulernest.eu/conformallab/ci-cpp:latest
steps:
- uses: actions/checkout@v4
with:
ref: refs/pull/${{ github.event.issue.number }}/head
- name: Install codespell + shellcheck (job-local)
run: |
apt-get update -qq
apt-get install -y --no-install-recommends \
codespell shellcheck
- name: License headers (every C++ source carries MIT SPDX)
run: bash scripts/quality/license-headers.sh
- name: CGAL conventions (6 rules over CGAL public headers)
run: python3 scripts/quality/cgal-conventions.py
- name: codespell (docs + source comments + script messages)
run: bash scripts/quality/codespell.sh
- name: shellcheck (scripts/**/*.sh, severity=warning, strict)
run: bash scripts/quality/shellcheck.sh --strict
- name: Summary
if: always()
run: |
echo "QUALITY ▸ all four gates passed."
echo " see scripts/quality/README.md for the full catalogue"
echo " (sanitizers, clang-tidy, coverage, etc. are local-only)"