scripts/coverage.py configures an instrumented build tree (-DAKERR_COVERAGE=ON), runs the CTest suite in it, and reports merged gcov line/branch/function coverage per library source. Like the mutation harness it has no third-party dependencies and supports --threshold and --junit; thresholds gate each file as well as the total so the generated status-name table cannot mask a regression in src/error.c. Only the library is instrumented. The public header's macros cannot be measured this way -- GCC attributes an expanded macro to its call site, so header logic would report as lines of the test that used it -- which is what mutation testing against include/akerror.tmpl.h is for. Coverage flags are applied per target rather than globally, so they do not leak into the exported/installed target interface. Current numbers for src/error.c are 94.0% line and 59.5% branch; the CI gate is set to 90/50 to keep headroom, matching the convention used for the mutation score threshold. Tests run: ctest (23/23), cmake --build build --target coverage, threshold gate verified failing at --threshold 99, cmake --install checked for flag leakage, out-of-tree --build-dir checked. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
100 lines
4.1 KiB
YAML
100 lines
4.1 KiB
YAML
name: libakerror CI Build
|
|
run-name: ${{ gitea.actor }} libakerror test
|
|
on: [push]
|
|
|
|
jobs:
|
|
cmake_build:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- run: echo "Triggered by ${{ gitea.event_name }} from ${{ gitea.repository }}@${{ gitea.ref }}. Building on ${{ runner.os }}."
|
|
- name: Check out repository code
|
|
uses: actions/checkout@v4
|
|
- name: dependencies
|
|
run: |
|
|
sudo apt-get update -y
|
|
sudo apt-get install -y cmake gcc moreutils
|
|
- name: build and install
|
|
run: |
|
|
mkdir installdir
|
|
cmake -S . -B build -DCMAKE_INSTALL_PREFIX=installdir
|
|
cmake --build build
|
|
cmake --install build
|
|
# --output-junit resolves relative to the test dir, so give an absolute
|
|
# path to land the report in the workspace root for the reporter below.
|
|
- name: test (JUnit)
|
|
run: ctest --test-dir build --output-on-failure --output-junit "$(pwd)/ctest-junit.xml"
|
|
# annotate_only: true skips creating a check run via the Checks API, which
|
|
# Gitea does not support and 404s on (mikepenz/action-junit-report#23).
|
|
# Results surface via the job summary instead.
|
|
- name: publish test results
|
|
if: always()
|
|
uses: mikepenz/action-junit-report@v4
|
|
with:
|
|
report_paths: 'ctest-junit.xml'
|
|
annotate_only: true
|
|
detailed_summary: true
|
|
include_passed: true
|
|
fail_on_failure: 'true'
|
|
- run: echo "🍏 This job's status is ${{ job.status }}."
|
|
|
|
coverage:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Check out repository code
|
|
uses: actions/checkout@v4
|
|
- name: dependencies
|
|
run: |
|
|
sudo apt-get update -y
|
|
sudo apt-get install -y cmake gcc moreutils python3
|
|
# Run the suite against a gcov-instrumented build and gate on coverage of
|
|
# the library sources. Thresholds keep headroom below the current numbers
|
|
# (src/error.c: ~94% line, ~60% branch) and apply per file as well as to
|
|
# the total, so the generated status-name table cannot mask a regression.
|
|
- name: coverage
|
|
run: |
|
|
python3 scripts/coverage.py --junit coverage-junit.xml --threshold 90 --branch-threshold 50
|
|
# Publish even when the threshold gate fails, so gaps are visible.
|
|
# Display-only (fail_on_failure: false); the --threshold above is the gate.
|
|
# annotate_only avoids the Checks API 404 on Gitea (see note above).
|
|
- name: publish coverage results
|
|
if: always()
|
|
uses: mikepenz/action-junit-report@v4
|
|
with:
|
|
report_paths: 'coverage-junit.xml'
|
|
annotate_only: true
|
|
detailed_summary: true
|
|
include_passed: true
|
|
fail_on_failure: 'false'
|
|
- run: echo "🍏 This job's status is ${{ job.status }}."
|
|
|
|
mutation_test:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Check out repository code
|
|
uses: actions/checkout@v4
|
|
- name: dependencies
|
|
run: |
|
|
sudo apt-get update -y
|
|
sudo apt-get install -y cmake gcc moreutils python3
|
|
# Verify the tests actually catch bugs: break the library many ways and
|
|
# confirm the suite fails. Gated on src/error.c (fast, deterministic).
|
|
# The threshold keeps headroom below the current score for equivalent
|
|
# mutants; see tests/MUTATION.md. Run the full default target locally for
|
|
# deeper (slower) coverage including the macro header.
|
|
- name: mutation testing
|
|
run: |
|
|
python3 scripts/mutation_test.py --target src/error.c --junit mutation-junit.xml --threshold 65
|
|
# Publish even when the threshold gate fails, so survivors are visible.
|
|
# Display-only (fail_on_failure: false); the --threshold above is the gate.
|
|
# annotate_only avoids the Checks API 404 on Gitea (see note above).
|
|
- name: publish mutation results
|
|
if: always()
|
|
uses: mikepenz/action-junit-report@v4
|
|
with:
|
|
report_paths: 'mutation-junit.xml'
|
|
annotate_only: true
|
|
detailed_summary: true
|
|
include_passed: true
|
|
fail_on_failure: 'false'
|
|
- run: echo "🍏 This job's status is ${{ job.status }}."
|