Repository navigation
4326 lines (3744 loc) · 249 KB
/
Copy pathbuild-ipa.yml
File metadata and controls
4326 lines (3744 loc) · 249 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
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
name: Build Madeira IPA (unsigned)
on:
workflow_dispatch:
# Paused while builds run on the owner's Mac (2026-10-13). To build on push
# to main again, uncomment the three lines below.
# push:
# branches: [main]
# paths: [".github/workflows/build-ipa.yml"]
# A push and a manual dispatch seconds apart used to start two parallel
# multi-hour macOS jobs on the same commit.
concurrency:
group: build-ipa
cancel-in-progress: true
jobs:
build:
# madeira-bcd: runs only in the owner's repository; a fork's run is skipped.
if: github.repository == 'thebcd69/madeira-bcd'
runs-on: macos-15
# contents: write only so the token can see DRAFT releases, which is where
# the Metal Shader Converter installer is kept (drafts are not public).
# Nothing in this job creates, edits or pushes anything.
permissions:
contents: write
actions: read
timeout-minutes: 360
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
# ContentView.swift uses glassEffect(.regular, in:), which needs the
# iOS 26 SDK. The runner defaults to Xcode 16.4 (iOS 18.5), so pick the
# newest Xcode installed rather than whatever xcode-select points at.
- name: Select newest Xcode
shell: bash
run: |
echo "-- installed Xcodes --"
ls -d /Applications/Xcode*.app 2>/dev/null || echo "(none beyond the default)"
NEWEST=$(ls -d /Applications/Xcode*.app 2>/dev/null | sort -V | tail -1)
if [ -n "$NEWEST" ]; then
sudo xcode-select -s "$NEWEST/Contents/Developer"
echo "::notice::selected $NEWEST"
fi
# madeira-bcd FORK-ONLY: one build-number sequence across GitHub Actions
# and the owner's Mac (owner's decision 2026-10-13). This build's number is
# in docs/local-build/BUILD-NUMBER: the Mac's run.sh, or a cloud session
# before it dispatches this workflow, commits it as "Build N (...)".
# GitHub's own run_number does not follow that sequence, so nothing below
# uses it.
- name: Build number
id: bn
shell: bash
run: |
n=$(grep -v '^#' docs/local-build/BUILD-NUMBER | tr -d '[:space:]')
case "$n" in
''|*[!0-9]*) echo "::error::docs/local-build/BUILD-NUMBER holds no build number"; exit 1 ;;
esac
echo "n=$n" >> "$GITHUB_OUTPUT"
echo "::notice::build $n (GitHub run #${{ github.run_number }})"
- name: Toolchain versions
run: |
xcodebuild -version
xcrun --sdk iphoneos --show-sdk-path
xcrun --sdk iphoneos --show-sdk-version
clang --version
- name: Check generated settings catalog
run: python3 tests/host/check-config-catalog.py
# The preview still compiles every distinct input; identical checks share its successful result.
- name: Check preview build cache correctness
run: python3 tests/host/check-ui-preview-cache.py
# madeira-bcd: the games' built-in recommended settings and where the app
# applies them (GameRecommendations.swift; owner's decision 2026-10-09).
- name: Check built-in recommended game settings
run: python3 tests/host/check-game-recommendations.py --require-swift
# BCD: the recommended settings online (recommended/recommendations.json, signed with
# Ed25519; GameRecommendationsSource.swift): the built-in list equals the Swift literals it
# replaced, signatures, allowed keys, versions, offline and a bad file keep the list in use.
- name: Check online recommended settings
run: python3 tests/host/check-remote-recommendations.py --require-swift
# madeira-bcd: auto-tune (docs/AUTO-TUNE.md): off changes nothing; its hooks, rules,
# fixtures, engine and app side.
- name: Check auto-tune
run: python3 tests/host/check-autotune.py --require-swift
# GTA V Legacy's GPU reset at the first scene frame (tester logs 574-592, the owner's build 546 start): auto-tune
# adds env.MADEIRA_DXMT_FAULT_INFO = 1, the one line the owner's build 547 start differed by, after that failure only.
- name: Check GTA V Legacy GPU reset rule
run: python3 tests/host/check-gta5l-gpu-reset.py
# The Wine desktop's Start menu (BCDStartMenu.c, WineProcessBridge.m): an Explorer entry and a test program for each of
# Direct3D 9, 10, 11 and 12, as shortcut files in the prefix's public Start Menu. The bytes are read back by a port
# of Wine's own shell link loader, by an independent [MS-SHLLINK] reader and by Wine's winedump; the install writes
# only when a file is missing or BCD's own and outdated, never over a person's file, and only in a desktop session.
- name: Check the Start menu entries
run: python3 tests/host/check-bcd-startmenu.py
# BCD's system tests (tests/systests): the RAM test that stops before iOS would close the app (its loop is run against thousands of
# made-up devices), the JIT pool, CPU, system info, VC++ and .NET, disk and network tests, one Windows program for x64 and one
# for the 32-bit set. The program is built with llvm-mingw for both machines and compared with the tracked binaries.
- name: Check the system tests
run: python3 tests/host/check-systests.py
# What those tests are told about the device and the engine (app/Madeira/BCDHostStatus.c, build/ntdll-unix/ios_host_status.h):
# two small files in the prefix, only in the plain Windows desktop session; off, a session behaves as before.
- name: Check the host status for the system tests
run: python3 tests/host/check-host-status.py
- name: Check the desktop session's guest-log mirror for the Start menu tests
run: python3 tests/host/check-desktop-guest-log.py
# BCD's Direct3D 9, 10, 11 and 12 test programs (tests/dxtests, madeira-d3d12/tests/windows/cube_window.c): shaders
# (DXBC made offline from cube.hlsl), sources, window handling, the tracked binaries and where they ship.
- name: Check the DirectX test programs
run: python3 tests/host/check-dx-tests.py
# BCD's graphics, sound, video and input test programs of round 602 (tests/dxtests, the "BCD Tests" Start menu folder): the
# arithmetic of bcdstats.h run on the host against known answers, the two self-made clips (MP4 and ASF structure, decoded on a
# Mac), the sources, the tracked 64-bit and 32-bit binaries rebuilt and compared, and where they ship.
- name: Check the graphics, sound, video and input tests
run: python3 tests/host/check-bcd-tests.py
# 7-Zip in the Start menu (round 603): the pinned release of the project (SHA-256, licence text), the RAR code left out of the
# object lists the build reads from 7-Zip's own makefiles, the two tracked programs (x86-64, imports a Wine session has, no RAR
# code), the notices. BCD_CHECK_7ZIP_BUILD=1 builds both again and compares them with the tracked ones.
- name: Check 7-Zip (pinned source, no RAR code, the tracked programs)
run: python3 tests/host/check-7zip.py
# BCD's runtime installer (bcd-runtimes/, round 603; the "BCD Runtimes" Start menu folder): SHA-256, deflate and ZIP against Python's
# hashlib and zlib, the download rules (HTTPS, one host, redirects by hand), the table of runtimes, the PhysX install from NVIDIA's own
# manifest and the DirectX cabinet reader run on fake disks and registries, the sources and the tracked program.
- name: Check the runtime installer (downloads, checksums, XNA, PhysX, OpenAL, DirectX June 2010)
env:
MINGW: ${{ github.workspace }}/toolchains/llvm-mingw-20260421-ucrt-macos-universal/bin
run: python3 tests/host/check-bcd-runtimes.py
# Opt-in screen orientation lock for a game's session (BCDOrientation.swift): Settings › Graphics and a game's page
# choose "follow the device" (the default, today's behaviour), landscape or a landscape side; the game's own choice wins.
# The rule is run on the host, the UIKit part is type-checked against the iOS SDK, and off is shown to change nothing.
- name: Check the screen orientation lock
run: python3 tests/host/check-bcd-orientation.py
# Experimental support for the foldable iPhone, iPhone Duo (BCDFoldable.swift): runs only on that model (iPhone19,4) with an
# experimental switch on (off by default). The gate is run over 56 other model identifiers, the hooks are listed (one line each),
# the default Resolution for its inner display and the scene-size tracker are run on the host, and the engine side is shown to
# follow only (no orientation or geometry request, nothing paused or restarted). Nothing else in the app changes.
- name: Check the foldable iPhone support
run: python3 tests/host/check-bcd-foldable.py
# A Done button on the keyboard where config lines and long text are typed (BCDKeyboardDone): every editor has one.
- name: Check the keyboard's Done button
run: python3 tests/host/check-bcd-keyboard-done.py
# What the classic interface did for a person, kept in BCD's (parity audit, 2026-10-18):
# its alerts reach BCD's interface, background downloads, the Downloads tab's buttons,
# links, no classic-only place in messages, no "Madeira" in what a person reads.
- name: Check parity with the classic interface
run: python3 tests/host/check-parity.py --require-swift
# madeira-bcd FORK-ONLY: Send logs to BCD (LogUpload*.swift, bcd-logs/worker): the
# phone's scrub is tools/autotune-fixture.py's, the gzip is valid, the compressed copy
# is deleted, automatic sending is opt-in and Wi-Fi only.
- name: Check Send logs to BCD
run: python3 tests/host/check-log-upload.py --require-swift
# The performance trace (round 604; BCDPerfTrace*.swift): one line a second, an hour at most, the newest 20 kept, sent after a log's
# last line when the player turned it on (or a guided debug run did), nothing at all while it is off, and tools/log-facts.py reading it.
- name: Check the performance trace
run: python3 tests/host/check-bcd-perftrace.py --require-swift
# Help with a game (round 604; BCDHelpCore/BCDGameHelp/BCDReadinessCore.swift and their live sides): the guided debug run (nothing sent unless the
# player taps Send, the trace and the detailed log asked for by the session only), game feedback through the existing Feedback intake, and the
# launch check (a note on the game's page, from the import tables of its program files), with tools/pull-logs.py reading the feedback.
- name: Check help with a game
run: python3 tests/host/check-bcd-help.py --require-swift
# Shareable control layouts (round 604; BCDControlShare*.swift): a custom layout as a small JSON file, a file added as a new layout after the
# envelope and every control are checked (size, ranges, nesting, fresh ids, a name that replaces nothing).
- name: Check shareable control layouts
run: python3 tests/host/check-bcd-control-share.py --require-swift
# The performance HUD (round 603: Off, four layouts and Custom; BCDHUD*.swift, BCDFrameRing.c): the layouts against the design, an
# old overlay carried over unchanged, the frame arithmetic, placement from the window's size and safe area alone (a phone, 4:3,
# a near-square window, a resize), the ring under the address, undefined-behaviour and thread sanitizers, the present-path
# patch on the pinned DXMT, nothing alive while it is off, and no touch taken from the game.
- name: Check the performance HUD
run: python3 tests/host/check-bcd-hud.py --require-swift
# The session summary line ([session], BCDSessionCore.swift), the marker of an open session and the one question after a
# session that closed unexpectedly (BCDSessionRecorderLive.swift), and the readers of the line: tools/log-facts.py and
# the scanner behind the replay.
- name: Check the session summary and the question after an unexpected close
run: python3 tests/host/check-bcd-session-record.py --require-swift
# Screenshots from the in-game menu and Send Log (BCDScreenshotLive.swift, LogUpload.swift, the intake's POST /v1/shots,
# tools/pull-logs.py): the game's own surface only, a memory guard, Photos add-only, the picture sent as it is and only when
# chosen, as a small copy of 100 KB or less made apart from the kept one (BCDScreenshotShrink.swift, run on generated pictures),
# the intake's 160 KB limit, and the pull tool saving it beside its log.
- name: Check screenshots with Send Log
run: python3 tests/host/check-bcd-screenshot.py --require-swift
# madeira-bcd FORK-ONLY: Settings › Feedback (FeedbackUpload*.swift, BCDSettingsFeedback.swift,
# the intake's POST /v1/feedback, tools/pull-logs.py --feedback): the intake's gate, endpoint
# and fields, nothing personal in the body, the person's words untouched, the limits, the
# section's place after Logs, and the pull tool never printing the key.
- name: Check Settings › Feedback
run: python3 tests/host/check-feedback.py --require-swift
# A newer BCD, said at most once a day (BCDUpdateCheck.swift, BCDUpdateNotice.swift): the source's shape
# as tools/update-altsource.py writes it, the build compare, the day key, one host with a size cap, the
# alert only over the library with OK alone, env.MADEIRA_UPDATE_CHECK = 0.
- name: Check the update notice
run: python3 tests/host/check-update-check.py --require-swift
# An install without the increased memory limit is told once per build and where a log is sent, never blocked
# (MemoryRights.swift; the box over the library, Settings › Logs and a game's page).
- name: Check the memory limit notice
run: python3 tests/host/check-memory-rights-notice.py
# The GDI handle table a 32-bit program can map: the Dock and the library's Desktop ask for the
# section-backed table, games keep the default, bcd.cfg can turn it off, and ntdll says when a
# 32-bit program meets a private table (ContentView.swift, build/ntdll-unix/virtual_ios.c).
- name: Check the section-backed GDI table
run: python3 tests/host/check-dock-gdi-section.py
# BCD's in-game layer (BCDSession.swift and its views, BCDSessionLive.swift): the starting
# screen, menu button, overlay, in-game menu and key bar in BCD's look, the classic engine
# calls behind every function, nothing alive while closed, the preview build.
- name: Check BCD's in-game layer
run: python3 tests/host/check-bcd-session.py --require-swift --require-preview
# BCD's store-neutral content engine (app/Madeira/BCDContent/, docs/GOG.md): plans, streamed
# and checked chunks, the journal across a kill, pause and cancel, free space, Range resume,
# host rotation, the queue (game sessions, one download at a time with Steam), memory.
- name: Check the content engine
run: python3 tests/host/check-content-engine.py --require-swift
# GOG in BCD, milestone 1 (app/Madeira/BCDGOG/): sign-in without a token in any log, the
# library and its pictures, builds and manifests into a plan, install into C:\GOG Games
# end to end, the play task as a library entry. Synthetic replies only: GOG is never contacted.
- name: Check GOG
run: python3 tests/host/check-gog.py --require-swift
# Epic Games in BCD, milestone 0 (app/Madeira/BCDEpic/): sign-in on Epic's own page, the owned
# games and their pictures, the Keychain-only token rule, the masks on every [epic-*] log line,
# the tokens sent to Epic's hosts only, the preview build. Synthetic replies only: Epic is never contacted.
- name: Check Epic Games
run: python3 tests/host/check-epic.py --require-swift --require-preview
# BCD Host (bcd-host/): the helper that starts an Epic game signed in, inside Wine (milestone 2). Its
# request reader under AddressSanitizer and a fuzz, the report's bounds; with llvm-mingw also the PE itself
# (x86-64, GUI, relocatable, kernel32 only, no secret text). Without the toolchain only the host part runs.
- name: Check BCD Host
run: python3 tests/host/check-bcd-host.py
# Epic's start arguments (the one-time code, the account's ID and name) are masked in the two places the runtime and
# the bridge print a command line (build/bcd_epic_mask.h): both forms compiled and fuzzed, both call sites read.
- name: Check Epic's masks
run: python3 tests/host/check-epic-mask.py
# madeira-bcd FORK-ONLY: the public alpha IPA is unsigned and carries nothing about the
# owner (tools/make-alpha-ipa.py, owner 2026-10-17).
- name: Check the alpha IPA tool
run: python3 tests/host/check-alpha-ipa.py
# BCD's interface, Settings › Accounts, JIT and BCD Dock (BCDAccounts/JIT/Dock.swift):
# no engine type in the views, sign-out and the Dock reset only after a question, the
# password never kept or logged, the JIT methods per iOS version, the preview build.
- name: Check Settings › Accounts, JIT and BCD Dock
run: python3 tests/host/check-bcd-settings-accounts.py --require-preview
# madeira-bcd: the Dock's Reset removes what one-time installs put into the prefix,
# and the installs run in a session of their own (DockReset.swift; 2026-10-12).
- name: Check the Dock's one-time install reset
run: python3 tests/host/check-dock-reset.py --require-swift
# madeira-bcd (round 578): Valve's client service (Steam Client Service) is installed before a
# custom-executable (CEG) Dock start, with Valve's own SteamService.exe, because the host's
# in-session installer failed over RPC 1726 in 3 of 5 logged sessions (DockCEGService).
- name: Check Valve's client service for a CEG Dock start
run: python3 tests/host/check-dock-ceg-service.py --require-swift
# madeira-bcd (round 591): the "Registry" values of a game's Steam install script, written before a Dock
# start (env.MADEIRA_DOCK_SCRIPT_REGISTRY = 1; Fallout: New Vegas' launcher needs its Installed Path).
- name: Check the Dock's install-script registry values
run: python3 tests/host/check-dock-script-registry.py --require-swift
# Every Play and download of BCD's interface goes the classic library's way (the same
# launch function and checks for Steam via BCD Dock or directly, programs from Files and the
# desktop; downloads that keep running in the background on iOS 26; nothing for Epic or GOG).
- name: Check BCD's game starts and downloads
run: python3 tests/host/check-bcd-launch.py --require-swift
# Host checks that sat in tests/host without a workflow step until round 624. Every one passed in the committed tree with its
# submodules at their pins and in the built tree, so their place here does not matter; none needs an environment variable
# (wine/, FEX/, dxmt/, madeira-dock/ are at the repository root). Group 1 needs only the checkout (swiftc or cc where the check
# compiles); group 2 are the checks whose test was brought up to date with the code in round 624.
# ===== Group 1: 72 checks (check-jit-network opens loopback listeners only); none writes outside its temp folder; 0.1-14 s each under load =====
# tools/update-altsource.py builds the AltStore source from a release (download and codesign are mocked)
- name: Check altsource
run: python3 tests/host/check-altsource.py
# the iOS audio driver folds 5.1/7.1 layouts into the stereo bus (MADEIRA_AUDIO_DOWNMIX=0 restores the old mapping)
- name: Check audio downmix
run: python3 tests/host/check-audio-downmix.py
# the 32-bit audio driver table keeps the 64-bit table's 37 slots and the render-scratch allocator keeps a guest ceiling.
- name: Check audio wow64
run: python3 tests/host/check-audio-wow64.py
# bcd.cfg is found by native readers that run before the guest starts (early docs dir, HOME order)
- name: Check cfg early docs
run: python3 tests/host/check-cfg-early-docs.py
# a library game's own cfg lines ($MADEIRA_CFG_GAME) win over bcd.cfg.
- name: Check cfg game
run: python3 tests/host/check-cfg-game.py
# a pseudo-process child gets a desktop window like the session.
- name: Check child desktop
run: python3 tests/host/check-child-desktop.py
# a pseudo-process child's emulator gets the child's own ntdll copy (JIT alias push)
- name: Check child ntdll alias
run: python3 tests/host/check-child-ntdll-alias.py
# Chromium's out-of-memory exit names the failed request's size at NtTerminateProcess ([chromium-oom])
- name: Check chromium oom exit
run: python3 tests/host/check-chromium-oom-exit.py
# unchanged ClipCursor requests notify no one (wineserver queue_ios.c)
- name: Check clip dedupe
run: python3 tests/host/check-clip-dedupe.py
# a console's conhost.exe starts without a window (--headless)
- name: Check console headless
run: python3 tests/host/check-console-headless.py
# touch-control layouts and built-in presets (Foundation-only Swift blocks compiled on the host)
- name: Check control presets
run: python3 tests/host/check-control-presets.py
# SwapDeviceContextState patch and the opt-in source build of DXMT's 64-bit d3d11.dll.
- name: Check d3d11 src
run: python3 tests/host/check-d3d11-src.py
# opt-in tiled resources of the D3D12 runtime (d3d12-tiled-resources = 1)
- name: Check d3d12 tiled
run: python3 tests/host/check-d3d12-tiled.py
# round 624: the D3D12 methods that refuse a call say which ([madeira-d3d12] FAILED, log only), the unix ntdll's
# log-only lines of the round stay where they belong, and the Wine server survives a refused master-socket bind
- name: Check round 624 log lines
run: |
python3 tests/host/check-d3d12-fail-log.py
python3 tests/host/check-round624-log-lines.py
python3 tests/host/check-wineserver-bind-fallback.py
python3 tests/host/check-gdi-table-child.py
python3 tests/host/check-wow-unity-plain.py
python3 tests/host/check-present-lum.py
python3 tests/host/check-no-input-hint.py
python3 tests/host/check-windowed-hint.py
python3 tests/host/check-open-url.py
python3 tests/host/check-win-text.py
python3 tests/host/check-cluster-logs.py
python3 tests/host/check-fex-fault-diag.py
python3 tests/host/check-early-fault.py
python3 tests/host/check-log-upload-guard.py
python3 tests/host/check-jit-brk-trail.py
python3 tests/host/check-ill-insn-diag.py
python3 tests/host/check-installs-countdown.py
python3 tests/host/check-kernelbase-optin.py
python3 tests/host/check-fex-alias-capacity.py
python3 tests/host/check-fex-ec-teardown-ctx.py
python3 tests/host/check-fex-cpuid-classic.py
python3 tests/host/check-fex-thread-init-nomem.py
python3 tests/host/check-fex-exit-runaway.py
python3 tests/host/check-fex-inval-null-thread.py
python3 tests/host/check-fex-processorid.py
python3 tests/host/check-fex-moffs-rip.py
python3 tests/host/check-thread-sample-syscall.py
python3 tests/host/check-usd-osversion.py
python3 tests/host/check-thread-fault-isolate.py
python3 tests/host/check-display-rate.py
python3 tests/host/check-display-hz.py
python3 tests/host/check-x64-nocopy-dataimp.py
python3 tests/host/check-pe-module-name-safe.py
python3 tests/host/check-diag-module-name.py
python3 tests/host/check-ctx-null.py
python3 tests/host/check-hint-storm.py
python3 tests/host/check-fd-pollout-guard.py
python3 tests/host/check-dock-install-skip.py
python3 tests/host/check-godot-composition.py
python3 tests/host/check-clr-death-diag.py
python3 tests/host/check-crypt32-root-enum.py
python3 tests/host/check-gpu-stall.py
python3 tests/host/check-gpu-time-wow64.py
python3 tests/host/check-noexec-who.py
python3 tests/host/check-desktop-shell.py
python3 tests/host/check-d9-texfmt.py
python3 tests/host/check-d9-query-stuck.py
python3 tests/host/check-d11-query-stuck.py
python3 tests/host/check-soft-pool-decommit.py
python3 tests/host/check-mem-burst.py
# DXMT D3D9 upload ring stays bounded while a title loads without Present (ml1490)
- name: Check d9 upload commit
run: python3 tests/host/check-d9-upload-commit.py
# tools/patch-wine-dns-trace.py names every getaddrinfo and bounds it on request.
- name: Check dns trace
run: python3 tests/host/check-dns-trace.py
# Madeira Dock's transfer path through Wine's own prefix resolver.
- name: Check dock path
run: python3 tests/host/check-dock-path.py
# Madeira Dock's report parser (whitelisted numeric fields only)
- name: Check dock report
run: python3 tests/host/check-dock-report.py
# IDXGIFactory7 for DXMT's factory and the opt-in dxgi.dll source build.
- name: Check dxgi factory7
run: python3 tests/host/check-dxgi-factory7.py
# every DXMT/airconv/winemetal patch script applies in the workflow's order and is idempotent.
- name: Check dxmt patch chain
run: python3 tests/host/check-dxmt-patch-chain.py
# conhost.exe is refused in an ARM64EC session.
- name: Check ec conhost
run: python3 tests/host/check-ec-conhost.py
# NtProtectVirtualMemory's [exec-req] path leaves the syscall callback.
- name: Check execreq leave
run: python3 tests/host/check-execreq-leave.py
# FEX arena failure census: clipping, protection accounting, alignment, bounded output.
- name: Check fex arena census
run: python3 tests/host/check-fex-arena-census.py
# tools/patch-fex-ios-callret-8mb.py against the pinned FEX tree.
- name: Check fex callret 8mb
run: python3 tests/host/check-fex-callret-8mb.py
# D3D9 sampler anisotropy cap (getOrCreateSampler, ml1250)
- name: Check filtering cap
run: python3 tests/host/check-filtering-cap.py
# a version query cannot use up the fixed-base window (GTA V launcher, RDR2)
- name: Check fixed base guard
run: python3 tests/host/check-fixed-base-guard.py
# delayed release of 1-16 MB guest allocations (MADEIRA_FREE_DELAY_MS)
- name: Check free delay
run: python3 tests/host/check-free-delay.py
# library front end: launch profiles, controller navigation, session exit report.
- name: Check frontend
run: python3 tests/host/check-frontend.py
# snapshot transport and win32u gamepad query.
- name: Check gamepad
run: python3 tests/host/check-gamepad.py
# a scalar guest store crossing the end of an anonymous alias is stored page by page (build 623)
- name: Check gpr store straddle
run: python3 tests/host/check-gpr-store-straddle.py
# opt-in HID controller: descriptors and reports read back through Wine's own hid.dll code.
- name: Check hidpad
run: python3 tests/host/check-hidpad.py
# a module loaded again at the base of its unloaded pool copy gets fresh .data/.bss.
- name: Check image reload
run: python3 tests/host/check-image-reload.py
# unloaded-image translation retirement (MADEIRA_JIT_IMAGE_RETIRE)
- name: Check image retire
run: python3 tests/host/check-image-retire.py
# the JIT-pool dump is opt-in (ios_jit_dump_enabled)
- name: Check jit dump optin
run: python3 tests/host/check-jit-dump-optin.py
# every child gets the JIT pool's WINE_IOS_JIT_* variables (ios_env_with)
- name: Check jit env
run: python3 tests/host/check-jit-env.py
# StikDebug and the iOS 26 built-in JIT helper: static integration checks.
- name: Check jit method
run: python3 tests/host/check-jit-method.py
# LocalDevVPN loopback check and the JIT shortcut (JITNetwork.swift LoopbackProbe)
# Opens listeners on 127.0.0.1 (ephemeral ports) only; nothing leaves the machine.
- name: Check jit network
run: python3 tests/host/check-jit-network.py
# opt-in D3DKMT adapter, the [vkmt] trace and DXGI's UMD version patch.
- name: Check kmt adapter
run: python3 tests/host/check-kmt-adapter.py
# in-process NSI network tables (nsi_network_ios.c)
- name: Check nsi network
run: python3 tests/host/check-nsi-network.py
# NVAPI trace and display-name fallback patches.
- name: Check nvapi trace
run: python3 tests/host/check-nvapi-trace.py
# controller output (DualSense output reports, XInput rumble) on its way to the physical pad.
- name: Check pad output
run: python3 tests/host/check-pad-output.py
# a placement walk that found no gap is remembered (ios_ml1027_place)
- name: Check place proof
run: python3 tests/host/check-place-proof.py
# the CPU power governor holds the average at its target (MADEIRA_POWER_GOV_MW)
- name: Check power gov
run: python3 tests/host/check-power-gov.py
# Social Club layout 2 keeps room for RDR2's 8960 MB reserve (MADEIRA_RDR2_VA_HOLD)
- name: Check rdr2 va hold
run: python3 tests/host/check-rdr2-va-hold.py
# the wineserver overwrites a link to a read-only file (fd_ios.c)
- name: Check readonly link
run: python3 tests/host/check-readonly-link.py
# front end Settings: display rate, swap tier and sync engine (MadeiraConfig.set)
- name: Check runtime settings
run: python3 tests/host/check-runtime-settings.py
# Social Club's Chromium: one CEF process, its libcef.dll copy and its glued pools.
- name: Check sc cef gate
run: python3 tests/host/check-sc-cef-gate.py
# Social Club layout 2: the helper's commits into its large grants, in 256 MB steps.
- name: Check sc grant growth
run: python3 tests/host/check-sc-grant-growth.py
# Social Club helper restarts and layout 2 (virtual_ios.c)
- name: Check sc layout
run: python3 tests/host/check-sc-layout.py
# [sc-rph]: the browser CefApp hands out the renderer app's handler.
- name: Check sc render handler
run: python3 tests/host/check-sc-render-handler.py
# D3D9 scene batching (ml1250)
- name: Check scene batching
run: python3 tests/host/check-scene-batching.py
# a thread killed inside an uninterrupted section leaves it first (server_ios.c)
- name: Check section abort
run: python3 tests/host/check-section-abort.py
# packed shader cache madeira_sc_pack.c (opt-in d3d12-shader-pack = 1)
- name: Check shader pack
run: python3 tests/host/check-shader-pack.py
# guest-window band and small-map rule (ios_wow_band, ios_wow_map_allows_window)
- name: Check small va band
run: python3 tests/host/check-small-va-band.py
# thread stack spill and the small-stack executables (MADEIRA_THREAD_STACK_SPILL, MADEIRA_SMALL_STACK_EXES)
- name: Check stack spill
run: python3 tests/host/check-stack-spill.py
# the stale-pointer heal translates each copy for the process that uses it.
- name: Check stale heal owner
run: python3 tests/host/check-stale-heal-owner.py
# Steam games in the library: installed/partial state from Steam's own manifests, Dock discovery.
- name: Check steam games
run: python3 tests/host/check-steam-games.py
# Steam sign-in (SwiftSteam): licence headers, Keychain item stays local, no credential in logs; Swift checks.
- name: Check steam signin native
run: python3 tests/host/check-steam-signin-native.py
# swapchain mode-switch diagnostics ([swap-diag], [swap-win], [main-stall]) only log.
- name: Check swap diag
run: python3 tests/host/check-swap-diag.py
# a thread that cannot be created says why (Chromium OOM exit with size 0)
- name: Check thread create failure
run: python3 tests/host/check-thread-create-failure.py
# touch ownership/arbitration logic (TouchGamepadState)
- name: Check touch gamepad
run: python3 tests/host/check-touch-gamepad.py
# unix-library binder by caller bitness (load_builtin_unixlib)
- name: Check unixlib binder
run: python3 tests/host/check-unixlib-binder.py
# env.MADEIRA_VCRT_ARM64_KEY, the volatile ARM64 Visual C++ redistributable marker (server_ios.c)
- name: Check vcrt arm64 key
run: python3 tests/host/check-vcrt-arm64-key.py
# the virtual monitor's Win32 names (sysparams_ios.c)
- name: Check vmon identity
run: python3 tests/host/check-vmon-identity.py
# the monitor's fault-safe reads against real protected/unmapped pages (Wine patch applied twice to a temp copy)
- name: Check waiter read
run: python3 tests/host/check-waiter-read.py
# win32u allocation ceiling per pseudo-process (win32u_zero_bits)
- name: Check win32u zero bits
run: python3 tests/host/check-win32u-zero-bits.py
# window coordinates with Wine's real rectangle and DPI functions (build 391)
- name: Check window coordinates
run: python3 tests/host/check-window-coordinates.py
# the compositor callback and Wine's is_window_visible (build 391 regression)
- name: Check window visibility
run: python3 tests/host/check-window-visibility.py
# Wine Mono's first-use download: pins match build/wine-mono/pin.sh, installer unpacks synthetic .tar.xz archives.
- name: Check wine mono
run: python3 tests/host/check-wine-mono.py
# WoW64 thread contexts on the server side (I386_CONTEXT offsets, apply only for i386)
- name: Check wow context
run: python3 tests/host/check-wow-context.py
# FEX WOW64 module keeps the CPU area current and honours RESET_STATE.
- name: Check wow cpu area
run: python3 tests/host/check-wow-cpu-area.py
# WOW64 syscall parking in the code-buffer sweeper.
- name: Check wow sweep
run: python3 tests/host/check-wow-sweep.py
# ADD/SUB off x18 take the destination-register trampoline.
- name: Check x18 arith
run: python3 tests/host/check-x18-arith.py
# ===== Group 2: 20 checks whose test was brought up to date with the code in round 624 =====
# tools/patch-wine-cpu-error-diag.py applies once to the committed user32/wow64 files ([msgbox-origin], [pf-xmmi64] log only).
- name: Check cpu error diag
run: python3 tests/host/check-cpu-error-diag.py
# tools/patch-wine-rpc-np-diag.py: [rpc-np] logs a failed RPC named-pipe read, nothing else changes.
- name: Check rpc np diag
run: python3 tests/host/check-rpc-np-diag.py
# Madeira Dock's app-side contract (pool policy, discovery, launch validation, transfer envelope, environment) compiled from production Swift.
- name: Check dock contract
run: python3 tests/host/check-dock-contract.py
# Dock one-time installs: install-script plan, ledger, DirectX provided by BCD after a failure, batch text (production Swift under ASan).
- name: Check dock installers
run: python3 tests/host/check-dock-installers.py
# Round 626 (A1 S12): a Dock start that runs the EA app's installer links msiexec into system32 for that session.
- name: Check the EA app installer's Dock session
run: python3 tests/host/check-dock-ea-installer.py
# Round 626 (P S8): the Mach exception thread's diagnostics read through mach_vm_read_overwrite, never a plain load.
- name: Check the Mach exception thread's checked reads
run: python3 tests/host/check-mach-exc-safe-reads.py
# Round 626 (U2 S10, Sable PVTSYM): every CoreHaptics call of the controller rumble is guarded; a stopped engine is rebuilt.
- name: Check the rumble's CoreHaptics guard
run: python3 tests/host/check-pad-output-haptics-guard.py
# Ghost of Tsushima diagnostics switches in madeira_d3d12.c (skip-ps, dxil-dump, fence-strict, upload-guard, ...) stay off by default and sit behind g_sd_state.
- name: Check got diagnostics
run: python3 tests/host/check-got-diagnostics.py
# HKLM\HARDWARE\DESCRIPTION registry mirror of FEX's CPUID answers and wineboot's BIOS/processor values (fuzzed under ASan/UBSan).
- name: Check hw registry
run: python3 tests/host/check-hw-registry.py
# first-run setup: rules, pages, once-per-run decision, never over a session, Run setup again.
- name: Check onboarding
run: python3 tests/host/check-onboarding.py
# pso-warm: pipeline cache warm-up in winemetal (op 10), copies and retains balanced, d3d12 side sends both lazy kinds.
- name: Check pso warm
run: python3 tests/host/check-pso-warm.py
# replay-split: every D3D12 command kind has a named [perf] bucket, timers only behind the flag.
- name: Check replay split
run: python3 tests/host/check-replay-split.py
# media packaging gate (tools/check-wine-media-dlls.py): WMVCORE/winegstreamer exports, imports, forwarders, delay imports.
- name: Check wine media dlls
run: python3 tests/host/check-wine-media-dlls.py
# x64 classification, IAT slots and fault-safe guest-instruction diagnostics (ASan/UBSan, three negative controls).
- name: Check guest instruction
run: python3 tests/host/check-guest-instruction.py
# D3D9 device lock and FEX split CAS: no split-lock rollback, strict split locks on for WOW64, 4x20000 XADD exact.
- name: Check d3d9 splitlock
run: python3 tests/host/check-d3d9-splitlock.py
# MADEIRA_BAND_CENSUS: the 64 GB band census (layouts, 8960 MB fit, capped at 64 lines).
- name: Check band census
run: python3 tests/host/check-band-census.py
# [bg-qos]: background helper processes leave the performance cores while a game presents.
- name: Check bg qos
run: python3 tests/host/check-bg-qos.py
# always-on monitors stay off the game's cores (warmer sweep cadence, one [xp-names] line per native thread).
- name: Check monitor cadence
run: python3 tests/host/check-monitor-cadence.py
# an unaligned ordered/exclusive/LSE access in the app's own code is emulated in place (GTA V launcher stlr).
- name: Check native unaligned
run: python3 tests/host/check-native-unaligned.py
# wineserver request doorbell: no request lost through the bells alone (1.6 M requests, 8 clients; has a 5 s watchdog).
# The only one here with a wall-clock watchdog (5 s per request); passed 3/3 including 6 copies at once on 12 vCPUs.
- name: Check srv doorbell
run: python3 tests/host/check-srv-doorbell.py
# swap tier core: coverage modes, merged free extents, host-page copy-back, reserve-time backing, census.
- name: Check swap coverage
run: python3 tests/host/check-swap-coverage.py
# aux-IAT heal: timeGetTime's QPC/QPF stubs healed to the process's ntdll copy through the RW view only.
- name: Check aux iat heal
run: python3 tests/host/check-aux-iat-heal.py
# owned Steam library and downloads: protocol, manifests, decrypt/decompress, resumable install against three local HTTP servers (loopback only, ~25 s CPU).
# Starts three HTTP servers on 127.0.0.1 itself (never contacts Steam); needs swiftc, cc and the openssl command; 47-84 s wall under load (about 25 s of CPU).
- name: Check steam library
run: python3 tests/host/check-steam-library.py
# ===== Group 3: needs a host FFmpeg (built once, then cached) =====
# Builds a host FFmpeg 7.1.1 from the tracked tarball on first use (1 m 46 s cold here, 7 s warm) into ~/.cache/madeira-host-ffmpeg/ (set
# MADEIRA_HOST_FFMPEG to a prebuilt prefix to move it); then the production wg_parser under ASan/UBSan. Needs the diff of check-wg-parser.py.
- name: Check wg-parser on libavformat (MP3/WAV/MP4)
run: python3 tests/host/check-wg-parser.py
# ===== Not in the workflow =====
# check-fastsync.py non-deterministic (a stochastic "control must stall" assertion fails under CPU load)
# check-jit-pairing.py runs cargo test: writes build/rppairing-ios/target into the repo, needs loopback sockets and crates.io
# check-sc-ipc-rebind.py, check-sc-ipc-split.py, check-sc-render-loop.py, check-sc-runstate.py, check-sc-ui-close.py
# assemble x86-64 with GNU as/ld/objcopy/nm and run x86-64 code: need an x86-64 host + GNU binutils (the arm64 runner cannot run them)
# check-launcher-smc.py, check-fex-branch-history.py need the Python unicorn module (not installed, no network); also need their diffs
# BCD's interface is the app's interface (BCDLiveStore.swift, BCDLiveFrontEnd.swift;
# docs/BCD-UI-ARCHITECTURE.md): the BCD choice and its one-time move, Play through the
# classic library's function, the in-game flag, setup over it, the preview build.
- name: Check BCD's interface in the app
run: python3 tests/host/check-bcd-live.py --require-swift
# BCD's game page (BCDGamePage.swift, docs/BCD-UI-ARCHITECTURE.md): its rules for every
# state, the questions before what deletes or sends, the controller, cool running and
# the preview build.
- name: Check BCD's game page
run: python3 tests/host/check-bcd-game-page.py --require-swift
# BCD's Library tab and Add a game (BCDLibraryView.swift, BCDAddGame.swift): search, refresh,
# the Steam sign-in card, how games get into drive_c, the kept filter and order, a program
# of drive_c added with its name, Add every game, BCD's own screens in the app.
- name: Check BCD's library and Add a game
run: python3 tests/host/check-bcd-library.py --require-swift
# The graphics API the library shows (Library.swift apiNames, the scanner's dynamicAPIs, and from 2026-10-24 folderAPIs:
# Unity's UnityPlayer.dll, the Agility SDK's D3D12Core.dll and the DXIL DLLs beside a program whose imports name none).
- name: Check the library's graphics API detection
run: python3 tests/host/check-library-api.py
# The EA app installer's MSI package (build 593, log 17:15:17): its first custom action ran in rundll32 and asked msiexec's
# custom action server over a pipe; the server's first answer reached a running thread, no waiting thread could take it and BCD's
# own Windows server dropped it (JunoInitializeSession 1603). env.MADEIRA_APC_BUSY_QUEUE = 1 keeps it on its thread: the real
# server functions next to the original ones (off: byte for byte the same), the EA entry's line, auto-tune's rule and fixture.
- name: Check an async I/O completion kept for a busy thread (EA app installer)
run: python3 tests/host/check-apc-busy-queue.py
# Control and Slay the Spire 2 (logs X49WBQ, GZFVM3): a crash in RtlRunOnceComplete's walk of an InitOnce's waiters, because a
# NULL keyed-event handle was the first pseudo-process's global in a child. env.MADEIRA_KEYED_EVENT_PER_PROCESS = 1 gives each
# child its own: the Wine fork's two calls, the header's table over every case (off: the session's handle), the child boot hook,
# auto-tune's rule and its two fixtures.
- name: Check a child process's own keyed event (Control, RunOnce)
run: python3 tests/host/check-keyed-event-per-process.py
# Messiah's "Launch Messiah.bat" (logs since build 614): the 64-bit cmd.exe found no reg.exe. Sessions link the i386 command-line
# tools into the 64-bit system32 where the name is absent (env.MADEIRA_SYSTEM32_X86_TOOLS = 0 turns it off).
- name: Check Windows' command-line tools in the 64-bit system32 (Messiah)
run: python3 tests/host/check-system32-x86-tools.py
# Gal*Gun 2 and Hello Neighbor (logs CWFP3N, B2B7BR, TAW359): OpenSSL 1.0.2's SHA-extension SHA-1 routine returns with a wrong stack
# pointer after NETAPI32.DLL loads. env.MADEIRA_FEX_SHA = 0 tells such a game's guest the processor has no SHA extension: the app's
# rewrite of FEX's host probe compiled and run over every value, FEX's reading of it, the list rows, auto-tune's rule and its fixtures.
- name: Check the per-game SHA extension switch (Gal*Gun 2, Hello Neighbor)
run: python3 tests/host/check-fex-sha-off.py
# env.MADEIRA_ZERO_MITIGATION_POLICY (Glyphica: Typing Survival, ChakraCore's fail-fast over an unwritten CFG policy): the Wine fork's
# kernelbase GetProcessMitigationPolicy compiled on the host and run over every value of the switch (off: untouched; 1: zeroed, 1 to 16
# bytes), the game's list line (build 600), the list policy, auto-tune's rule and its fixture, the catalog.
- name: Check Wine's zeroed mitigation policy (Glyphica, ChakraCore)
run: python3 tests/host/check-zero-mitigation-policy.py
# PC launchers in the Library (Battle.net, EA app: BCDLaunchers.swift, BCDLauncherDownload.swift, BCDLaunchersLive.swift) and
# Wine Gecko for their installers (BCDGecko.swift): the installer addresses and hosts, the "installed" detection, the start
# on its own (no explorer), the download served from a URLProtocol, Gecko's SHA-256 values against addons.c.
# A game's session without BCD's fixed Steam identity (env.MADEIRA_STEAM_IDENTITY = none, WineProcessBridge.m): the bridge's
# real block compiled and run in every case, the list policy, the catalog, the auto-tune rule for Rockstar's launcher from Epic.
- name: Check the no-Steam-identity switch
run: python3 tests/host/check-steam-identity.py
- name: Check BCD's launchers and Wine Gecko
run: python3 tests/host/check-bcd-launchers.py --require-swift
# ajan32/ea-cef (2026-10-24): the EA app's Chromium (EADesktop.exe, CEF 109) in one process with its four 16 GB PartitionAlloc
# pools in the four slots of layout 2's band, only with env.MADEIRA_EA_CEF = 1 (the EA launcher entry's lines): the five gated hook
# lines in virtual_ios.c, the production routing compiled against a model of the band (restart, blocked slot, second browser),
# the soft-grant loop against the original (switch off = the old grants), the spawn gate and the command line.
- name: Check the EA app's Chromium
run: python3 tests/host/check-ea-cef.py
# BCD's menus (BCDMenu.swift): a game's menu on a long press or X (Play or Install, Game
# page, Uninstall or Remove after a question), the Library's sort menu, the controller layer.
- name: Check BCD's menus
run: python3 tests/host/check-bcd-menu.py --require-swift
# BCD's words: "license" in everything a person reads (identifiers and the credits' legal text stay).
- name: Check BCD's spelling
run: python3 tests/host/check-bcd-spelling.py
# BCD's on-screen touch controls and their editor (BCDTouch*.swift): every control sends
# the game what the classic one sent and takes the same touches, layouts convert byte for
# byte, the overlay and the in-game menu show BCD's, the preview build.
- name: Check BCD's touch controls
run: python3 tests/host/check-bcd-touch.py --require-swift
# The files BCD writes carry BCD's names (2026-10-18): bcd.cfg (madeira.cfg and the
# madeira-<key>.txt files are never read; every device installs BCD fresh),
# bcd-log.txt, bcd-library.json, bcd-art/, the controls' files, bcd-reset-backup/,
# BCD-saves-<date>.zip; no source opens a file by an old name.
- name: Check BCD's file names
run: python3 tests/host/check-bcd-file-names.py --require-swift
# The extra keys (round 603): the key bar over the game (Game › Key bar) and the second page of the bar over the
# iOS keyboard (Fn): Alt+Tab, Alt+Enter, Win, F1-F12, Esc, Del and Ctrl/Alt/Shift latches, posted as every key is.
- name: Check the extra keys
run: python3 tests/host/check-bcd-extra-keys.py --require-swift
# The in-game menu's items of round 604: Pause, Windows, Task Manager, magnifier, picture filter and flip, gestures help, the live log's
# tools with Wine debug-channel presets, vibration, touch controls that hide and take a colour, the controller's way of opening the
# menu, "Save these settings for this game", frame generation and the cooling cap. Every one is a menu choice; nothing changes
# for a game whose player does none of them.
- name: Check the BCD in-game menu items
run: python3 tests/host/check-bcd-menu-items.py --require-swift
# Turbo and macros (round 604): a held controller button repeats, a button plays a chain of presses, per game, off by default; nothing
# exists (two static flags, no timer) until a game turns it on and is played.
- name: Check turbo and macros
run: python3 tests/host/check-bcd-turbo.py --require-swift
# Players (round 604): press a button on a controller to make it Player 1 to 4, rumble for each player, the touch controls as a player; with
# nothing chosen a controller takes the first free slot as before.
- name: Check players
run: python3 tests/host/check-bcd-players.py --require-swift
# Radial menu (round 604): a button at the edge opens a ring of up to eight keys and actions round the thumb, per game, off by default;
# no window exists until a game turns it on and is played.
- name: Check radial menu
run: python3 tests/host/check-bcd-radial.py --require-swift
# Aim mode, touch gestures and the Apple Pencil as a mouse (round 604): what a finger or a Pencil on the game does beyond the pointer
# setting, per game, off by default; with all three off MetalBackedView reads one static flag.
- name: Check aim mode, touch gestures and the Apple Pencil
run: python3 tests/host/check-bcd-touch-extras.py --require-swift
# The gamepad model picker (round 604): what a game sees as player 1's controller (Xbox, DualSense, generic gamepad); it only names the
# values env.MADEIRA_PAD_MODE always took, and offers no DualShock 4 while the wineserver has none.
- name: Check the gamepad model picker
run: python3 tests/host/check-bcd-padmodel.py --require-swift
# Touch-control look (round 604): the colour of the on-screen buttons, what a press lights up in and the symbols on the face buttons;
# BCD's own look is what a player who chooses nothing has, drawn as before.
- name: Check touch-control look
run: python3 tests/host/check-bcd-touch-look.py --require-swift
# Gyro aim (round 603): turning the phone aims the game as the mouse or the right stick, per game, off by default; nothing runs
# (no sensor, one static flag in the controller code) until a game turns it on and is played.
- name: Check gyro aim
run: python3 tests/host/check-bcd-gyro.py --require-swift
# "Look like this GPU" (round 603): a game's gpu-card line names the graphics card it is told it has, the same in DXGI,
# Direct3D 9 and Windows' own adapter; nothing changes for a game that picks none.
- name: Check Look like this GPU
run: python3 tests/host/check-gpu-cards.py --require-swift
# BCD's interface: Settings (app/Madeira/BCDSettings*.swift): headers, no engine types in its
# views, the preview build, the controller's walk, no old name on screen, the credits word
# for word, every catalog key, and the classic settings kept reachable.
- name: Check BCD's Settings
run: python3 tests/host/check-bcd-settings.py
# Games on a USB-C SSD (Settings > Storage > External SSD, C:\External; docs/EXTERNAL-STORAGE.md; based on
# thebcd69/bcd-games#12 by Pardoxum). Opt-in by use: until a folder is chosen restore() is one UserDefaults read
# and every hook in the library keeps its original test first (compiled against the original scanner on real
# folders); then the reconnect without the picker, stale and damaged bookmarks, containment, and that no user
# file is deleted or overwritten. Needs macOS Foundation and swift (bookmarks, links, real folders).
- name: Check games on an external SSD (opt-in by use, reconnect, safety)
run: python3 tests/host/check-external-storage.py --require-swift
# The in-place External SSD folder-picker fix (app/Madeira/ExternalGamesPicker.swift): on an install
# whose signed App ID differs from the bundle id, correct the picker's host identity (only, never the
# whole app) so Open returns the real folder in place with no -Inbox copy; change nothing for installs
# that already work. Gating, no-global-identity-change and the pure identity decision are pinned here.
- name: Check the in-place External SSD folder-picker fix
run: python3 tests/host/check-external-picker.py --require-swift
# Every app source is in the Xcode project (build 623's first run: a new Swift file passed the typecheck but not the archive).
- name: Check the app sources are in the Xcode project
run: python3 tests/host/check-xcode-sources.py
# BCD's controller hub (BCDControllerHub.swift, written clean-room from
# docs/clean-room/controller-hub-spec.md): the mapping's sectors, keys, order, triggers and
# default; element handlers only (GamepadInput keeps the profile's and its queue); state on
# the main thread; the earlier third-party manager gone and named nowhere.
- name: Check BCD's controller hub
run: python3 tests/host/check-controller-hub.py --require-swift
# --- UNVERIFIED: exact configure invocation for the wine fork's
# iOS/arm64 cross target isn't documented anywhere in the repo.
# This is a best guess and will likely need correcting once we see
# the real error.
- name: Install newer bison (macOS ships an ancient 2.3)
run: |
brew install bison
echo "$(brew --prefix bison)/bin" >> "$GITHUB_PATH"
- name: Install llvm (need lld/llvm-dlltool for aarch64-windows PE cross target)
run: |
brew install llvm lld
echo "$(brew --prefix llvm)/bin" >> "$GITHUB_PATH"
echo "$(brew --prefix lld)/bin" >> "$GITHUB_PATH"
# 13m25s of a 21m37s run was spent rebuilding wine's host tools, every
# time, for a submodule that does not move. Key the cache on the wine
# revision so it rebuilds exactly when wine actually changes.
- name: Wine submodule revision
id: winerev
shell: bash
run: echo "sha=$(git -C wine rev-parse HEAD)" >> "$GITHUB_OUTPUT"
# willfaust/wine madeira-lgpl e828644: dlls/ntdll/loader.c line 1342
# #includes "arm64ec_x64_export_iat.c", which was never committed to the
# fork. It sits under #ifdef __arm64ec__ -- the PE ntdll, which this
# build does not compile (ntdll.dll is upstream's tracked binary) -- but
# configure's makedep scans every include and stops at the missing file,
# so no Makefile, no config.h, and nothing after it builds. Give makedep
# an empty file; if the fork later commits the real one, this is a no-op.
- name: Work around wine's uncommitted arm64ec_x64_export_iat.c
shell: bash
run: |
F=wine/dlls/ntdll/arm64ec_x64_export_iat.c
if [ -f "$F" ]; then
echo "::notice::$F is present upstream now -- this step can go"
else
printf '/* placeholder: see build-ipa.yml; PE-side only, never compiled here */\n' > "$F"
echo "::warning::$F missing from the wine fork -- empty placeholder written for makedep"
fi
# dlls/ntdll/unix/sync.c includes build/madeira_cfg.h BEFORE config.h,
# on purpose (ml1122: Wine's headers ban strncpy by macro). makedep
# treats that ordering as fatal, so configure never writes a
# Makefile. Upstream builds from a long-configured tree and never
# meets it. Make that one sanity check a warning.
MD=wine/tools/makedep.c
python3 - "$MD" <<'PYEOF'
import sys
p = sys.argv[1]
s = open(p).read()
old = 'fatal_error( "%s must be included before other headers\\n", file->name );'
new = ('fprintf( stderr, "%s:%d: warning: %s must be included before other headers '
'(madeira-bcd CI: not fatal)\\n", input_file_name, input_line, file->name );')
if new in s:
print("makedep: already patched")
elif s.count(old) == 1:
open(p, "w").write(s.replace(old, new))
print("makedep: config.h ordering check is now a warning")
else:
print("::error::makedep.c anchor not found -- wine moved, review this step")
sys.exit(1)
# The WoW64 series' wine (125hz pr/wow64-core) includes Madeira's
# iOS shim headers (ios_fastsync.h, ios_srv_stats.h, ...) by bare