-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
320 lines (307 loc) · 14.3 KB
/
Copy pathmacos_ci.yml
File metadata and controls
320 lines (307 loc) · 14.3 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
name: CI macOS
on:
workflow_dispatch:
push:
branches:
- master
paths-ignore:
# vlib/v3/** is intentionally NOT ignored: V3 is the default compiler on
# macOS, so changes to it must run this suite (with the fallback disabled).
- '**.md'
- '**.yml'
- '!**/macos_ci.yml'
- 'cmd/tools/**'
- '!cmd/tools/builders/**.v'
pull_request:
paths-ignore:
# vlib/v3/** is intentionally NOT ignored: V3 is the default compiler on
# macOS, so changes to it must run this suite (with the fallback disabled).
- '**.md'
- '**.yml'
- '!**/macos_ci.yml'
- 'cmd/tools/**'
- '!cmd/tools/builders/**.v'
concurrency:
group: macos-${{ github.workflow }}-${{ github.ref == 'refs/heads/master' && github.sha || github.ref }}
cancel-in-progress: true
jobs:
clang-macos:
strategy:
matrix:
# V3 (vlib/v3, `-new-compiler`) is the default compiler on macOS, so
# exercise it on every arm64 (Apple-silicon) runner image, not just one.
os: [macos-14, macos-15, macos-26]
fail-fast: false
runs-on: ${{ matrix.os }}
timeout-minutes: 151
env:
VFLAGS: -cc clang
VTEST_SHOW_LONGEST_BY_RUNTIME: 3
VTEST_SHOW_LONGEST_BY_COMPTIME: 3
VTEST_SHOW_LONGEST_BY_TOTALTIME: 3
# V3 is the default compiler on macOS; disable the V3->V1 fallback for every
# eligible V3 build so a regression fails CI directly. The `.vsh` runner is
# intentionally compiled by V1; the canary below verifies V3 dispatch itself.
V_MACOS_V3_NO_FALLBACK: 1
steps:
- uses: actions/checkout@v7.0.1
- name: Cache Homebrew downloads
uses: actions/cache@v6
with:
path: ~/Library/Caches/Homebrew
key: brew-${{ matrix.os }}-${{ hashFiles('.github/workflows/macos_ci.yml', 'ci/macos_ci.vsh') }}
restore-keys: |
brew-${{ matrix.os }}-
- name: Build V
# `make` runs bootstrap helpers before the V3 canary; `.vsh` helpers intentionally
# use V1, and other helpers may need the compatibility fallback. Clear the guard
# for this bootstrap step; later eligible builds and the canary retain it.
env:
V_MACOS_V3_NO_FALLBACK: 0
run: make -j4 && ./v symlink
- name: Assert V3 is the default compiler (fail if V1 is silently used)
run: |
set -uo pipefail
printf 'fn main() { println(6 * 7) }\n' > "$RUNNER_TEMP/v3_canary.v"
V_MACOS_V3_NO_FALLBACK=1 ./v -v run "$RUNNER_TEMP/v3_canary.v" > "$RUNNER_TEMP/v3_canary.out" 2>&1 || true
cat "$RUNNER_TEMP/v3_canary.out"
grep -q 'V3 compiler in process' "$RUNNER_TEMP/v3_canary.out" || { echo '::error::V3 was NOT dispatched on macOS — the program was compiled by V1'; exit 1; }
grep -qx '42' "$RUNNER_TEMP/v3_canary.out" || { echo '::error::the V3-compiled canary did not build/run correctly'; exit 1; }
if grep -qiE 'retrying with .-old-compiler|compatibility fallback|used the stable compiler' "$RUNNER_TEMP/v3_canary.out"; then echo '::error::V3 silently fell back to V1'; exit 1; fi
echo 'OK: V3 compiled and ran this program in-process on macOS, with the fallback disabled'
- name: Pkg-config regressions (Clang, no static executable)
run: |
set -euo pipefail
for test in \
vlib/v/pkgconfig/pkgconfig_static_test.v \
vlib/v/checker/pkgconfig_static_mode_test.v \
vlib/v/checker/pkgconfig_cross_compile_test.v \
vlib/v/builder/pkgconfig_link_segment_test.v
do
./v -cc clang -no-retry-compilation test "$test"
done
- name: Legacy gg import multiwindow isolation
run: ./v test vlib/gg/legacy_import_multiwindow_isolation_test.v
- name: Prepare multiwindow process-tree watchdog
run: |
set -euo pipefail
cat > "$RUNNER_TEMP/multiwindow_ci_watchdog.v" <<'EOF'
module main
import gg.testdata.multiwindow_probe_watchdog
import os
import time
fn main() {
run_ci_watchdog() or {
eprintln(err.msg())
exit(1)
}
}
fn run_ci_watchdog() ! {
if os.args.len < 4 {
return error('usage: multiwindow_ci_watchdog timeout-seconds expected-final-line executable [args...]')
}
timeout_seconds := os.args[1].int()
if timeout_seconds <= 0 {
return error('multiwindow CI watchdog timeout must be positive')
}
expected_final_line := os.args[2]
gate_path := os.join_path(os.temp_dir(), 'multiwindow_ci_gate_${os.getpid()}_${time.now().unix_nano()}')
defer {
os.rm(gate_path) or {}
}
result := multiwindow_probe_watchdog.run(
executable: os.args[3]
args: os.args[4..]
timeout: timeout_seconds * time.second
start_file: gate_path
)!
if result.stdout != '' {
print(result.stdout)
}
if result.stderr != '' {
eprint(result.stderr)
}
if result.timed_out {
return error('multiwindow CI child timed out after ${timeout_seconds} seconds')
}
if !result.reaped {
return error('multiwindow CI child leader was not reaped')
}
if !result.confinement_empty {
return error('multiwindow CI child process confinement is not empty')
}
if result.forced_cleanup {
return error('multiwindow CI child required forced cleanup')
}
if result.exit_code != 0 {
return error('multiwindow CI child exited with ${result.exit_code}')
}
if expected_final_line == '-' {
return
}
mut actual_final_line := ''
for line in result.stdout.split_into_lines() {
if line.trim_space() != '' {
actual_final_line = line.trim_space()
}
}
if actual_final_line != expected_final_line {
return error('multiwindow CI final record mismatch: expected `${expected_final_line}`, got `${actual_final_line}`')
}
}
EOF
./v -cc clang -o "$RUNNER_TEMP/multiwindow_ci_watchdog" "$RUNNER_TEMP/multiwindow_ci_watchdog.v"
- name: Native operation proof (explicit V1 compatibility gate)
env:
V_MACOS_V3_NO_FALLBACK: '1'
VGG_MULTIWINDOW_RUNTIME_PROBES: '1'
VGG_MULTIWINDOW_RUNTIME_BACKEND: appkit
VGG_MULTIWINDOW_EXAMPLE_UNATTENDED: appkit
V_MULTIWINDOW_PROBE_BACKEND: appkit
run: |
set -euo pipefail
source='vlib/x/multiwindow/native_operation_proof_test.v'
expected_source_sha256='429cbaf1ce2c2cda26c4b9a421f62997e85bc57e210e49062daded89a2a95667'
if [[ "${VFLAGS:-}" != '-cc clang' ]]; then
echo "native operation V1 compatibility gate VFLAGS mismatch" >&2
exit 1
fi
if [[ ! -s "$source" ]]; then
echo "native operation V1 compatibility gate source is missing or empty" >&2
exit 1
fi
actual_source_sha256="$(shasum -a 256 "$source" | awk '{print $1}')"
if [[ "$actual_source_sha256" != "$expected_source_sha256" ]]; then
echo "native operation V1 compatibility gate source hash mismatch" >&2
exit 1
fi
source_test_count="$(grep -Ec '^fn test_[A-Za-z0-9_]+\(\) \{$' "$source")"
if [[ "$source_test_count" != '53' ]]; then
echo "native operation V1 compatibility gate source test count mismatch" >&2
exit 1
fi
if [[ -n "${V_MACOS_V3_RETRY:-}" \
|| -n "${V_MACOS_V3_FALLBACK_FILE:-}" \
|| -n "${V_MACOS_V3_C_ERROR_DIR:-}" \
|| -n "${VTEST_ONLY:-}" \
|| -n "${VTEST_ONLY_FN:-}" \
|| -n "${VTEST_RUNNER:-}" \
|| -n "${V_MULTIWINDOW_NATIVE_PROOF_EGL_BAD_DISPLAY_CHILD:-}" \
|| -n "${V_MULTIWINDOW_NATIVE_PROOF_APPKIT_ORDINAL_EXHAUSTION_CHILD:-}" ]]; then
echo "native operation V1 compatibility gate inherited selector mismatch" >&2
exit 1
fi
"$RUNNER_TEMP/multiwindow_ci_watchdog" 300 - \
./v -old-compiler -no-retry-compilation -cc clang \
-d gg_multiwindow -d sokol_metal test "$source"
printf 'MULTIWINDOW_MACOS_NATIVE_OPERATION_PROOF status=PASS route=V1_COMPAT sha256=%s tests=%s\n' \
"$actual_source_sha256" "$source_test_count"
- name: Multiwindow Metal regressions and runtime probes
# Some multiwindow tests still exercise V3-incompatible constructs. The
# direct canary above remains strict; this lane also verifies fallback.
env:
V_MACOS_V3_NO_FALLBACK: 0
VGG_MULTIWINDOW_RUNTIME_PROBES: '1'
VGG_MULTIWINDOW_RUNTIME_BACKEND: appkit
VGG_MULTIWINDOW_EXAMPLE_UNATTENDED: appkit
V_MULTIWINDOW_PROBE_BACKEND: appkit
run: |
set -euo pipefail
./v -cc clang -d gg_multiwindow -d sokol_metal \
-o /tmp/gg_multiwindow_metal examples/gg/multiwindow.v
./v -cc clang -d gg_multiwindow -d sokol_metal \
-o /tmp/gg_multiwindow_render_runtime_metal examples/gg/multiwindow_render_runtime.v
tests=(
vlib/x/multiwindow/event_sequence_exhaustion_test.v
vlib/x/multiwindow/event_terminal_delivery_test.v
vlib/x/multiwindow/internal_fault_matrix_test.v
vlib/x/multiwindow/multiwindow_test.v
vlib/x/multiwindow/render_scheduler_test.v
vlib/x/multiwindow/render_target_lease_test.v
vlib/x/multiwindow/service_mock_test.v
vlib/x/multiwindow/service_native_appkit_contract_red_test.v
vlib/x/multiwindow/service_native_appkit_final_nonreadback_red_test.v
vlib/x/multiwindow/service_native_appkit_nonreadback_test.v
vlib/x/multiwindow/service_native_appkit_readback_metal_red_test.v
vlib/x/multiwindow/teardown_contract_test.v
vlib/sokol/gfx/metal_private_hook_contract_test.v
vlib/gg/multiwindow_api_d_gg_multiwindow_test.v
vlib/gg/multiwindow_appkit_readback_d_gg_multiwindow_test.v
vlib/gg/multiwindow_buffer_cleanup_d_gg_multiwindow_test.v
vlib/gg/multiwindow_render_fault_matrix_d_gg_multiwindow_test.v
vlib/gg/multiwindow_render_runtime_contract_test.v
vlib/gg/frame_pacing_test.v
vlib/gg/draw_fns_api_test.v
vlib/gg/draw_rect_empty_test.v
)
native_operation_proof='vlib/x/multiwindow/native_operation_proof_test.v'
if [[ "${#tests[@]}" -ne 21 ]]; then
echo "multiwindow Metal test inventory cardinality mismatch" >&2
exit 1
fi
for test in "${tests[@]}"; do
if [[ "$test" == "$native_operation_proof" ]]; then
echo "native operation proof leaked into the strict V3 Metal inventory" >&2
exit 1
fi
done
for test in "${tests[@]}"; do
"$RUNNER_TEMP/multiwindow_ci_watchdog" 300 - \
./v -cc clang -d gg_multiwindow -d sokol_metal test "$test"
done
"$RUNNER_TEMP/multiwindow_ci_watchdog" 300 - \
./v -cc clang test vlib/gg/multiwindow_services_contract_test.v
"$RUNNER_TEMP/multiwindow_ci_watchdog" 120 \
'{"example":"multiwindow_render_runtime","status":"PASS","cleanup":"complete"}' \
/tmp/gg_multiwindow_render_runtime_metal
"$RUNNER_TEMP/multiwindow_ci_watchdog" 120 \
'{"example":"multiwindow","status":"PASS","cleanup":"complete"}' \
/tmp/gg_multiwindow_metal
- name: Test AppKit GLCore rejection guard
run: ./v -d gg_multiwindow -d darwin_sokol_glcore33 test vlib/x/multiwindow/multiwindow_test.v
- name: Test symlink
run: v run ci/macos_ci.vsh test_symlink
- name: v doctor
run: v run ci/macos_ci.vsh v_doctor
- name: Build v with -prealloc
run: v run ci/macos_ci.vsh build_v_with_prealloc
- name: Test cross compilation to Linux
run: v run ci/macos_ci.vsh test_cross_compilation
- name: Test inline assembly on macos
run: v run ci/macos_ci.vsh test_inline_assembly
- name: Build V with -cstrict
run: v run ci/macos_ci.vsh build_with_cstrict
- name: All code is formatted
run: v run ci/macos_ci.vsh all_code_is_formatted
- name: Run sanitizers
run: v run ci/macos_ci.vsh run_sanitizers
- name: Build V using V
run: v run ci/macos_ci.vsh build_using_v
- name: Verify `v test` works
run: v run ci/macos_ci.vsh verify_v_test_works
- name: Install iconv for encoding.iconv
run: v run ci/macos_ci.vsh install_iconv
- name: Test pure V math module
run: v run ci/macos_ci.vsh test_pure_v_math_module
- name: Self tests
run: v run ci/macos_ci.vsh self_tests
- name: Build examples
run: v run ci/macos_ci.vsh build_examples
- name: Build hello_world with -autofree
run: v run ci/macos_ci.vsh build_hello_world_autofree
- name: Build tetris with -autofree
run: v run ci/macos_ci.vsh build_tetris_autofree
- name: Build blog tutorial with -autofree
run: v run ci/macos_ci.vsh build_blog_autofree
- name: Build examples with -prod
run: v run ci/macos_ci.vsh build_examples_prod
- name: Build examples with V build with tcc
run: v run ci/macos_ci.vsh build_examples_v_compiled_with_tcc
## - name: V self compilation with -usecache
## run: v run ci/macos_ci.vsh v_self_compilation_usecache
- name: V self compilation with -parallel-cc
run: v run ci/macos_ci.vsh v_self_compilation_parallel_cc
- name: Test password input
run: v run ci/macos_ci.vsh test_password_input
- name: Test readline
run: v run ci/macos_ci.vsh test_readline