Add a Gitea workflow

Fills the gap TODO.md recorded last commit: the sibling libraries all carry
.gitea/workflows/ci.yaml and this one did not, so every gate was run by hand.
Four jobs, in the shape libakerror and libakstdlib use, down to the JUnit
reporting and the annotate_only note about Gitea 404ing on the Checks API.

cmake_build configures, builds and runs the 61-case suite with JUnit output.
docs runs `doxygen Doxyfile` -- a real gate, since WARN_AS_ERROR is set -- and
uploads build/docs/html as the api-documentation artifact. sanitizers runs the
whole suite under ASan and UBSan, which libakstdlib's TODO.md calls its own
highest-value missing item and which matters here because this library is all
fixed pools and manual buffer arithmetic. coverage gates at 90% of lines against
an actual 92.3% and uploads the html report.

Two things worth knowing, both checked rather than assumed.

The checkout is submodules: true, not recursive. The build needs libakerror,
libakstdlib and basicinterpret; it does not need libakgl, which is guarded
behind AKBASIC_WITH_AKGL and defaults OFF, and recursing would clone SDL,
SDL_image, SDL_mixer, SDL_ttf and jansson for a target that is never configured.
The nested submodules are uninitialized in this working tree today and the build
is green, which is the proof. The docs job takes no submodules at all -- verified
by running doxygen against a tree with deps/ absent.

There is no branch-coverage gate. Branch coverage reads 17.3% and is not a
meaningful number here, for the reason libakgl's and libakstdlib's TODO.md both
record: the akerror control-flow macros expand into large branch trees at every
call site, most unreachable in normal operation. Gating on it would mean writing
tests for libakerror's macros.

All four jobs were executed locally end to end before committing, not just
eyeballed: 61/61 plain, 61/61 under ASan+UBSan, doxygen exit 0 producing 441
files, and gcovr exit 0 at the 90 gate. The gate was also confirmed to bite by
raising it to 99.

Not added: a mutation-testing job, which all three siblings have. There is no
scripts/mutation_test.py in this repository to run, and porting libakerror's is
its own piece of work -- filed in TODO.md, where it matters more than usual
because the akerror macros expand at their call sites and coverage cannot see
them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-31 07:09:38 -04:00
parent 134ade9392
commit 2ddee571a1
3 changed files with 183 additions and 5 deletions

23
TODO.md
View File

@@ -635,10 +635,17 @@ Dependency baseline:
| `deps/libakstdlib` | 0.1.0 | soname `libakstdlib.so.0.1`. `AKSL_VERSION_CHECK()` asserted in `tests/version_check.c`. Its `aksl_ato*` family is banned here — see §1.9. |
| `deps/libakgl` | 0.1.0 | Migrated to the 1.0.0 registry and owns 256260. Not yet linked: `AKBASIC_WITH_AKGL` defaults OFF and `src/sink_akgl.c` does not exist. |
**This repository has no CI.** `libakgl` and `libakstdlib` both carry
`.gitea/workflows/ci.yaml`; akbasic does not, so every gate here — ctest, the sanitizer build,
coverage, and `doxygen Doxyfile` with `WARN_AS_ERROR` — is currently run by hand. Copying
`deps/libakgl/.gitea/workflows/ci.yaml` and adjusting the option prefixes is the whole job.
CI is `.gitea/workflows/ci.yaml`, in the shape the sibling libraries use: four jobs covering
the suite, the doxygen gate, ASan+UBSan and coverage. The generated API documentation and the
coverage report are both uploaded as artifacts. Two notes on it worth keeping:
- The checkout is `submodules: true`, **not** `recursive`. The build needs `libakerror`,
`libakstdlib` and `basicinterpret`; it does not need `libakgl`, which is guarded behind
`AKBASIC_WITH_AKGL` and defaults OFF — and recursing into it would clone SDL, SDL_image,
SDL_mixer, SDL_ttf and jansson for a target that is never configured. The `docs` job needs
no submodules at all.
- There is no mutation-testing job, unlike `libakerror`, `libakstdlib` and `libakgl`. This
repository has no `scripts/mutation_test.py`; see the item below.
What remains, in priority order:
@@ -647,5 +654,11 @@ What remains, in priority order:
2. **§4 — the language completion work queue.** Groups A, B, D, F and J need nothing from
`libakgl` and can start immediately. Multiple statements per line (the `COLON` token exists
and nothing consumes it) should come first, because `DO`/`LOOP` reads badly without it.
3. **§6 items 1216** — the defects the port uncovered. Item 12 is the one that produces a
3. **§6 items 1217** — the defects the port uncovered. Item 12 is the one that produces a
*wrong answer* rather than a refused one, and should be fixed first.
4. **Mutation testing.** All three sibling libraries gate on it and this one does not, because
there is no `scripts/mutation_test.py` here to run. It matters more than usual for this
codebase: the akerror macros expand at their call sites, so line coverage cannot see them
and mutation testing is the only thing that checks the `ATTEMPT`/`CATCH`/`PASS` control
flow at all. `deps/libakerror/scripts/mutation_test.py` is the one to port; `src/value.c`
or `src/scanner.c` would be the right first target.