Repository navigation
442 lines (422 loc) · 22.1 KB
/
Copy pathci.yml
File metadata and controls
442 lines (422 loc) · 22.1 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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
name: CI
# What this workflow asserts about mcpplibs.os.
#
# tests every module behaves as stated, on every system and with every
# compiler family a consumer builds it with (the native rows)
# hosted the same tests, the program's C library and C++ run-time being
# openkal-musl and openkal-llvm-runtime on the system's own triple
# (checks/hosted; mcpp docs/24)
# platform a platform module used outside `if constexpr' for its platform
# fails to LINK, and the same use in a discarded branch links (R5)
# emscripten the tests that start no program, built for wasm32-emscripten and
# run under node (checks/emscripten); a program that starts one
# fails at LINK naming the openkal symbol (checks/absent)
#
# The library is built with the released mcpp, 2026.11.9.1: its tests are
# mtest's, and mtest uses mcpplibs.os, so the package being built has to stand
# for itself in its tests' graph, which mcpp does from 2026.11.9.1; it also
# resolves within the platform's version group (an earlier mcpp takes the newest
# member of a range and then refuses it against the group). The ok images
# (MCPP_PLATFORM) and checks/hosted select openkal-platform 0.24 and its
# OpenKal 0.24 implementation, musl 0.28 and C++ runtime 0.19 group. The library
# itself needs 2026.10.27.1 or later, the first that selects a platform
# (SPEC-013). A dispatch may name a branch of mcpp instead (`mcpp_ref'), which
# the latest released mcpp builds and which is then used.
on:
push:
branches: [main]
pull_request:
workflow_dispatch:
inputs:
mcpp_ref:
description: "Branch of mcpp-community/mcpp to build and test with (empty = the released mcpp)"
required: false
default: ""
env:
MCPP_SOURCE_REF: ${{ github.event.inputs.mcpp_ref || vars.MCPP_SOURCE_REF || '' }}
# 2026.11.3.1: the std module compiled with the platform's words (openkal-platform 0.23.0's
# `-fcf-protection=full` refused every `import std` of an earlier mcpp's).
MCPP_INSTALL: ${{ (github.event.inputs.mcpp_ref || vars.MCPP_SOURCE_REF) && 'mcpp' || 'mcpp@2026.11.9.1' }}
XLINGS_VERSION: v2026.10.26.1
XLINGS_NON_INTERACTIVE: '1'
jobs:
native:
name: ${{ matrix.os }} ${{ matrix.toolchain }} ${{ matrix.profile }}
runs-on: ${{ matrix.os }}
timeout-minutes: 90
strategy:
fail-fast: false
matrix:
include:
- { os: ubuntu-24.04, toolchain: 'gcc@16.1.0', profile: dev }
- { os: ubuntu-24.04, toolchain: 'gcc@16.1.0', profile: release }
- { os: ubuntu-24.04, toolchain: 'llvm@23.1.3', profile: dev }
- { os: ubuntu-24.04-arm, toolchain: 'gcc@16.1.0', profile: dev }
- { os: macos-15, toolchain: 'llvm@23.1.3', profile: dev }
- { os: windows-2022, toolchain: 'llvm@23.1.3', profile: dev }
- { os: windows-2022, toolchain: 'msvc@system', profile: dev }
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v4
- name: Install xlings and mcpp (Unix)
if: runner.os != 'Windows'
run: |
curl -fsSL https://raw.githubusercontent.com/openxlings/xlings/main/tools/other/quick_install.sh \
| bash -s "$XLINGS_VERSION"
echo "$HOME/.xlings/subos/current/bin" >> "$GITHUB_PATH"
- name: Install xlings and mcpp (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
irm https://d2learn.org/xlings-install.ps1.txt | iex
"$env:USERPROFILE\.xlings\subos\current\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
- name: The mcpp under cross-validation
run: |
# The configured mirror (GLOBAL), then CN (GitCode first) from the fourth attempt: a cached index
# can predate the release, and xlings keeps it when an anonymous refresh fails.
for attempt in 1 2 3 4 5 6; do
[ "$attempt" = 4 ] && { xlings config --mirror CN > /dev/null 2>&1 || true; }
xlings update > /dev/null 2>&1 || true
if xlings install "$MCPP_INSTALL" -y -g; then break; fi
[ "$attempt" = 6 ] && { echo "::error::mcpp could not be installed"; exit 1; }
sleep 60
done
mcpp --version
mcpp self config --mirror GLOBAL
if [ -n "${MCPP_SOURCE_REF:-}" ]; then
src="$RUNNER_TEMP/mcpp-src"
git clone --quiet --depth 1 --branch "$MCPP_SOURCE_REF" https://github.com/mcpp-community/mcpp.git "$src"
rm -f "$src/.xlings.json"
# mcpp's own build is not this job's target: MCPP_PLATFORM names the
# platform of the os package's images, and mcpp's graph is another.
( cd "$src" && env -u MCPP_PLATFORM mcpp build --release )
built=$(find "$src/target" -type f \( -name mcpp -o -name mcpp.exe \) | head -1)
[ -n "$built" ] || { echo "::error::mcpp did not build from $MCPP_SOURCE_REF"; exit 1; }
echo "$(cd "$(dirname "$built")" && pwd)" >> "$GITHUB_PATH"
echo "under review: $("$built" --version) (from $MCPP_SOURCE_REF)"
fi
- name: Select the toolchain
run: |
spec='${{ matrix.toolchain }}'
case "$spec" in
msvc*) mcpp toolchain default msvc ;;
*) mcpp toolchain install "${spec%@*}" "${spec#*@}"
mcpp toolchain default "$spec" ;;
esac
- name: Tests
run: |
profile='${{ matrix.profile }}'
mcpp test --profile "$profile" 2>&1 | tee tests.log
for name in platform_test fs_test process_test ipc_test unit_test dirs_terminal_test linux_test watch_test windows_test macos_test; do
grep -q "^$name \.\.\. ok" tests.log || { echo "::error::$name did not run or did not pass"; exit 1; }
done
- name: The compile-time constants of a native target (R3)
run: ( cd checks/constants && mcpp build ) || { echo "::error::a native constant does not hold"; exit 1; }
- name: A platform module is a link error outside its platform, and links in a discarded branch (R5)
run: |
( cd checks/discarded && mcpp build ) || { echo "::error::a discarded use of a platform module did not link"; exit 1; }
if ( cd checks/misuse && mcpp build ) > misuse.log 2>&1; then
cat misuse.log
echo "::error::a platform module used outside its platform linked"
exit 1
fi
grep -Eiq "undefined|unresolved" misuse.log || { cat misuse.log; echo "::error::the misuse failed for another reason than an undefined name"; exit 1; }
echo " ok the misuse fails at the link, naming what is undefined"
# ── THE TESTS OVER A C LIBRARY ON OPENKAL ──────────────────────────────────
#
# The C library presents POSIX and openkal rather than the system: its headers
# are not the SDK's, on Windows its data model is LP64 and its `wchar_t' 32
# bits, and its descriptors and signals are its own. The units beside openkal
# reach each system through the system's own interface, and these rows are
# where that is asserted.
hosted:
name: hosted ${{ matrix.os }} ${{ matrix.profile }}
runs-on: ${{ matrix.os }}
timeout-minutes: 90
strategy:
fail-fast: false
matrix:
# The system's own triple; on macOS and Windows named, as a program in
# this arrangement names it: a Windows host defaults to the MSVC target,
# and openkal's Windows implementation is reached through the GNU one.
include:
- { os: ubuntu-24.04, target: '', profile: dev }
- { os: ubuntu-24.04, target: '', profile: release }
- { os: ubuntu-24.04-arm, target: '', profile: dev }
- { os: macos-15, target: '--target aarch64-macos', profile: dev }
- { os: windows-2022, target: '--target x86_64-windows-gnu', profile: dev }
- { os: windows-2022, target: '--target x86_64-windows-gnu', profile: release }
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v4
- name: Install xlings and mcpp (Unix)
if: runner.os != 'Windows'
run: |
curl -fsSL https://raw.githubusercontent.com/openxlings/xlings/main/tools/other/quick_install.sh \
| bash -s "$XLINGS_VERSION"
echo "$HOME/.xlings/subos/current/bin" >> "$GITHUB_PATH"
- name: Install xlings and mcpp (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
irm https://d2learn.org/xlings-install.ps1.txt | iex
"$env:USERPROFILE\.xlings\subos\current\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
- name: The mcpp under cross-validation
run: |
# The configured mirror (GLOBAL), then CN (GitCode first) from the fourth attempt: a cached index
# can predate the release, and xlings keeps it when an anonymous refresh fails.
for attempt in 1 2 3 4 5 6; do
[ "$attempt" = 4 ] && { xlings config --mirror CN > /dev/null 2>&1 || true; }
xlings update > /dev/null 2>&1 || true
if xlings install "$MCPP_INSTALL" -y -g; then break; fi
[ "$attempt" = 6 ] && { echo "::error::mcpp could not be installed"; exit 1; }
sleep 60
done
mcpp --version
mcpp self config --mirror GLOBAL
if [ -n "${MCPP_SOURCE_REF:-}" ]; then
src="$RUNNER_TEMP/mcpp-src"
git clone --quiet --depth 1 --branch "$MCPP_SOURCE_REF" https://github.com/mcpp-community/mcpp.git "$src"
rm -f "$src/.xlings.json"
# mcpp's own build is not this job's target: MCPP_PLATFORM names the
# platform of the os package's images, and mcpp's graph is another.
( cd "$src" && env -u MCPP_PLATFORM mcpp build --release )
built=$(find "$src/target" -type f \( -name mcpp -o -name mcpp.exe \) | head -1)
[ -n "$built" ] || { echo "::error::mcpp did not build from $MCPP_SOURCE_REF"; exit 1; }
echo "$(cd "$(dirname "$built")" && pwd)" >> "$GITHUB_PATH"
echo "under review: $("$built" --version) (from $MCPP_SOURCE_REF)"
fi
mcpp toolchain install llvm 23.1.3
- name: Every test of the package has its counterpart here
run: |
for t in tests/*_test.cpp; do
n=$(basename "$t")
[ -f "checks/hosted/tests/$n" ] || { echo "::error::checks/hosted/tests has no $n"; exit 1; }
done
- name: Tests
working-directory: checks/hosted
run: |
profile='${{ matrix.profile }}'
mcpp test --profile "$profile" ${{ matrix.target }} 2>&1 | tee tests.log
for name in platform_test fs_test process_test ipc_test unit_test dirs_terminal_test linux_test library_test watch_test windows_test macos_test; do
grep -q "^$name \.\.\. ok" tests.log || { echo "::error::$name did not run or did not pass"; exit 1; }
done
# ── THE TESTS AS OK IMAGES (`<arch>-openkal`, openkal SPEC clause 12) ──────
#
# The same five suites, built once on Linux for both architectures and run
# through okrun on four systems: `os::host()` is known only when an image is
# loaded, the conventions follow it, and a test that starts copies of itself
# starts the loader and the image (`os::env::self_command`).
images:
name: tests as ok images (built once)
runs-on: ubuntu-24.04
timeout-minutes: 120
env:
# openkal 0.24.0, which this release is written against, in the group of
# openkal-platform 0.24.4: its C++ run-time keeps the volume of a
# normalized name (openkal-llvm-runtime 0.19.2, which the long-spelling
# tests of 0.3.1 need on Windows), and its tools are openkal-ld and
# openkal-run 0.5.3, whose okrun enters an image in its convention's
# floating-point state.
MCPP_PLATFORM: openkal-platform@0.24.4
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v4
- name: Install xlings
run: |
curl -fsSL https://raw.githubusercontent.com/openxlings/xlings/main/tools/other/quick_install.sh \
| bash -s "$XLINGS_VERSION"
echo "$HOME/.xlings/subos/current/bin" >> "$GITHUB_PATH"
- name: The mcpp that has the target
run: |
xlings update > /dev/null 2>&1 || true
xlings install "$MCPP_INSTALL" -y -g
mcpp self config --mirror GLOBAL
if [ -n "${MCPP_SOURCE_REF:-}" ]; then
src="$RUNNER_TEMP/mcpp-src"
git clone --quiet --depth 1 --branch "$MCPP_SOURCE_REF" https://github.com/mcpp-community/mcpp.git "$src"
rm -f "$src/.xlings.json"
# mcpp's own build is not this job's target: MCPP_PLATFORM names the
# platform of the os package's images, and mcpp's graph is another.
( cd "$src" && env -u MCPP_PLATFORM mcpp build --release )
built=$(find "$src/target" -type f -name mcpp | head -1)
[ -n "$built" ] || { echo "::error::mcpp did not build"; exit 1; }
echo "$(cd "$(dirname "$built")" && pwd)" >> "$GITHUB_PATH"
fi
- name: The suites, run here and built for the other architecture
run: |
set -euo pipefail
mcpp test --target x86_64-openkal 2>&1 | tee tests.log
for name in platform_test fs_test process_test ipc_test unit_test dirs_terminal_test linux_test watch_test windows_test macos_test; do
grep -q "^$name \.\.\. ok" tests.log || { echo "::error::$name did not pass as an image"; exit 1; }
done
mcpp test --target aarch64-openkal --no-run
for arch in x86_64 aarch64; do
mkdir -p "out/$arch"
cp target/"$arch"-openkal/*/bin/*_test.oke "out/$arch/"
done
(cd out && sha256sum */* | tee SHA256SUMS)
- uses: actions/upload-artifact@v4
with: { name: os-test-images, path: out }
images-run:
name: tests as ok images on ${{ matrix.host }}
needs: images
runs-on: ${{ matrix.os }}
timeout-minutes: 45
env:
# openkal 0.24.0, which this release is written against, in the group of
# openkal-platform 0.24.4: its C++ run-time keeps the volume of a
# normalized name (openkal-llvm-runtime 0.19.2, which the long-spelling
# tests of 0.3.1 need on Windows), and its tools are openkal-ld and
# openkal-run 0.5.3, whose okrun enters an image in its convention's
# floating-point state.
MCPP_PLATFORM: openkal-platform@0.24.4
strategy:
fail-fast: false
matrix:
include:
- { host: linux-x86_64, os: ubuntu-24.04, arch: x86_64 }
- { host: linux-aarch64, os: ubuntu-24.04-arm, arch: aarch64 }
- { host: macos-arm64, os: macos-15, arch: aarch64 }
- { host: windows-x86_64, os: windows-2022, arch: x86_64 }
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v4
with: { sparse-checkout: mcpp.toml, sparse-checkout-cone-mode: false }
- uses: actions/download-artifact@v4
with: { name: os-test-images, path: out }
- name: Install xlings (Unix)
if: runner.os != 'Windows'
run: |
curl -fsSL https://raw.githubusercontent.com/openxlings/xlings/main/tools/other/quick_install.sh \
| bash -s "$XLINGS_VERSION"
echo "$HOME/.xlings/subos/current/bin" >> "$GITHUB_PATH"
- name: Install xlings (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
irm https://d2learn.org/xlings-install.ps1.txt | iex
"$env:USERPROFILE\.xlings\subos\current\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
- name: okrun, built here
run: |
xlings install "$MCPP_INSTALL" -y -g
mcpp self config --mirror GLOBAL
if [ -n "${MCPP_SOURCE_REF:-}" ]; then
src="$RUNNER_TEMP/mcpp-src"
git clone --quiet --depth 1 --branch "$MCPP_SOURCE_REF" https://github.com/mcpp-community/mcpp.git "$src"
rm -f "$src/.xlings.json"
# mcpp's own build is not this job's target: MCPP_PLATFORM names the
# platform of the os package's images, and mcpp's graph is another.
( cd "$src" && env -u MCPP_PLATFORM mcpp build --release )
built=$(find "$src/target" -type f \( -name mcpp -o -name mcpp.exe \) -path '*/bin/*' | head -1)
[ -n "$built" ] || { echo "::error::mcpp did not build"; exit 1; }
PATH="$(cd "$(dirname "$built")" && pwd):$PATH"
echo "$(cd "$(dirname "$built")" && pwd)" >> "$GITHUB_PATH"
fi
# The platform's runner, as this machine's configuration of the
# target names it: the platform's toolchain installed, its tools
# built (mcpp SPEC-013 §13).
t='${{ matrix.arch }}-openkal'
cd "$RUNNER_TEMP" # outside the sparse checkout: the configuration of no project
mcpp toolchain install --target "$t"
py=python3; command -v python3 > /dev/null 2>&1 && python3 -c '' 2>/dev/null || py=python
okrun=$(mcpp self env --target "$t" --format json | $py -c 'import json,sys; print(json.load(sys.stdin)["data"]["runner"]["program"] or "")')
[ -n "$okrun" ] || { echo "::error::the platform's runner was not located"; exit 1; }
echo "OKRUN=$okrun" >> "$GITHUB_ENV"
- name: The same bytes, every suite
run: |
set -euo pipefail
a='${{ matrix.arch }}'
if command -v sha256sum > /dev/null; then (cd out && sha256sum -c SHA256SUMS)
else (cd out && shasum -a 256 -c SHA256SUMS); fi
failed=0
for t in out/"$a"/*_test.oke; do
echo "::group::$t"
if "$OKRUN" "$t"; then echo " ok $t"; else echo "::error::$t"; failed=1; fi
echo "::endgroup::"
done
exit $failed
# ── EMSCRIPTEN (`wasm32-emscripten`) ────────────────────────────────────────
#
# A wasm module over Emscripten's C library and openkal-emscripten, run under
# node. The toolchain is the target's (emsdk 6.0.9) and the runner is node
# from the payload's descriptor. openkal-emscripten has no openkal.process, so
# the two suites that start programs are not built; that a program which
# starts one fails at link, naming the symbol, is asserted instead.
emscripten:
name: emscripten (node) ${{ matrix.profile }}
runs-on: ubuntu-24.04
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
profile: [dev, release]
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v4
- name: Install xlings and mcpp
run: |
curl -fsSL https://raw.githubusercontent.com/openxlings/xlings/main/tools/other/quick_install.sh \
| bash -s "$XLINGS_VERSION"
echo "$HOME/.xlings/subos/current/bin" >> "$GITHUB_PATH"
export PATH="$HOME/.xlings/subos/current/bin:$PATH"
# The configured mirror (GLOBAL), then CN (GitCode first) from the fourth attempt: a cached index
# can predate the release, and xlings keeps it when an anonymous refresh fails.
for attempt in 1 2 3 4 5 6; do
[ "$attempt" = 4 ] && { xlings config --mirror CN > /dev/null 2>&1 || true; }
xlings update > /dev/null 2>&1 || true
if xlings install "$MCPP_INSTALL" -y -g; then break; fi
[ "$attempt" = 6 ] && { echo "::error::mcpp could not be installed"; exit 1; }
sleep 60
done
mcpp --version
mcpp self config --mirror GLOBAL
if [ -n "${MCPP_SOURCE_REF:-}" ]; then
src="$RUNNER_TEMP/mcpp-src"
git clone --quiet --depth 1 --branch "$MCPP_SOURCE_REF" https://github.com/mcpp-community/mcpp.git "$src"
rm -f "$src/.xlings.json"
# mcpp's own build is not this job's target: MCPP_PLATFORM names the
# platform of the os package's images, and mcpp's graph is another.
( cd "$src" && env -u MCPP_PLATFORM mcpp build --release )
built=$(find "$src/target" -type f -name mcpp | head -1)
[ -n "$built" ] || { echo "::error::mcpp did not build"; exit 1; }
echo "$(cd "$(dirname "$built")" && pwd)" >> "$GITHUB_PATH"
fi
- name: Every test of the package that starts no program has its counterpart here
run: |
for t in tests/*_test.cpp; do
n=$(basename "$t")
case "$n" in process_test.cpp|ipc_test.cpp|unit_test.cpp) continue ;; esac
[ -f "checks/emscripten/tests/$n" ] || { echo "::error::checks/emscripten/tests has no $n"; exit 1; }
done
- name: Tests, under node
working-directory: checks/emscripten
run: |
set -euo pipefail
mcpp test --target wasm32-emscripten --profile '${{ matrix.profile }}' 2>&1 | tee tests.log
for name in platform_test fs_test dirs_terminal_test linux_test library_test watch_test windows_test macos_test; do
grep -q "^$name \.\.\. ok" tests.log || { echo "::error::$name did not run or did not pass"; exit 1; }
done
- name: The compile-time constants of Emscripten (R3)
run: ( cd checks/constants && mcpp build --target wasm32-emscripten ) || { echo "::error::a constant does not hold"; exit 1; }
- name: A program that names itself fails at link, naming the openkal symbol
run: |
if ( cd checks/absent && mcpp build --target wasm32-emscripten ) > absent.log 2>&1; then
cat absent.log
echo "::error::a program using openkal.process linked for Emscripten"
exit 1
fi
grep -E "^(error|wasm-ld)" absent.log | head -5
grep -q "undefined symbol: kal_process_" absent.log \
|| { cat absent.log; echo "::error::the build did not fail naming an openkal.process symbol"; exit 1; }
echo " ok the link names the symbol this platform does not have"