55 branches : [thirdparty-macos-arm64]
66 pull_request :
77 branches : [thirdparty-macos-arm64]
8- workflow_dispatch : {}
8+
9+ permissions :
10+ contents : read
11+
12+ env :
13+ CONTRACT_REPOSITORY : vlang/v
14+ CONTRACT_SHA : 7545e515b434cd399333d43659238427d72e22e7
15+ VC_SHA : dfc458a13ba8923ebc249e262c331f8169aa728b
16+ PUBLISH : ' false'
17+ TCCBIN_PUBLISH : ' false'
918
1019concurrency :
1120 group : build-and-test-macos-arm64-${{ github.ref }}
1221 cancel-in-progress : true
1322
1423jobs :
1524 build :
25+ if : >-
26+ github.repository == 'vlang/tccbin' &&
27+ (
28+ (github.event_name == 'pull_request' &&
29+ github.base_ref == 'thirdparty-macos-arm64') ||
30+ (github.event_name == 'push' &&
31+ github.ref == 'refs/heads/thirdparty-macos-arm64')
32+ )
1633 runs-on : macos-15
1734 timeout-minutes : 30
1835 steps :
@@ -26,23 +43,59 @@ jobs:
2643 # this branch reuses its own prebuilt libgc.a/libgc.dylib rather
2744 # than compiling thirdparty/libgc/gc.c from source.
2845 - name : checkout v (for thirdparty/libgc and thirdparty/tccbin_tests)
29- uses : actions/checkout@v4
46+ uses : actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
3047 with :
3148 repository : vlang/v
32- ref : c82d3f08271e9324d6fb8de3c251e9c0e1a9154b
33- sparse-checkout : |
34- thirdparty/libgc/include
35- thirdparty/tccbin_tests
36- vlib/v/compiler_errors_test.v
37- sparse-checkout-cone-mode : false
49+ ref : ${{ env.CONTRACT_SHA }}
3850 path : work
51+ fetch-depth : 0
52+ persist-credentials : false
53+
54+ - name : checkout immutable VC bootstrap snapshot
55+ uses : actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
56+ with :
57+ repository : vlang/vc
58+ ref : ${{ env.VC_SHA }}
59+ path : .tccbin-bootstrap-vc
60+ fetch-depth : 0
61+ persist-credentials : false
62+
63+ - name : bootstrap contract-bound validator
64+ shell : bash
65+ run : |
66+ set -euo pipefail
67+ validator_work="$RUNNER_TEMP/tccbin-validator-work"
68+ test ! -e "$validator_work"
69+ git -C work config --local core.autocrlf false
70+ git -C .tccbin-bootstrap-vc config --local core.autocrlf false
71+ work/thirdparty/tccbin_automation/bootstrap/bootstrap.sh \
72+ "$GITHUB_WORKSPACE/work" "$CONTRACT_REPOSITORY" "$CONTRACT_SHA" \
73+ "$GITHUB_WORKSPACE/.tccbin-bootstrap-vc" "$validator_work"
74+ {
75+ echo "TCCBIN_VALIDATOR_CLI=$validator_work/tccbin-automation"
76+ echo "TCCBIN_VALIDATOR_CONTRACT_ROOT=$validator_work/contract-source"
77+ } >> "$GITHUB_ENV"
3978
4079 # this branch, checked out where build.sh expects to find itself
4180 # (work/thirdparty/tcc), matching a normal local checkout layout.
4281 - name : checkout this branch
43- uses : actions/checkout@v4
82+ uses : actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
4483 with :
84+ ref : ${{ github.sha }}
4585 path : work/thirdparty/tcc
86+ fetch-depth : 0
87+ persist-credentials : false
88+
89+ - name : validate baseline manifest and immutable contract binding
90+ shell : bash
91+ run : |
92+ set -euo pipefail
93+ git -C work/thirdparty/tcc config --local core.autocrlf false
94+ bash work/thirdparty/tcc/automation/probes/baseline-contract.sh \
95+ "$TCCBIN_VALIDATOR_CLI" "$TCCBIN_VALIDATOR_CONTRACT_ROOT" \
96+ "$GITHUB_WORKSPACE/work/thirdparty/tcc" macos-arm64 \
97+ thirdparty-macos-arm64 "$CONTRACT_SHA" "$GITHUB_SHA" \
98+ "$GITHUB_WORKSPACE/.tccbin-bootstrap-vc"
4699
47100 # This branch DISTRIBUTES the checked-in tcc.exe/libgc.a/libgc.dylib
48101 # directly - that's what V's own builder and anyone else using this
@@ -195,40 +248,88 @@ jobs:
195248 if [ "$code" -eq 0 ]; then
196249 echo "::error::Static libgc.a linking now succeeds on macOS arm64 - this lane's special-casing should be removed and folded back into a single blocking lane, this workaround is no longer needed."
197250 exit 1
251+ elif [ "$code" -ne 1 ]; then
252+ echo "::error::Static libgc.a XFAIL returned exit $code; expected TCC compile-error exit 1 exactly."
253+ exit 1
198254 fi
199255
256+ set +e
257+ direct_err_gc_alloc=$(thirdparty/tcc/tcc.exe thirdparty/tccbin_tests/shared/gc_alloc.c \
258+ -DGC_BUILTIN_ATOMIC=1 \
259+ -DGC_THREADS=1 \
260+ -DMPROTECT_VDB=1 \
261+ -I thirdparty/libgc/include \
262+ "$PWD/thirdparty/tcc/lib/libgc.a" \
263+ -ldl -lpthread \
264+ -o /tmp/gc_alloc_arm64_xfail_probe 2>&1)
265+ direct_code_gc_alloc=$?
266+ direct_err_hello=$(thirdparty/tcc/tcc.exe thirdparty/tccbin_tests/shared/hello.c \
267+ -DGC_BUILTIN_ATOMIC=1 \
268+ -DGC_THREADS=1 \
269+ -DMPROTECT_VDB=1 \
270+ -I thirdparty/libgc/include \
271+ "$PWD/thirdparty/tcc/lib/libgc.a" \
272+ -ldl -lpthread \
273+ -o /tmp/hello_arm64_xfail_probe 2>&1)
274+ direct_code_hello=$?
275+ set -e
276+
277+ is_known_gc_init() {
278+ # TCC's compile-error exit is exactly 1. Every nonempty stderr
279+ # line must be one complete unresolved GC_* diagnostic; require
280+ # GC_init specifically so an unrelated missing symbol cannot
281+ # masquerade as the known archive-parsing limitation.
282+ if [ "$2" -ne 1 ]; then
283+ return 1
284+ fi
285+ stderr_lines=$(printf '%s\n' "$1" | sed '/^$/d')
286+ [ -n "$stderr_lines" ] || return 1
287+ unexpected=$(printf '%s\n' "$stderr_lines" | grep -Ev "^tcc: error: unresolved reference to '_?GC_[A-Za-z0-9_]+'$" || true)
288+ [ -z "$unexpected" ] || return 1
289+ printf '%s\n' "$stderr_lines" | grep -E "^tcc: error: unresolved reference to '_?GC_init'$" >/dev/null
290+ }
291+
292+ pass_count=$(printf '%s\n' "$output" | grep -Ec '^PASS ' || true)
293+ fail_count=$(printf '%s\n' "$output" | grep -Ec '^FAIL ' || true)
294+ final_summary=$(printf '%s\n' "$output" | sed '/^$/d' | tail -n 1)
200295 case "$output" in
201- *"PASS crash"*"FAIL gc_alloc (compile error)"*"FAIL hello (compile error)"*)
202- echo "known XFAIL: static libgc.a still can't link gc_alloc/hello, as expected - not blocking CI"
296+ *"PASS crash"*"FAIL gc_alloc (compile error:"*"FAIL hello (compile error:"*)
297+ if [ "$pass_count" -ne 1 ] || [ "$fail_count" -ne 2 ] || [ "$final_summary" != '1 passed, 2 failed' ]; then
298+ echo "::error::Static libgc.a summary counts/final line differ from the exact known XFAIL (PASS=1, FAIL=2, final='1 passed, 2 failed')."
299+ exit 1
300+ fi
301+ if is_known_gc_init "$direct_err_gc_alloc" "$direct_code_gc_alloc" && is_known_gc_init "$direct_err_hello" "$direct_code_hello"; then
302+ echo "known XFAIL: static libgc.a still can't link gc_alloc/hello (unresolved GC_init, the known tcc archive-parsing bug), as expected - not blocking CI"
303+ else
304+ echo "::error::libgc.a lane failed with the known summary shape, but at least one of gc_alloc.c/hello.c's direct compile errors does NOT mention an unresolved GC_init reference (or exited abnormally) - this looks like a different, unexpected regression:"
305+ echo "gc_alloc.c: exit=$direct_code_gc_alloc: $direct_err_gc_alloc"
306+ echo "hello.c: exit=$direct_code_hello: $direct_err_hello"
307+ exit 1
308+ fi
203309 ;;
204310 *)
205311 echo "::error::Static libgc.a lane failed, but NOT with the known/expected signature (PASS crash, FAIL gc_alloc/hello with compile error) - this looks like a different, unexpected problem and should not be silently treated as the known XFAIL."
206312 exit 1
207313 ;;
208314 esac
209315
210- # actions/upload-artifact doesn't preserve executable bits on raw
211- # files (tcc.exe would come back chmod 644 after download), and
212- # hand-listing individual paths already missed lib/libtcc1.a -
213- # which tcc.exe needs at link time just as much as libgc. Archive
214- # the whole rebuilt thirdparty/tcc output instead: tar preserves
215- # modes, and keeping the thirdparty/tcc/ prefix inside the
216- # archive means extracting it anywhere reproduces the exact
217- # relative layout tcc.exe's own baked-in library path expects
218- # (see the comment on the "run shared conformance tests" step
219- # above) - a raw multi-path upload-artifact list would instead
220- # flatten that prefix away.
221- - name : package built tcc for upload
222- # Run even after an earlier failure, so a maintainer debugging
223- # a red run still gets a downloadable build to reproduce
224- # against instead of just a log transcript.
225- if : ${{ !cancelled() }}
226- working-directory : work
227- run : tar --exclude=.git -czf tccbin-macos-arm64-current.tar.gz thirdparty/tcc
228-
229- - name : upload built binaries
230- if : ${{ !cancelled() }}
231- uses : actions/upload-artifact@v4
232- with :
233- name : tccbin-macos-arm64-current
234- path : work/tccbin-macos-arm64-current.tar.gz
316+ tccbin-branch-gate :
317+ name : tccbin-branch-gate
318+ if : >-
319+ always() &&
320+ github.repository == 'vlang/tccbin' &&
321+ (
322+ (github.event_name == 'pull_request' &&
323+ github.base_ref == 'thirdparty-macos-arm64') ||
324+ (github.event_name == 'push' &&
325+ github.ref == 'refs/heads/thirdparty-macos-arm64')
326+ )
327+ needs : [build]
328+ runs-on : ubuntu-latest
329+ timeout-minutes : 5
330+ steps :
331+ - name : require successful baseline validation
332+ shell : bash
333+ env :
334+ BUILD_RESULT : ${{ needs.build.result }}
335+ run : test "$BUILD_RESULT" = success
0 commit comments