ci(windows): build the Windows release files on the Linux runner #99
No reviewers
Labels
No labels
area/accessibility
area/audio
area/input
area/install
area/menu
area/renderer
area/saves
area/upscaling
good first issue
gpu/amd
gpu/igpu
gpu/intel
gpu/nvidia
help wanted
kind
bug
kind
chore
kind
docs
kind
feature
kind
performance
kind
question
needs measurements
platform/linux
platform/steam-deck
platform/windows
preview
priority
critical
priority
high
priority
low
status
blocked
status
confirmed
status
duplicate
status
invalid
status
needs-info
status
wontfix
testing wanted
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
MagicBeanDev/Longshot!99
Loading…
Reference in a new issue
No description provided.
Delete branch "HumanBean/Longshot:ci-windows-on-linux"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Why
There is no Windows runner, so every job asking for
windows-2022queues forever: the Windows builder zip, and with it every Longshot release, could never be made. This builds the Windows release files on the Linux runner we have.What changed
build (
.forgejo/workflows/build-windows.yml): every job onubuntu-24.04.builder/setup/setup.c,setup.rcthroughwindres) with llvm-mingw's Linux build of the releasetools.lockpins (20261104). It is pinned by version, SHA-256 and size asLINUX_LLVM_MINGWinscripts/builder_package.py, and fetched withbuilder_package.py llvm-mingw --host linux(throughtools.fetch, extracted with tarfile'sdatafilter).--hostdefaults to the running system. The dav1d job now uses the same pin, not its own copy.dotnet publish -c Release --runtime win-x64 -p:EnableWindowsTargeting=true. It stays self-contained, a folder (not a single file), as the csproj's Release configuration has it.RX_TARGET=windows(nx2/build.py's existing cross build),$(nproc)in place of$NUMBER_OF_PROCESSORS.build (
scripts/check_windows_files.py, new): it checks the zip as Windows files, catching what a non-Windows build could drop without a word:ICON/GROUP_ICON/MANIFEST/VERSIONINFOresources, imports only Windows' own,DependentLoadFlags0x800;VERSIONINFOandMANIFESTcopied from the assembly;Resourceitems inLongshotBuilder.dll;runtimeconfig.json(self-containedMicrosoft.NETCore.AppandMicrosoft.WindowsDesktop.App8.x), anddeps.json(.NETCoreApp,Version=v8.0/win-x64).--winestarts both under Wine in Xvfb, with no window and nothing downloaded.build (
.forgejo/workflows/vulkan-dlss.yml): onubuntu-24.04withRX_TARGET=windows.ci (
.forgejo/workflows/ci.yml): thewindows-2022matrix entries are gone. The Builder's compile and its worker-delivery check (tests/builder_workers) now run in Linux part 1 withEnableWindowsTargeting; the worker check passes on Linux's .NET with Linux's Python, 104 assertions. The MSVC step (clonpresent_rect_test.cpp,test_invalidate_vcore.py --cxx cl) and the suite on Windows' Python move to RELEASING.md, Needs a Windows tester. Both C++ checks already run on Linux with GCC/Clang.tests (
tests/test_windows_on_linux.py, new): it fails if any workflow names a Windows runner (runs-onor a matrixos). It also checks thatLINUX_LLVM_MINGWis the releasetools.lockpins, that the builder job publisheswin-x64withEnableWindowsTargetingand runs both checks, and that the csproj stays self-contained.docs:
docs/forgejo-runners.md(no Windows runner needed; Windows files, built on Linux),RELEASING.md(new Needs a Windows tester; the rc step points to it; Bump a tool also bumpsLINUX_LLVM_MINGW; one-time setup: Linux runners only),docs/releases.md(CI table and note),docs/control.md(the named-pipe tests are now a tester's).Decisions:
builder/msi/LongshotBuilder.wxsis not built by any workflow, and the release files (docs/releases.md,release.yml) have no MSI. So there is nothing to move towixl. The source stays as it is.RUN_ALL_SKIPskips on Linux (the setup's Win32 file/path handling, the portable homes, structured exceptions) are not run under Wine here. Each test runs the exe it builds directly. A--run wineoption liketest_dav1d_av1.py's would be a follow-up per test. Until then they are on the Windows tester's list.signtoolstep existed). No resource step is skipped:windresruns as before, and the SDK's apphost resource copy works on Linux (checked).Flags and settings
None for the game or the builder. The one new option is CI's:
scripts/builder_package.py llvm-mingw --host windows|linux(default: the running system) picks tools.lock's Windows llvm-mingw or the pinned Linux build; it is documented in the script's docstring.Measurements
No runtime or game change: nothing to measure in the game. The build itself, below.
main:
5eaaf7fb(2026-11-12)this PR: ci-windows-on-linux @
8e5150d1(on main @5eaaf7fb; built again after the rebase, the numbers below are this commit's)Hardware: Ryzen, 24 threads, 30 GB, CachyOS Linux 7.3 (Docker)
Scene: n/a (CI)
Method: the build-windows.yml commands run in
docker run ghcr.io/catthehacker/ubuntu:act-24.04(the runner's job image), repo mounted; .NET 8.0.428 SDK from dotnet-install, wine64 9.0 and Xvfb from aptHow to reproduce: the job's steps as written, in that image
5eaaf7fb8e5150d1LongshotBuilder-Setup.exelongshot_vk.dllLONGSHOT_FSR=1also linksTesting
Tested:
act-24.04container: the setup,dotnet publish,builder_package.py packageandzip,check_windows_files.py(output above).RX_TARGET=windows, pinned headers) in the same container:longshot_vk.dlllinks, imports onlyKERNEL32,USER32and the UCRT'sapi-ms-win-crt-*.dotnet build(Debug) of the builder, and thetests/builder_workerscheck on Linux: "Windows Builder worker checks passed (104 assertions)".--play <empty folder>and the builder's--cliboth say why they stop. The builder needs Xvfb, because WPF'sApplicationmakes a hidden window first; without a display it throws inHwndWrapper. Wine'smscoreemust stay enabled: overriding it off breaks loading .NET's IL assemblies ("Could not load System.Runtime.dll"). With those two settled it passed 6 of 6 runs, 5 of them from a fresh prefix, in about 9 s, so it is a workflow step.LONGSHOT_VULKAN_HEADERS=/usr/include python -I -B tests/run_all.py, interleaved, 2 runs each. main @f41db065: 490 passed, 2 failed, 36 skipped (both runs). This PR: 491 passed, 2 failed, 36 skipped (both runs; +1 istest_windows_on_linux.py). The 2 failures are the same on both and known on main:test_bake_portability,test_builder_log_read_only. After the rebase onto main @5eaaf7fb, one more interleaved pair: main 491 passed, this PR 492 passed, the same 2 failures and 36 skipped on both.Not tested:
vulkan-dlss.yml): not run locally, because it downloads NVIDIA's SDK under its license. The FSR 4 part linked locally..gitattributesforces LF, so checkout line endings can't differ. The builder'sApplicationIconis conditional onwork/longshot.ico, which no CI checkout has. So the WPF exe has no custom icon, as it would not have had on Windows either; the setup does have its icon.Needs other testers:
LongshotBuilder.exe(setup installs the builder and tools), build from your own copy and reach the title screen. Expect the setup icon, the builder's fonts and image, and no SmartScreen/antivirus removal beyond what unsigned files got before (T-FCA3)python -I -B tests/run_all.py --strict, plus the MSVC commands in RELEASING.md, Needs a Windows tester. Expect everything to pass (T-FCA3)Screenshots
Nothing on screen
Risk and rollback
If a Windows file built on Linux differs from a Windows build in a way the checks don't cover, the symptom would be a broken install for Windows players. That is what the rc's Windows tester step is for. Reverting the commit restores the windows-2022 jobs, which would again queue forever without a Windows runner.
Reviewer notes
Start with
build-windows.yml's package job andscripts/check_windows_files.py.RELEASING.mdanddocs/releases.mdare shared byte-identical with MagicBeanDev/LongshotLauncher: this commit's changes to both need copying there.Issues
None
Checklist
For everyone
type(scope): description).main.python -I -B tests/run_all.pyrun and passing (any failure that also fails onmainis named above).third_party/untouched (a new folder with aPROVENANCE.mdinstead).If applicable
mainand passing here.tests/that reads changed source updated in this PR, not weakened. (test_recomplauncher_json.pyandtest_ship_state_list.pyreadbuild-windows.ymlandbuilder_package.pyand pass unchanged; the newtest_windows_on_linux.pyreads the workflows andbuilder_package.py.)Description filled in: what changed, the MSI and Wine decisions, the container run of the package and Vulkan jobs (artifacts and sizes), and the interleaved test runs (main 490 passed / this PR 491 passed, the same 2 known failures on both).
6943794c788e5150d1deRebased onto main @
5eaaf7fb(now8e5150d1). Built again there in the act-24.04 container: the zip is 73,930,773 bytes with 1608 files, the setup 193,536 bytes, longshot_vk.dll 13,417,984 bytes; the file checks and both Wine starts pass. One more interleaved test pair: main 491 passed, this PR 492 passed, with the same 2 known failures. The description follows the updated template (Flags and settings, If applicable).Opened the Windows test request T-FCA3 (the builder end to end; the suite on Windows' Python and the MSVC checks).
WIP: ci(windows): build the Windows release files on the Linux runnerto ci(windows): build the Windows release files on the Linux runnerllun referenced this pull request2026-11-13 03:02:42 +00:00