143 lines
8.1 KiB
YAML
143 lines
8.1 KiB
YAML
name: Windows build and validation
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
push:
|
|
paths:
|
|
- "src/**"
|
|
- "tests/**"
|
|
- "mods/**"
|
|
- "data/**"
|
|
- "art/**"
|
|
- "bin/**"
|
|
- "Cargo.toml"
|
|
- "Cargo.lock"
|
|
- "run.cmd"
|
|
- "runtime-manifest.json"
|
|
- ".gitattributes"
|
|
- "runtime-windows-manifest.json"
|
|
- "tools/assemble_windows.py"
|
|
- "tools/assemble_runtime.py"
|
|
- ".github/workflows/windows.yml"
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
windows:
|
|
runs-on: windows-latest
|
|
timeout-minutes: 60
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-python@v5
|
|
with:
|
|
python-version: "3.13"
|
|
- name: Install the pinned Rust toolchain
|
|
run: |
|
|
rustup toolchain install 1.99.0 --profile minimal
|
|
rustup default 1.99.0
|
|
- name: Download and verify the official SDL2 SDK
|
|
shell: pwsh
|
|
run: |
|
|
$url = "https://github.com/libsdl-org/SDL/releases/download/release-2.32.10/SDL2-devel-2.32.10-VC.zip"
|
|
Invoke-WebRequest $url -OutFile "$env:RUNNER_TEMP\SDL2.zip"
|
|
$expected = "af347939395a58b365846aaea27391e69f9ec9d4dd650d6ac40802159b418a6e"
|
|
if ((Get-FileHash "$env:RUNNER_TEMP\SDL2.zip" -Algorithm SHA256).Hash.ToLower() -ne $expected) {
|
|
throw "SDL2 SDK checksum mismatch"
|
|
}
|
|
Expand-Archive "$env:RUNNER_TEMP\SDL2.zip" "$env:RUNNER_TEMP\sdl2"
|
|
- name: Run portable simulation, mod and Windows save tests
|
|
run: cargo test --locked --no-default-features
|
|
- name: Complete Black Tide with carried pilot saves and paid repairs
|
|
shell: pwsh
|
|
run: |
|
|
$env:RAPTOR_TEST_DATA = "$env:GITHUB_WORKSPACE\data"
|
|
$env:RAPTOR_STAGE2_REPORT = "$env:RUNNER_TEMP\stage2-route.json"
|
|
cargo test --release --locked --no-default-features --test iron_coast_stage2 starter_ship_completes_all_eight_missions_with_paid_repairs_and_finale_replay -- --ignored --nocapture
|
|
if ($LASTEXITCODE -ne 0) { throw "Native Windows campaign continuation failed" }
|
|
- name: Check the included Windows executable and launcher
|
|
shell: pwsh
|
|
run: |
|
|
$package = $env:GITHUB_WORKSPACE
|
|
$manifest = Get-Content "$package\runtime-windows-manifest.json" -Raw | ConvertFrom-Json
|
|
foreach ($entry in $manifest.files.PSObject.Properties) {
|
|
$actual = (Get-FileHash (Join-Path $package $entry.Name) -Algorithm SHA256).Hash.ToLower()
|
|
if ($actual -ne $entry.Value) { throw "Bundled Windows hash mismatch: $($entry.Name)" }
|
|
}
|
|
Set-Location $env:RUNNER_TEMP
|
|
& "$package\run.cmd" --verify-assets
|
|
if ($LASTEXITCODE -ne 0) { throw "Included Windows launcher failed" }
|
|
$env:SDL_VIDEODRIVER = "dummy"
|
|
$env:SDL_AUDIODRIVER = "dummy"
|
|
& "$package\run.cmd" --profile-root "$env:RUNNER_TEMP\bundled-profile" --smoke-frames 32 --preview-mission base:sector_1_wave_1
|
|
if ($LASTEXITCODE -ne 0) { throw "Included Windows SDL gameplay failed" }
|
|
- name: Build and package Windows desktop
|
|
run: python tools/assemble_windows.py --target x86_64-pc-windows-msvc --sdl2-dir "$env:RUNNER_TEMP\sdl2\SDL2-2.32.10" --zip dist/RustRaptor-windows-x86_64.zip
|
|
- name: Check displayed boss phases and SD HD shop artwork
|
|
shell: pwsh
|
|
run: |
|
|
$separator = [char]31
|
|
$sdkLibrary = "$env:RUNNER_TEMP\sdl2\SDL2-2.32.10\lib\x64"
|
|
$env:CARGO_ENCODED_RUSTFLAGS = "-L${separator}native=$sdkLibrary${separator}-C${separator}target-feature=+crt-static"
|
|
$env:PATH = "$env:GITHUB_WORKSPACE\bin;$env:PATH"
|
|
cargo test --release --locked --target x86_64-pc-windows-msvc --target-dir target/windows-runtime --lib scripted_enemy_phase_frames_reach_sd_hd_sprites_and_both_shadow_layers -- --nocapture
|
|
if ($LASTEXITCODE -ne 0) { throw "Windows phase sprite and shadow regression failed" }
|
|
cargo test --release --locked --target x86_64-pc-windows-msvc --target-dir target/windows-runtime --lib iron_coast_stage2_art_and_shop_preview_captures_preserve_simulation -- --ignored --nocapture
|
|
if ($LASTEXITCODE -ne 0) { throw "Windows Stage2 SD HD phase and shop preview failed" }
|
|
Remove-Item Env:CARGO_ENCODED_RUSTFLAGS
|
|
- name: Validate packaged data, HD artwork, mods and SDL gameplay
|
|
shell: pwsh
|
|
run: |
|
|
$portable = "$env:RUNNER_TEMP\Portable Windows Ω folder"
|
|
Expand-Archive "$env:GITHUB_WORKSPACE\dist\RustRaptor-windows-x86_64.zip" $portable
|
|
$package = "$portable\RustRaptor"
|
|
$exe = "$package\bin\raptor-rust.exe"
|
|
Set-Location $env:RUNNER_TEMP
|
|
& "$package\run.cmd" --verify-assets
|
|
if ($LASTEXITCODE -ne 0) { throw "Catalog validation failed" }
|
|
& $exe --validate-hd
|
|
if ($LASTEXITCODE -ne 0) { throw "HD validation failed" }
|
|
$mods = (Get-ChildItem "$package\mods" -Directory | Where-Object { Test-Path "$($_.FullName)\mod.toml" } | ForEach-Object { $_.Name }) -join ","
|
|
& $exe --mods "$package\mods" --profile-root "$env:RUNNER_TEMP\raptor-profile" --validate-mods $mods
|
|
if ($LASTEXITCODE -ne 0) { throw "Mod validation failed" }
|
|
$env:SDL_VIDEODRIVER = "dummy"
|
|
$env:SDL_AUDIODRIVER = "dummy"
|
|
& $exe --profile-root "$env:RUNNER_TEMP\raptor-profile" --smoke-frames 32 --preview-mission base:sector_1_wave_1 --screenshot "$env:GITHUB_WORKSPACE\dist\windows-gameplay.png"
|
|
if ($LASTEXITCODE -ne 0) { throw "Windows SDL gameplay failed" }
|
|
$stageProfile = "$env:RUNNER_TEMP\stage2-profile"
|
|
New-Item -ItemType Directory -Force "$stageProfile\config" | Out-Null
|
|
$selection = (Get-ChildItem "$package\mods" -Directory | Where-Object { Test-Path "$($_.FullName)\mod.toml" } | ForEach-Object { '"' + $_.Name + '"' }) -join ","
|
|
@"
|
|
enabled_mods = [$selection]
|
|
hd_mode = true
|
|
scale = 4
|
|
width = 1920
|
|
height = 1080
|
|
"@ | Set-Content "$stageProfile\config\config.toml" -Encoding utf8
|
|
$env:RAPTOR_AUDIO_CAPTURE = "$env:GITHUB_WORKSPACE\dist\windows-stage2-audio.wav"
|
|
$env:RAPTOR_AUDIO_CAPTURE_SECONDS = "3"
|
|
& $exe --profile-root $stageProfile --smoke-frames 240 --preview-mission iron_coast_stage2_mission_1:mission_01 --screenshot "$env:GITHUB_WORKSPACE\dist\windows-stage2.png"
|
|
if ($LASTEXITCODE -ne 0) { throw "Windows Stage2 SDL gameplay failed" }
|
|
if (!(Test-Path $env:RAPTOR_AUDIO_CAPTURE)) { throw "Windows Stage2 audio capture missing" }
|
|
python -c "import array, wave; w=wave.open(r'$env:RAPTOR_AUDIO_CAPTURE'); p=array.array('h',w.readframes(w.getnframes())); assert w.getframerate()==44100 and w.getnchannels()==2 and w.getnframes()>=44100 and sum(x!=0 for x in p)>1000"
|
|
if ($LASTEXITCODE -ne 0) { throw "Windows Stage2 audio was empty or malformed" }
|
|
Add-Content "$stageProfile\config\config.toml" "music_volume = 0"
|
|
$env:RAPTOR_AUDIO_CAPTURE = "$env:GITHUB_WORKSPACE\dist\windows-stage2-sfx.wav"
|
|
& $exe --profile-root $stageProfile --smoke-frames 240 --preview-mission iron_coast_stage2_mission_8:mission_08
|
|
if ($LASTEXITCODE -ne 0) { throw "Windows Stage2 sound-effect gameplay failed" }
|
|
python -c "import array, wave; w=wave.open(r'$env:RAPTOR_AUDIO_CAPTURE'); p=array.array('h',w.readframes(w.getnframes())); assert w.getframerate()==44100 and w.getnchannels()==2 and w.getnframes()>=44100 and sum(x!=0 for x in p)>1000"
|
|
if ($LASTEXITCODE -ne 0) { throw "Windows Stage2 sound effects were silent" }
|
|
Remove-Item Env:RAPTOR_AUDIO_CAPTURE
|
|
Remove-Item Env:RAPTOR_AUDIO_CAPTURE_SECONDS
|
|
- uses: actions/upload-artifact@v4
|
|
with:
|
|
name: RustRaptor-windows-x86_64
|
|
path: |
|
|
dist/RustRaptor-windows-x86_64.zip
|
|
dist/windows-gameplay.png
|
|
dist/windows-stage2.png
|
|
dist/windows-stage2-audio.wav
|
|
dist/windows-stage2-sfx.wav
|
|
.reference/iron-coast-stage2/visual/*.png
|
|
if-no-files-found: error
|