Repository navigation
124 lines (111 loc) · 6.36 KB
/
Copy pathci.yml
File metadata and controls
124 lines (111 loc) · 6.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
name: ci
# Host-side verification of the PROS-free core, plus the ARM compile gate.
# Runs the same checks we run locally: the architecture guards, the strict host
# build, the test suite, and (since chunk A4) a cross-COMPILE of every v2 header
# for the V5's Cortex-A9.
# (The on-robot ARM LINK/run is intentionally NOT in CI — it needs PROS's bundled
# toolchain, the kernel cold package, and ultimately the robot (chunks R1/R3);
# what CI can and does hold is that no host-only assumption ever enters the
# headers unnoticed.)
on:
push:
pull_request:
jobs:
host-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# python3 is REQUIRED by the host test build, not optional: it runs the
# documentation gates (tools/api_doc_tool.py) that fail the build when a
# public member is undocumented, when the generated reference in docs/api/
# is stale, when a documented example has drifted from the compiled test
# that proves it, or when a public document links into docs/internal/.
# Before chunk D3 the last two lived only in an internal verify script, so
# a rotted example passed CI; mutation found that, and this is the fix.
- name: Install host toolchain
run: sudo apt-get update && sudo apt-get install -y cmake g++ python3
# ARCHITECTURE GUARD: the library must never include <pros/*>. That
# PROS-freeness is exactly what makes it host-testable. Scope = ALL of
# include/shulib/ (broadened at the C7 legacy cutover, 2026-08-10, when
# the old PROS-coupled code was deleted), EXCEPT the one path that exists
# to include PROS: include/shulib/hal/pros/, the adapter tree (chunk
# R1a). The exemption is PATH-ANCHORED (a prefix match on the exact
# directory), NOT --exclude-dir=pros: the name-based form was MEASURED
# missing a violation planted at include/shulib/localization/pros/ —
# any directory named "pros", anywhere, would have been exempt (D3: "a
# gate's exclusion list is where its holes live"; brief M8/M9).
# src/main.cpp remains the other deliberate exception: it lives outside
# include/shulib/ and is the PROS entry point wiring the PROS-free core.
- name: No <pros/> in the library (except hal/pros, path-anchored)
run: |
if grep -rnE '#[[:space:]]*include[[:space:]]*[<"]pros/' include/shulib \
| grep -v '^include/shulib/hal/pros/'; then
echo "::error::include/shulib must stay PROS-free outside hal/pros/ (no #include <pros/...> / \"pros/...\")"
exit 1
fi
echo "library is PROS-free (all of include/shulib except hal/pros/)"
# LAYERING GUARD (chunk A2, constraint 3): ground truth must never be reachable
# from an estimator. shulib/sim/ (the host plant) may include the core; the core
# may NEVER include shulib/sim/ — so code under test can only ever see the
# synthesized fakes, and truth stays a harness/assertion-only quantity.
# Scope = all of include/shulib/ EXCEPT sim/ itself (--exclude-dir), so a
# new core directory is covered the moment it exists — an enumerated list
# rots (broadened alongside the PROS guard at the C7 cutover).
- name: Core never includes the sim plant
run: |
if grep -rnE --exclude-dir=sim '#[[:space:]]*include[[:space:]]*[<"]shulib/sim/' \
include/shulib; then
echo "::error::the core must not depend on shulib/sim (ground truth would become reachable from estimators)"
exit 1
fi
echo "layering holds: core is sim-free"
# DOCUMENTATION GATES (chunk D3). Run explicitly as well as via the build,
# so a failure names itself in the CI log instead of appearing as "build
# failed" three hundred lines into a compile.
- name: Documentation gates (coverage, freshness, examples, removability, briefing, staleness)
run: |
python3 tools/api_doc_tool.py self-test
python3 tools/api_doc_tool.py check-coverage
python3 tools/api_doc_tool.py check-fresh
python3 tools/api_doc_tool.py check-examples
python3 tools/api_doc_tool.py check-removability
python3 tools/briefing_status.py check
python3 tools/doc_staleness_audit.py self-test
python3 tools/doc_staleness_audit.py
- name: Configure (host tests)
run: cmake -S test -B build/test
- name: Build (strict -Werror)
run: cmake --build build/test
- name: Run tests
run: ./build/test/shulib_tests
# ARM COMPILE GATE (chunk A4). The v2 core was verified to cross-compile clean
# for the V5's Cortex-A9 at every chunk since A1 — but only by hand, so nothing
# KEPT it that way: a host-only construct (a header, an intrinsic, a hosted-only
# std facility) could enter the core unnoticed and surface at R1, where it is
# expensive. This job holds the line.
#
# Scope, stated honestly: this is a COMPILE gate, not a link or run gate. The
# real on-robot build still needs PROS's bundled toolchain + the kernel cold
# package (R1) and the robot itself (R3). What compiling every header as one TU
# under the same strict flags as host DOES guarantee: the headers make no
# host-only assumption, at the exact -std/-mcpu/-mfpu/-mfloat-abi the V5 uses.
#
# The header list is GENERATED (find | sort), never hard-coded — a gate you must
# remember to update when adding a file is a gate that rots. A new header under
# include/shulib/ is covered the moment it exists.
arm-compile-gate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install ARM cross-compiler
run: sudo apt-get update && sudo apt-get install -y gcc-arm-none-eabi
- name: Cross-compile every v2 header for the V5 (Cortex-A9, softfp)
run: |
find include/shulib -name '*.hpp' | sed 's|^include/||' | LC_ALL=C sort \
| awk '{print "#include \""$0"\""}' > all_headers.cpp
echo 'int main() { return 0; }' >> all_headers.cpp
echo "TU includes $(grep -c '#include' all_headers.cpp) headers"
arm-none-eabi-g++ -std=gnu++20 -Wall -Wextra -Wconversion -Wsign-conversion \
-Wshadow -Werror -Os -mcpu=cortex-a9 -mfpu=neon-fp16 -mfloat-abi=softfp \
-c all_headers.cpp -o /dev/null -Iinclude
echo "ARM compile gate: CLEAN (all v2 headers)"