Skip to content

Commit c75fa83

Browse files
committed
probe: strip to a single Windows job pinned to the instrumented mcpp
Only the workspace job survives, only its Windows matrix entry, and only the ffmpeg member — everything else here is noise while chasing the 127. The pin is mcpp's throwaway prerelease v0.0.107-dbg, built from branch debug/win127-instrumentation, which traces every ninja argv and every Windows popen command string from inside the process.
1 parent 4b5df6e commit c75fa83

1 file changed

Lines changed: 6 additions & 228 deletions

File tree

.github/workflows/validate.yml

Lines changed: 6 additions & 228 deletions
Original file line numberDiff line numberDiff line change
@@ -60,151 +60,6 @@ env:
6060
MCPP_VERSION: "0.0.107"
6161

6262
jobs:
63-
lint:
64-
runs-on: ubuntu-latest
65-
steps:
66-
- uses: actions/checkout@v4
67-
- name: Install lua
68-
run: sudo apt-get install -y --no-install-recommends lua5.4
69-
- name: Lint package descriptors
70-
run: |
71-
fail=0
72-
for f in pkgs/*/*.lua; do
73-
# 1. Lua syntax check — load (= compile) without executing.
74-
# `loadfile(name, 't')` rejects bytecode and parses text only.
75-
if ! lua5.4 -e "assert(loadfile('$f', 't'))" >/dev/null 2>&1; then
76-
echo "::error file=$f::lua syntax error"
77-
fail=1
78-
fi
79-
# 2. xpkg V1 baseline: the file has to populate `package = { ... }`
80-
# with at least `spec`, `name`, and an `xpm` table. Form A vs
81-
# Form B (mcpp = "<path>" / mcpp = { ... }) is descriptor-author
82-
# choice and not enforced here.
83-
for needle in 'spec *=' 'name *=' 'xpm *='; do
84-
if ! grep -q "$needle" "$f"; then
85-
echo "::error file=$f::missing required field ($needle)"
86-
fail=1
87-
fi
88-
done
89-
# 3. Package version identifiers and dependency versions should be
90-
# bare versions ("1.2.3"), not upstream tag names ("v1.2.3").
91-
# Download URLs may still contain refs/tags/v* when upstream
92-
# uses that tag spelling.
93-
if grep -nE '\["v[0-9]+|\["[^"]+"\][[:space:]]*=[[:space:]]*"v[0-9]+' "$f"; then
94-
echo "::error file=$f::version identifiers must not use a leading v"
95-
fail=1
96-
fi
97-
# 4. Mirror table sanity: when a download `url` is written as a
98-
# { GLOBAL=..., CN=... } table, both regions must be present and
99-
# the CN entry must point at the gitcode mcpp-res mirror.
100-
if ! lua5.4 tests/check_mirror_urls.lua "$f"; then
101-
fail=1
102-
fi
103-
# 5. `name` must be a SINGLE ATOMIC SEGMENT; hierarchy belongs in
104-
# `namespace` (mcpp SPEC-001 §3.2). The legacy fully-qualified
105-
# spelling stays accepted. Cheap second gate: it runs before the
106-
# pinned mcpp is even downloaded, and mcpp >= 0.0.106 enforces
107-
# the same rule inside `mcpp xpkg parse`.
108-
if ! lua5.4 tests/check_package_name.lua "$f"; then
109-
fail=1
110-
fi
111-
# 6. c++fly admission policy (mcpp design 2026-07-14 §11-Q2, v1):
112-
# c++fly means "toolchain's latest level + every experimental
113-
# gate" — deliberately toolchain-dependent, so a published
114-
# package built with it is not reproducible for consumers.
115-
# Policy: WARN (never fail) and observe ecosystem usage before
116-
# deciding whether to tighten. Two spellings: `language = ` is
117-
# the descriptor's inline mcpp-segment key; `standard = ` covers
118-
# mcpp.toml content embedded in heredoc/generated_files blocks.
119-
if grep -nE '\b(language|standard)[[:space:]]*=[[:space:]]*"c\+\+fly"' "$f" >/dev/null; then
120-
echo "::warning file=$f::declares C++ standard \"c++fly\" (experimental playground mode) — toolchain-dependent and non-reproducible for consumers; published packages should pin a concrete standard (c++23/c++26)"
121-
fi
122-
done
123-
[ $fail -eq 0 ] && echo "All package files valid."
124-
exit $fail
125-
# ── Whole-repository check (needs every descriptor at once) ──────
126-
# An install() hook addressing a sibling package does so by
127-
# `<namespace>:<literal package.name>`, and a miss returns nil rather
128-
# than raising — so a stale spelling surfaces far downstream (a broken
129-
# libxcb showed up as a libX11 link error). Verified across the repo
130-
# because it needs the full set of declared identities.
131-
- name: Lint cross-package references
132-
run: lua5.4 tests/check_cross_package_refs.lua pkgs/*/*.lua
133-
# ── Single-source-of-truth grammar check ─────────────────────────
134-
# `mcpp xpkg parse` uses EXACTLY the resolver's parser, so what
135-
# passes here is what builds for users of the pinned MCPP_VERSION.
136-
# Strict by default: unknown mcpp-segment keys fail (they would be
137-
# silently ignored at build time). This also mechanically enforces
138-
# the rollout rule "floor first, new grammar after": descriptors
139-
# needing a newer grammar cannot pass a lint pinned to an older mcpp.
140-
- name: Download pinned mcpp
141-
run: |
142-
curl -L -fsS -o mcpp.tar.gz \
143-
"https://github.com/mcpp-community/mcpp/releases/download/v${MCPP_VERSION}/mcpp-${MCPP_VERSION}-linux-x86_64.tar.gz"
144-
tar -xzf mcpp.tar.gz
145-
echo "MCPP=$PWD/mcpp-${MCPP_VERSION}-linux-x86_64/bin/mcpp" >> "$GITHUB_ENV"
146-
- name: Parse descriptors with the resolver grammar (mcpp xpkg parse)
147-
run: |
148-
fail=0
149-
for f in pkgs/*/*.lua; do
150-
if ! "$MCPP" xpkg parse "$f" > /dev/null; then
151-
echo "::error file=$f::mcpp xpkg parse failed (resolver grammar)"
152-
fail=1
153-
fi
154-
done
155-
[ $fail -eq 0 ] && echo "All descriptors parse with mcpp ${MCPP_VERSION}."
156-
exit $fail
157-
158-
mirror-cn-reachable:
159-
# Closed-loop guard for the CN mirror: every CN url referenced by a
160-
# descriptor must be a live, downloadable gitcode release asset.
161-
runs-on: ubuntu-latest
162-
steps:
163-
- uses: actions/checkout@v4
164-
- name: Install lua
165-
run: sudo apt-get install -y --no-install-recommends lua5.4
166-
- name: Check CN mirror assets are reachable
167-
run: |
168-
fail=0
169-
# collect unique CN urls across all descriptors
170-
: > /tmp/cn.tsv
171-
for f in pkgs/*/*.lua; do
172-
lua5.4 tests/list_cn_urls.lua "$f" >> /tmp/cn.tsv || true
173-
done
174-
sort -u /tmp/cn.tsv -o /tmp/cn.tsv
175-
total=$(grep -c . /tmp/cn.tsv || true)
176-
echo "checking $total CN mirror url(s)"
177-
while IFS=$'\t' read -r url sha; do
178-
[ -z "$url" ] && continue
179-
# follow redirects; gitcode release assets resolve to object storage
180-
code=$(curl -fsSL -o /dev/null -w '%{http_code}' --retry 2 --max-time 60 "$url" || echo "000")
181-
if [ "$code" != "200" ]; then
182-
echo "::error::CN mirror unreachable ($code): $url"
183-
fail=1
184-
else
185-
echo "ok: $url"
186-
fi
187-
done < /tmp/cn.tsv
188-
[ $fail -eq 0 ] && echo "All CN mirror urls reachable."
189-
exit $fail
190-
191-
# ── The whole test surface, as a mcpp workspace ───────────────────────
192-
# mcpp-index is a mcpp [workspace]; every per-library test project under
193-
# tests/examples/ is a member. `mcpp test --workspace` builds + runs each
194-
# member's tests/ (behavioral assertions) on each OS — members self-gate by
195-
# `[target.'cfg(...)']` (e.g. the X11/glfw stack is linux-only, openblas is
196-
# windows-only), so one command covers the matrix with no shell driver.
197-
# The ~/.mcpp/registry cache carries the built compat packages (xpkgs) across
198-
# runs, so repeat builds are fast.
199-
#
200-
# timeout-minutes is sized for the COLD build, not the cached path. The opencv
201-
# module package carries a from-source OpenCV 5 build, and each feature variant
202-
# re-keys the store into a full recompile, so a full run (forced whenever this
203-
# workflow file changes — e.g. a version bump) serially builds three OpenCV
204-
# variants on one runner: the opencv-module base member plus the `unifont` and
205-
# `dnn` feature members. The registry cache (restore-keys prefix below)
206-
# amortizes those across subsequent runs. 150 covers the one-time cold full
207-
# build with headroom; it is a ceiling, not a target.
20863
workspace:
20964
name: workspace (${{ matrix.platform }})
21065
runs-on: ${{ matrix.os }}
@@ -213,30 +68,16 @@ jobs:
21368
fail-fast: false
21469
matrix:
21570
include:
216-
# Archive names are derived from env.MCPP_VERSION in the Download
217-
# step — bumping the pin is a ONE-line change (hardcoded versions
218-
# here once 404'd a pin bump).
219-
- platform: linux
220-
os: ubuntu-latest
221-
suffix: linux-x86_64
222-
ext: tar.gz
223-
mcpp: bin/mcpp
224-
xlings: registry/bin/xlings
225-
mcpp_version: "0.0.107" # keep in sync with env.MCPP_VERSION
226-
- platform: macos
227-
os: macos-15
228-
suffix: macosx-arm64
229-
ext: tar.gz
230-
mcpp: bin/mcpp
231-
xlings: registry/bin/xlings
232-
mcpp_version: "0.0.107" # keep in sync with env.MCPP_VERSION
71+
# PROBE: only Windows, and pinned to the instrumented debug build
72+
# published by mcpp's debug-win workflow (branch
73+
# debug/win127-instrumentation, prerelease tag v0.0.107-dbg).
23374
- platform: windows
23475
os: windows-latest
23576
suffix: windows-x86_64
23677
ext: zip
23778
mcpp: bin/mcpp.exe
23879
xlings: registry/bin/xlings.exe
239-
mcpp_version: "0.0.107" # keep in sync with env.MCPP_VERSION
80+
mcpp_version: "0.0.107-dbg"
24081
env:
24182
MCPP_EFFECTIVE: ${{ matrix.mcpp_version }}
24283
steps:
@@ -360,71 +201,8 @@ jobs:
360201
MCPP_INDEX_MIRROR: GLOBAL
361202
run: |
362203
"$MCPP" --version
363-
# PROBE (do not merge): the Windows job dies with a bare 127 the
364-
# instant compat:ffmpeg finishes downloading, printing nothing. Run
365-
# that one member on its own, keep the shell alive past the failure,
366-
# and record the exit status plus free disk on either side.
367-
echo "=== free space before ==="; df -h . || true
204+
echo "=== ffmpeg member, instrumented ==="
368205
rc=0
369-
"$MCPP" test -p tests/examples/ffmpeg || rc=$?
206+
"$MCPP" test -p tests/examples/ffmpeg 2>&1 | tail -120 || rc=$?
370207
echo "=== ffmpeg member exit status: $rc ==="
371-
echo "=== free space after ==="; df -h . || true
372-
# mcpp returns the xlings child's exit code, so 127 may well be
373-
# xlings'. Drive xlings directly on the same package and show what it
374-
# says — mcpp swallows the child's stderr on this path.
375-
# MCPP_VERBOSE=1 prints the exact xlings invocation (xlings.cppm:923).
376-
# This path otherwise swallows the child's stderr, which is why the
377-
# 127 arrives with no output at all.
378-
echo "=== retry under MCPP_VERBOSE ==="
379-
vrc=0
380-
MCPP_VERBOSE=1 "$MCPP" test -p tests/examples/ffmpeg 2>&1 | tail -60 || vrc=$?
381-
echo "=== verbose retry exit status: $vrc ==="
382-
# Third attempt. The two before this failed on my own path mistakes
383-
# (a relative ninja path, then looking under $HOME instead of the
384-
# extracted release, which is the registry mcpp actually uses). List
385-
# every candidate this time and require an absolute one.
386-
echo "=== ninja candidates ==="
387-
find "$PWD" "$HOME" -name 'ninja.exe' 2>/dev/null | head -5
388-
NJ=$(find "$PWD" "$HOME" -name 'ninja.exe' 2>/dev/null | head -1)
389-
BN=$(find "$PWD/tests/examples/ffmpeg/target" -maxdepth 3 -name build.ninja 2>/dev/null | head -1)
390-
echo "build.ninja: $BN"
391-
echo "ninja: $NJ"
392-
# cmd.exe caps a command line at 8191 chars and ninja spawns through
393-
# it. ffmpeg is the only member big enough for that to bite, so
394-
# measure rather than assume.
395-
if [ -n "$BN" ]; then
396-
echo "=== build.ninja size / longest line ==="
397-
wc -c "$BN"
398-
awk '{ if (length($0) > m) { m = length($0); ml = NR } } END { print "longest line: " m " chars (line " ml ")" }' "$BN"
399-
fi
400-
if [ -n "$BN" ] && [ -n "$NJ" ]; then
401-
"$NJ" --version || echo "(ninja --version failed rc=$?)"
402-
nrc=0
403-
"$NJ" -C "$(dirname "$BN")" -j2 2>&1 | tail -40 || nrc=$?
404-
echo "=== manual ninja exit status: $nrc ==="
405-
fi
406-
echo "=== locating xlings ==="
407-
XL=$(find . "$HOME" -name 'xlings.exe' -path '*registry/bin*' 2>/dev/null | head -1)
408-
echo "xlings: $XL"
409-
if [ -n "$XL" ]; then
410-
"$XL" --version || true
411-
xrc=0
412-
"$XL" install "compat:ffmpeg@8.1.2" -y || xrc=$?
413-
echo "=== xlings direct exit status: $xrc ==="
414-
fi
415208
exit $rc
416-
# No `timeout` wrapper: absent on macOS runners; job-level timeout-minutes bounds it.
417-
if [ "$MEMBERS" = "__ALL__" ]; then
418-
"$MCPP" test --workspace
419-
elif [ -z "$MEMBERS" ]; then
420-
echo "No workspace member affected by this change — nothing to test."
421-
else
422-
rc=0
423-
for m in $MEMBERS; do
424-
echo "::group::mcpp test -p $m"
425-
"$MCPP" test -p "$m" || rc=1
426-
echo "::endgroup::"
427-
done
428-
exit $rc
429-
fi
430-

0 commit comments

Comments
 (0)