3636 XLINGS_NON_INTERACTIVE : ' 1'
3737
3838jobs :
39+ # ── Linux, under both standard libraries ─────────────────────────────────────
40+ #
41+ # WHY TWO TOOLCHAINS. The job used to run whatever mcpp installed by default on
42+ # a fresh runner, which is gcc and libstdc++, and nothing ran the tests under
43+ # libc++. libc++ is the standard library of every other job below — macOS and
44+ # openkal — and of mcpp's own default where a developer has chosen llvm; the
45+ # cancellation tests met a libc++ defect that libstdc++ does not have
46+ # (tests/test_cancel.cpp, at the top), and no job here could have seen it.
3947 build :
40- name : build + test (linux x86_64, mcpp )
48+ name : build + test (linux x86_64, ${{ matrix.toolchain }} )
4149 runs-on : ubuntu-latest
4250 timeout-minutes : 45
51+ strategy :
52+ fail-fast : false
53+ matrix :
54+ toolchain : ['gcc@16.1.0', 'llvm@22.1.8']
4355 steps :
4456 - uses : actions/checkout@v4
4557
@@ -67,21 +79,28 @@ jobs:
6779 mcpp self config --mirror GLOBAL
6880
6981 # The toolchain mcpp bootstraps is decided by the version pinned above, so
70- # that version is the whole of the key.
82+ # that version and the toolchain are the whole of the key.
7183 - name : Cache mcpp sandbox
7284 uses : actions/cache@v4
7385 with :
7486 path : ~/.xlings/data/xpkgs/xim-x-mcpp/${{ env.MCPP_VERSION }}/registry
75- key : mcpp-sandbox-${{ runner.os }}-mcpp${{ env.MCPP_VERSION }}
87+ key : mcpp-sandbox-${{ runner.os }}-mcpp${{ env.MCPP_VERSION }}-${{ matrix.toolchain }}
88+
89+ - name : Select the toolchain
90+ run : |
91+ spec='${{ matrix.toolchain }}'
92+ mcpp toolchain install "${spec%@*}" "${spec#*@}"
93+ mcpp toolchain default "$spec"
94+ mcpp toolchain list
7695
7796 - name : Build with mcpp
7897 run : mcpp build
7998
80- # Most of these are hermetic: `test_framing` needs nothing, and `test_pool`
81- # scripts its own TLS server on 127.0.0.1. The eight in `test_download`
82- # and `test_resolver` reach httpbin.org and one.one.one.one; a network
83- # failure among them is distinguishable in the log by the endpoint it
84- # names.
99+ # Most of these are hermetic: `test_framing` needs nothing, and `test_pool`,
100+ # `test_proxy` and `test_cancel` script their own servers on 127.0.0.1. The
101+ # eight in `test_download` and `test_resolver` reach httpbin.org and
102+ # one.one.one.one; a network failure among them is distinguishable in the
103+ # log by the endpoint it names.
85104 - name : Run tests
86105 run : mcpp test
87106
@@ -95,6 +114,52 @@ jobs:
95114 - name : Smoke-test the project templates
96115 run : bash tools/template_smoke.sh
97116
117+ # ── macOS ────────────────────────────────────────────────────────────────────
118+ #
119+ # THE README NAMES macOS, AND UNTIL THIS JOB NOTHING RAN THERE. The
120+ # differences are real and in this library's own code: SO_NOSIGPIPE rather
121+ # than MSG_NOSIGNAL (src/platform.cppm), /dev/urandom as mbedTLS's entropy,
122+ # the system CA bundle's location, and poll(2) on a socket whose connect is in
123+ # progress, which the cancellation slices wait on.
124+ macos :
125+ name : build + test (macos arm64, llvm@22.1.8)
126+ runs-on : macos-15
127+ timeout-minutes : 45
128+ steps :
129+ - uses : actions/checkout@v4
130+
131+ - name : Install xlings
132+ run : |
133+ curl -fsSL --retry 3 --retry-all-errors --retry-delay 2 \
134+ https://raw.githubusercontent.com/openxlings/xlings/main/tools/other/quick_install.sh \
135+ | bash -s "$XLINGS_VERSION"
136+ echo "$HOME/.xlings/subos/current/bin" >> "$GITHUB_PATH"
137+
138+ - name : Install mcpp
139+ run : |
140+ xlings update
141+ xlings install "mcpp@$MCPP_VERSION" -y -g
142+ mcpp --version
143+ mcpp self config --mirror GLOBAL
144+
145+ - name : Cache mcpp sandbox
146+ uses : actions/cache@v4
147+ with :
148+ path : ~/.xlings/data/xpkgs/xim-x-mcpp/${{ env.MCPP_VERSION }}/registry
149+ key : mcpp-sandbox-${{ runner.os }}-mcpp${{ env.MCPP_VERSION }}-llvm@22.1.8
150+
151+ - name : Select the toolchain
152+ run : |
153+ mcpp toolchain install llvm 22.1.8
154+ mcpp toolchain default llvm@22.1.8
155+ mcpp toolchain list
156+
157+ - name : Build with mcpp
158+ run : mcpp build
159+
160+ - name : Run tests
161+ run : mcpp test
162+
98163 # ── The same sources, on a different kernel ABI ──────────────────────────────
99164 #
100165 # WHY THIS IS A SEPARATE JOB AND NOT A STEP. It resolves a different toolchain
@@ -109,10 +174,21 @@ jobs:
109174 # openkal-musl defines the first and not the second. A `#ifdef` that is wrong
110175 # about that compiles cleanly here and fails there, which is exactly how
111176 # 5e7d66f reached master.
177+ #
178+ # FOUR TARGETS, THE ONES mcpp-index MEASURES tinyhttps ON (its
179+ # tests/openkal/pins.toml). x86_64-windows-musl runs under wine and
180+ # aarch64-linux-musl under qemu, through the runners examples/openkal names.
181+ # The Windows one is where every handshake used to fail for want of entropy
182+ # (src/tls.cppm); it has no name resolution, so its network step reports
183+ # "no network" and the cancellation check, which needs none, is what runs.
112184 openkal :
113- name : build + run (linux x86_64 , above openkal)
114- runs-on : ubuntu-latest
185+ name : build + run (${{ matrix.target }} , above openkal)
186+ runs-on : ubuntu-24.04
115187 timeout-minutes : 45
188+ strategy :
189+ fail-fast : false
190+ matrix :
191+ target : ['x86_64-linux-gnu', 'x86_64-linux-musl', 'x86_64-windows-musl', 'aarch64-linux-musl']
116192 steps :
117193 - uses : actions/checkout@v4
118194
@@ -130,32 +206,50 @@ jobs:
130206 mcpp --version
131207 mcpp self config --mirror GLOBAL
132208
209+ - name : Install the runners
210+ if : matrix.target == 'x86_64-windows-musl' || matrix.target == 'aarch64-linux-musl'
211+ run : |
212+ sudo apt-get update -qq
213+ sudo apt-get install -y -qq mingw-w64 wine64 qemu-user > /dev/null
214+ command -v wine || sudo ln -s "$(command -v wine64)" /usr/local/bin/wine
215+ wine --version
216+ qemu-aarch64 --version | head -1
217+
133218 - name : Cache mcpp sandbox
134219 uses : actions/cache@v4
135220 with :
136221 path : ~/.xlings/data/xpkgs/xim-x-mcpp/${{ env.MCPP_VERSION }}/registry
137- key : mcpp-openkal-${{ runner.os }}-mcpp${{ env.MCPP_VERSION }}
222+ key : mcpp-openkal-${{ runner.os }}-mcpp${{ env.MCPP_VERSION }}-${{ matrix.target }}
138223
139224 # The example builds the library from this checkout (`path = "../.."`) and
140225 # takes the stack beneath it from the index, so what is tested is this
141226 # commit against the published openkal packages.
142227 #
143- # It makes one HTTPS request and reports "no network" rather than failing
144- # when there is none, so a runner without egress reports "not run" instead
145- # of "broken". A certificate the client refused is a failure, not an
146- # absence of network. The build, the link and the framing parsers are
147- # checked either way.
228+ # It cancels a handshake against a local listener, which needs no network,
229+ # and then makes one HTTPS request; it reports "no network" rather than
230+ # failing when there is none, so a runner without egress reports "not run"
231+ # instead of "broken". A certificate the client refused is a failure, not
232+ # an absence of network. The build, the link, the framing parsers and the
233+ # cancellation are checked either way.
148234 - name : Build and run above openkal
149235 working-directory : examples/openkal
150- run : mcpp run
236+ run : |
237+ set -o pipefail
238+ mcpp run --target '${{ matrix.target }}' 2>&1 | tee run.log
239+ grep -q '^cancellation: ok' run.log
151240
152- # ── The Windows ROOT certificate store ───────────────────────────────────────
241+ # ── Windows ─────────────────────────── ───────────────────────────────────────
153242 #
154243 # WHY THIS JOB EXISTS. Windows keeps no bundle file, so on a Windows Sockets
155244 # build `load_ca_certs` reads the system's ROOT store through the Win32 API
156245 # (src/ca_bundle.cppm). That code is compiled on no other platform, and a job
157246 # elsewhere can show neither that it builds nor that the roots it returns
158247 # verify a real certificate chain. `test_ca_store` asserts both.
248+ #
249+ # AND THE HERMETIC TESTS RUN HERE TOO. They script their own servers on
250+ # 127.0.0.1, and Windows Sockets is where `poll` is `WSAPoll`, a connect in
251+ # progress is reported differently, and the cancellation slices were never
252+ # run before this job ran them.
159253 windows :
160254 name : build + test (windows x86_64, ${{ matrix.toolchain }})
161255 runs-on : windows-2022
@@ -197,3 +291,11 @@ jobs:
197291 run : |
198292 mcpp test test_ca_store 2>&1 | tee tests.log
199293 grep -q '^test_ca_store \.\.\. ok' tests.log
294+
295+ - name : The hermetic tests
296+ run : |
297+ set -o pipefail
298+ for t in test_framing test_tls_verify test_pool test_proxy test_cancel; do
299+ mcpp test "$t" 2>&1 | tee "$t.log"
300+ grep -q "^$t \.\.\. ok" "$t.log"
301+ done
0 commit comments