diff --git a/.github/scripts/generate_matrix.py b/.github/scripts/generate_matrix.py new file mode 100644 index 00000000000..dab717a281c --- /dev/null +++ b/.github/scripts/generate_matrix.py @@ -0,0 +1,52 @@ +import os +import json + + +def get_presets(): + def p(name, replay=False): + return {"preset": name, "tools": True, "extras": True, "replay": replay} + + generals = [ + p("vc6"), + p("vc6-profile"), + p("vc6-debug"), + p("win32"), + p("win32-profile"), + p("win32-debug"), + p("win32-vcpkg"), + p("win32-vcpkg-profile"), + p("win32-vcpkg-debug"), + ] + + # replay=True for retail-compatible builds that need replay testing + generalsmd = [ + p("vc6", replay=True), + p("vc6-profile"), + p("vc6-debug"), + p("vc6-releaselog", replay=True), + p("win32"), + p("win32-profile"), + p("win32-debug"), + p("win32-vcpkg"), + p("win32-vcpkg-profile"), + p("win32-vcpkg-debug"), + ] + + return { + "presets_generals": generals, + "presets_generalsmd": generalsmd, + } + + +if __name__ == "__main__": + matrix_map = get_presets() + + github_output = os.environ.get("GITHUB_OUTPUT") + if github_output: + with open(github_output, "a") as f: + for key, value in matrix_map.items(): + f.write(f"{key}={json.dumps(value)}\n") + else: + for key, value in matrix_map.items(): + print(f"{key}:") + print(json.dumps(value, indent=2)) diff --git a/.github/workflows/build-toolchain.yml b/.github/workflows/build-toolchain.yml index 6dcad70e0de..2b700c697b2 100644 --- a/.github/workflows/build-toolchain.yml +++ b/.github/workflows/build-toolchain.yml @@ -2,7 +2,6 @@ name: Build Toolchain permissions: contents: read - pull-requests: write on: workflow_call: @@ -25,6 +24,11 @@ on: default: false type: boolean description: "Build extras" + replay: + required: false + default: false + type: boolean + description: "Run replay compatibility check after build" jobs: build: @@ -54,7 +58,7 @@ jobs: uses: actions/cache@v4 with: path: build\${{ inputs.preset }}\_deps - key: cmake-deps-${{ inputs.preset }}-${{ hashFiles('CMakePresets.json','cmake/**/*.cmake','**/CMakeLists.txt') }} + key: cmake-deps-${{ inputs.preset }}-${{ hashFiles('CMakePresets.json','cmake/**/*.cmake','Dependencies/**/CMakeLists.txt', 'CMakeLists.txt') }} - name: Download VC6 Portable from itsmattkc repo if: ${{ startsWith(inputs.preset, 'vc6') && steps.cache-vc6.outputs.cache-hit != 'true' }} @@ -106,7 +110,7 @@ jobs: arch: x86 - name: Compute vcpkg cache key parts - if: startsWith(inputs.preset, 'win32') + if: contains(inputs.preset, 'vcpkg') id: vcpkg_key shell: pwsh run: | @@ -128,7 +132,7 @@ jobs: Write-Host "vcpkg cache key parts: baseline=$baseline, msvc=$msvcMajorMinor, triplet=$triplet" - name: Restore vcpkg binary cache - if: startsWith(inputs.preset, 'win32') + if: contains(inputs.preset, 'vcpkg') id: vcpkg_cache uses: actions/cache/restore@v4 with: @@ -139,13 +143,14 @@ jobs: vcpkg-bincache-v2-${{ runner.os }}- - name: Setup vcpkg + if: contains(inputs.preset, 'vcpkg') uses: lukka/run-vcpkg@v11 with: runVcpkgInstall: false doNotCache: true - name: Configure vcpkg to use cached directory - if: startsWith(inputs.preset, 'win32') + if: contains(inputs.preset, 'vcpkg') shell: pwsh run: | $cacheDir = "${{ github.workspace }}\vcpkg-bincache" @@ -182,7 +187,7 @@ jobs: - name: Save vcpkg binary cache # Only one job should save to avoid "Unable to reserve cache" conflicts. - if: ${{ startsWith(inputs.preset, 'win32') && steps.vcpkg_cache.outputs.cache-hit != 'true' && inputs.game == 'Generals' && inputs.preset == 'win32-vcpkg-debug' }} + if: ${{ contains(inputs.preset, 'vcpkg') && steps.vcpkg_cache.outputs.cache-hit != 'true' && inputs.game == 'Generals' && inputs.preset == 'win32-vcpkg-debug' }} uses: actions/cache/save@v4 with: path: ${{ github.workspace }}\vcpkg-bincache @@ -212,3 +217,132 @@ jobs: path: build\${{ inputs.preset }}\${{ inputs.game }}\artifacts retention-days: 30 if-no-files-found: error + + # ───────────────────────────────────────────────────────────────────────── + # Replay Compatibility Check (conditional - controlled by matrix.replay) + # ───────────────────────────────────────────────────────────────────────── + + - name: Checkout Replays Submodule + if: ${{ inputs.replay }} + run: git submodule update --init --recursive GeneralsReplays + + - name: Cache Game Data + if: ${{ inputs.replay }} + id: cache-gamedata + uses: actions/cache@v4 + with: + path: C:\GameData + key: gamedata-permanent-cache-v4 + + - name: Download Game Data from Cloudflare R2 + if: ${{ inputs.replay && steps.cache-gamedata.outputs.cache-hit != 'true' }} + env: + AWS_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }} + AWS_ENDPOINT_URL: ${{ secrets.R2_ENDPOINT_URL }} + EXPECTED_HASH_GENERALS: "37A351AA430199D1F05DEB9E404857DCE7B461A6AC272C5D4A0B5652CDB06372" + EXPECTED_HASH_GENERALSMD: "6837FE1E3009A4C239406C39B1598216C0943EE8ED46BB10626767029AC05E21" + shell: pwsh + run: | + if (-not $env:AWS_ACCESS_KEY_ID -or -not $env:AWS_SECRET_ACCESS_KEY -or -not $env:AWS_ENDPOINT_URL) { + Write-Host "One or more required secrets are not set or are empty." + exit 1 + } + + Write-Host "Downloading Game Data for Generals" -ForegroundColor Cyan + aws s3 cp s3://github-ci/generals108_gamedata_trimmed.7z generals108_gamedata_trimmed.7z --endpoint-url $env:AWS_ENDPOINT_URL + $fileHash = (Get-FileHash -Path generals108_gamedata_trimmed.7z -Algorithm SHA256).Hash + if ($fileHash -ne $env:EXPECTED_HASH_GENERALS) { + Write-Error "Hash verification failed for Generals!" + exit 1 + } + & 7z x generals108_gamedata_trimmed.7z -o"C:\GameData\Generals" + Remove-Item generals108_gamedata_trimmed.7z + + Write-Host "Downloading Game Data for GeneralsMD" -ForegroundColor Cyan + aws s3 cp s3://github-ci/zerohour104_gamedata_trimmed.7z zerohour104_gamedata_trimmed.7z --endpoint-url $env:AWS_ENDPOINT_URL + $fileHash = (Get-FileHash -Path zerohour104_gamedata_trimmed.7z -Algorithm SHA256).Hash + if ($fileHash -ne $env:EXPECTED_HASH_GENERALSMD) { + Write-Error "Hash verification failed for GeneralsMD!" + exit 1 + } + & 7z x zerohour104_gamedata_trimmed.7z -o"C:\GameData\GeneralsMD" + Remove-Item zerohour104_gamedata_trimmed.7z + + - name: Set Up Game Data for Replay + if: ${{ inputs.replay }} + shell: pwsh + run: | + $buildDir = "build\${{ inputs.preset }}\${{ inputs.game }}\artifacts" + Copy-Item -Path "C:\GameData\${{ inputs.game }}\*" -Destination $buildDir -Recurse -Force + + - name: Set Generals InstallPath in Registry + if: ${{ inputs.replay }} + shell: pwsh + run: | + $regPath = "HKCU:\SOFTWARE\Electronic Arts\EA Games\Generals" + if (-not (Test-Path $regPath)) { New-Item -Path $regPath -Force | Out-Null } + Set-ItemProperty -Path $regPath -Name InstallPath -Value "C:\GameData\Generals\" -Type String + + - name: Copy Replays and Maps to User Dir + if: ${{ inputs.replay }} + shell: pwsh + run: | + $replaySource = "GeneralsReplays/GeneralsZH/1.04/Replays" + $replayDest = "$env:USERPROFILE\Documents\Command and Conquer Generals Zero Hour Data\Replays" + New-Item -ItemType Directory -Path $replayDest -Force | Out-Null + Copy-Item -Path "$replaySource\*" -Destination $replayDest -Recurse -Force + + $mapSource = "GeneralsReplays/GeneralsZH/1.04/Maps" + $mapDest = "$env:USERPROFILE\Documents\Command and Conquer Generals Zero Hour Data\Maps" + New-Item -ItemType Directory -Path $mapDest -Force | Out-Null + Copy-Item -Path "$mapSource\*" -Destination $mapDest -Recurse -Force + + - name: Run Replay Compatibility Tests + if: ${{ inputs.replay }} + shell: pwsh + run: | + $buildDir = "build\${{ inputs.preset }}\${{ inputs.game }}\artifacts" + $exePath = "$buildDir/generalszh.exe" + $arguments = "-jobs 4 -headless -replay *.rep" + $timeoutSeconds = 600 + $stdoutPath = "stdout.log" + $stderrPath = "stderr.log" + + if (-not (Test-Path $exePath)) { + Write-Host "ERROR: Executable not found at $exePath" + exit 1 + } + + Remove-Item $stdoutPath, $stderrPath -ErrorAction SilentlyContinue + Write-Host "Run $exePath $arguments" + $process = Start-Process -FilePath $exePath -ArgumentList $arguments -RedirectStandardOutput $stdoutPath -RedirectStandardError $stderrPath -PassThru + $exited = $process.WaitForExit($timeoutSeconds * 1000) + + if (-not $exited) { + Write-Host "ERROR: Process timed out after $timeoutSeconds seconds" + Stop-Process -Id $process.Id -Force + } + + Write-Host "=== STDOUT ===" + Get-Content $stdoutPath + if ((Test-Path $stderrPath) -and (Get-Item $stderrPath).Length -gt 0) { + Write-Host "`n=== STDERR ===" + Get-Content $stderrPath + } + + if (-not $exited) { exit 1 } + if ($process.ExitCode -ne 0) { + Write-Host "ERROR: Process failed with exit code $($process.ExitCode)" + exit $process.ExitCode + } + Write-Host "Success!" + + - name: Upload Replay Debug Log + if: ${{ inputs.replay && always() }} + uses: actions/upload-artifact@v4 + with: + name: Replay-Debug-Log-${{ inputs.preset }} + path: build\${{ inputs.preset }}\${{ inputs.game }}\artifacts\DebugLogFile*.txt + retention-days: 30 + if-no-files-found: ignore diff --git a/.github/workflows/check-replays.yml b/.github/workflows/check-replays.yml deleted file mode 100644 index 0f10f67d85b..00000000000 --- a/.github/workflows/check-replays.yml +++ /dev/null @@ -1,242 +0,0 @@ -name: Check Replays - -permissions: - contents: read - pull-requests: write - -on: - workflow_call: - inputs: - game: - required: true - type: string - description: "Game to check (only GeneralsMD for now)" - userdata: - required: true - type: string - description: "Path to folder with replays and maps" - preset: - required: true - type: string - description: "CMake preset" - -jobs: - build: - name: ${{ inputs.preset }} - runs-on: windows-2022 - timeout-minutes: 15 - env: - GAME_PATH: C:\GameData - GENERALS_PATH: C:\GameData\Generals - GENERALSMD_PATH: C:\GameData\GeneralsMD - steps: - - name: Checkout Code - uses: actions/checkout@v4 - with: - submodules: true - - - name: Download Game Artifact - uses: actions/download-artifact@v4 - with: - name: ${{ inputs.game }}-${{ inputs.preset }} - path: build - - - name: Cache Game Data - id: cache-gamedata - uses: actions/cache@v4 - with: - path: ${{ env.GAME_PATH }} - key: gamedata-permanent-cache-v4 - - - name: Download Game Data from Cloudflare R2 - if: ${{ steps.cache-gamedata.outputs.cache-hit != 'true' }} - env: - AWS_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }} - AWS_ENDPOINT_URL: ${{ secrets.R2_ENDPOINT_URL }} - EXPECTED_HASH_GENERALS: "37A351AA430199D1F05DEB9E404857DCE7B461A6AC272C5D4A0B5652CDB06372" - EXPECTED_HASH_GENERALSMD: "6837FE1E3009A4C239406C39B1598216C0943EE8ED46BB10626767029AC05E21" - shell: pwsh - run: | - # Download trimmed gamedata of both Generals 1.08 and Generals Zero Hour 1.04. - # This data cannot be used for playing because it's - # missing textures, audio and gui files. But it's enough for replay checking. - # It's also encrypted because it's not allowed to distribute these files. - - if (-not $env:AWS_ACCESS_KEY_ID -or -not $env:AWS_SECRET_ACCESS_KEY -or -not $env:AWS_ENDPOINT_URL) { - $ok1 = [bool]$env:AWS_ACCESS_KEY_ID - $ok2 = [bool]$env:AWS_SECRET_ACCESS_KEY - $ok3 = [bool]$env:AWS_ENDPOINT_URL - Write-Host "One or more required secrets are not set or are empty. R2_ACCESS_KEY_ID: $ok1, R2_SECRET_ACCESS_KEY: $ok2, R2_ENDPOINT_URL: $ok3" - exit 1 - } - - # Download Generals Game Files - # The archive contains these files: - # BINKW32.DLL - # English.big - # INI.big - # Maps.big - # mss32.dll - # W3D.big - # Data\Scripts\MultiplayerScripts.scb - # Data\Scripts\SkirmishScripts.scb - - Write-Host "Downloading Game Data for Generals" -ForegroundColor Cyan - aws s3 cp s3://github-ci/generals108_gamedata_trimmed.7z generals108_gamedata_trimmed.7z --endpoint-url $env:AWS_ENDPOINT_URL - - Write-Host "Verifying File Integrity" -ForegroundColor Cyan - $fileHash = (Get-FileHash -Path generals108_gamedata_trimmed.7z -Algorithm SHA256).Hash - Write-Host "Downloaded file SHA256: $fileHash" - Write-Host "Expected file SHA256: $env:EXPECTED_HASH_GENERALS" - if ($fileHash -ne $env:EXPECTED_HASH_GENERALS) { - Write-Error "Hash verification failed! File may be corrupted or tampered with." - exit 1 - } - - Write-Host "Extracting Archive" -ForegroundColor Cyan - $extractPath = $env:GENERALS_PATH - & 7z x generals108_gamedata_trimmed.7z -o"$extractPath" - Remove-Item generals108_gamedata_trimmed.7z -Verbose - - # Download GeneralsMD (ZH) Game Files - # The archive contains these files: - # BINKW32.DLL - # INIZH.big - # MapsZH.big - # mss32.dll - # W3DZH.big - # Data\Scripts\MultiplayerScripts.scb - # Data\Scripts\Scripts.ini - # Data\Scripts\SkirmishScripts.scb - - Write-Host "Downloading Game Data for GeneralsMD" -ForegroundColor Cyan - aws s3 cp s3://github-ci/zerohour104_gamedata_trimmed.7z zerohour104_gamedata_trimmed.7z --endpoint-url $env:AWS_ENDPOINT_URL - - Write-Host "Verifying File Integrity" -ForegroundColor Cyan - $fileHash = (Get-FileHash -Path zerohour104_gamedata_trimmed.7z -Algorithm SHA256).Hash - Write-Host "Downloaded file SHA256: $fileHash" - Write-Host "Expected file SHA256: $env:EXPECTED_HASH_GENERALSMD" - if ($fileHash -ne $env:EXPECTED_HASH_GENERALSMD) { - Write-Error "Hash verification failed! File may be corrupted or tampered with." - exit 1 - } - - Write-Host "Extracting Archive" -ForegroundColor Cyan - $extractPath = $env:GENERALSMD_PATH - & 7z x zerohour104_gamedata_trimmed.7z -o"$extractPath" - Remove-Item zerohour104_gamedata_trimmed.7z -Verbose - - - name: Set Up Game Data - shell: pwsh - run: | - $source = "$env:GAME_PATH\${{ inputs.game }}" - $destination = "build" - Copy-Item -Path $source\* -Destination $destination -Recurse -Force - - - name: Set Generals InstallPath in Registry - shell: pwsh - run: | - # Zero Hour loads some Generals files and needs this registry key to find the - # Generals data files. - - $regPath = "HKCU:\SOFTWARE\Electronic Arts\EA Games\Generals" - $installPath = "$env:GENERALS_PATH\" - - # Ensure the key exists - if (-not (Test-Path $regPath)) { - New-Item -Path $regPath -Force | Out-Null - } - - # Set the InstallPath value - Set-ItemProperty -Path $regPath -Name InstallPath -Value $installPath -Type String - Write-Host "Registry key set: $regPath -> InstallPath = $installPath" - - - name: Move Replays and Maps to User Dir - shell: pwsh - run: | - # These files are expected in the user dir, so we move them here. - - $source = "${{ inputs.userdata }}\Replays" - $destination = "$env:USERPROFILE\Documents\Command and Conquer Generals Zero Hour Data\Replays" - Write-Host "Move replays to $destination" - New-Item -ItemType Directory -Path $destination -Force | Out-Null - Move-Item -Path "$source\*" -Destination $destination -Force - - $source = "${{ inputs.userdata }}\Maps" - $destination = "$env:USERPROFILE\Documents\Command and Conquer Generals Zero Hour Data\Maps" - Write-Host "Move maps to $destination" - New-Item -ItemType Directory -Path $destination -Force | Out-Null - Move-Item -Path "$source\*" -Destination $destination -Force - - - name: Run Replay Compatibility Tests - shell: pwsh - run: | - $exePath = "build/generalszh.exe" - $arguments = "-jobs 4 -headless -replay *.rep" - $timeoutSeconds = 10*60 - $stdoutPath = "stdout.log" - $stderrPath = "stderr.log" - - if (-not (Test-Path $exePath)) { - Write-Host "ERROR: Executable not found at $exePath" - exit 1 - } - - # Note that the game is a gui application. That means we need to redirect console output to a file - # in order to retrieve it. - # Clean previous logs - Remove-Item $stdoutPath, $stderrPath -ErrorAction SilentlyContinue - - # Start the process - Write-Host "Run $exePath $arguments" - $process = Start-Process -FilePath $exePath ` - -ArgumentList $arguments ` - -RedirectStandardOutput $stdoutPath ` - -RedirectStandardError $stderrPath ` - -PassThru - - # Wait with timeout - $exited = $process.WaitForExit($timeoutSeconds * 1000) - - if (-not $exited) { - Write-Host "ERROR: Process still running after $timeoutSeconds seconds. Killing process..." - Stop-Process -Id $process.Id -Force - } - - # Read output - Write-Host "=== STDOUT ===" - Get-Content $stdoutPath - - if ((Test-Path $stderrPath) -and (Get-Item $stderrPath).Length -gt 0) { - Write-Host "`n=== STDERR ===" - Get-Content $stderrPath - } - - if (-not $exited) { - exit 1 - } - - # Check exit code - $exitCode = $process.ExitCode - - # The above doesn't work on all Windows versions. If not, try this: (see https://stackoverflow.com/a/16018287) - #$process.HasExited | Out-Null # Needs to be called for the command below to work correctly - #$exitCode = $process.GetType().GetField('exitCode', 'NonPublic, Instance').GetValue($process) - #Write-Host "exit code $exitCode" - - if ($exitCode -ne 0) { - Write-Host "ERROR: Process failed with exit code $exitCode" - exit $exitCode - } - - Write-Host "Success!" - - - name: Upload Debug Log - if: always() - uses: actions/upload-artifact@v4 - with: - name: Replay-Debug-Log-${{ inputs.preset }} - path: build/DebugLogFile*.txt - retention-days: 30 - if-no-files-found: ignore diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0420bc2e276..750165cc0b5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,6 +26,8 @@ jobs: generals: ${{ steps.filter.outputs.generals }} generalsmd: ${{ steps.filter.outputs.generalsmd }} shared: ${{ steps.filter.outputs.shared }} + presets_generals: ${{ steps.matrix.outputs.presets_generals }} + presets_generalsmd: ${{ steps.matrix.outputs.presets_generalsmd }} steps: - name: Checkout Code uses: actions/checkout@v4 @@ -34,7 +36,7 @@ jobs: uses: dorny/paths-filter@v3 id: filter with: - token: '' + token: "" filters: | generals: - 'Generals/**' @@ -48,6 +50,15 @@ jobs: - 'Core/**' - 'Dependencies/**' + - name: Define Build Matrix + id: matrix + shell: python + run: | + import os + script_path = os.path.join('.github', 'scripts', 'generate_matrix.py') + with open(script_path, 'r') as file: + exec(file.read()) + - name: Changes Summary run: | echo "### 🔍 File Changes Summary" >> $GITHUB_STEP_SUMMARY @@ -61,34 +72,7 @@ jobs: if: ${{ github.event_name == 'workflow_dispatch' || needs.detect-changes.outputs.generals == 'true' || needs.detect-changes.outputs.shared == 'true' }} strategy: matrix: - include: - - preset: "vc6" - tools: true - extras: true - - preset: "vc6-profile" - tools: true - extras: true - - preset: "vc6-debug" - tools: true - extras: true - - preset: "win32" - tools: true - extras: true - - preset: "win32-profile" - tools: true - extras: true - - preset: "win32-debug" - tools: true - extras: true - - preset: "win32-vcpkg" - tools: true - extras: true - - preset: "win32-vcpkg-profile" - tools: true - extras: true - - preset: "win32-vcpkg-debug" - tools: true - extras: true + include: ${{ fromJson(needs.detect-changes.outputs.presets_generals) }} fail-fast: false uses: ./.github/workflows/build-toolchain.yml with: @@ -96,29 +80,16 @@ jobs: preset: ${{ matrix.preset }} tools: ${{ matrix.tools }} extras: ${{ matrix.extras }} + replay: ${{ matrix.replay }} secrets: inherit - # Note build-generalsmd is split into two jobs for vc6 and win32 because replaycheck-generalsmd - # only requires the vc6 build and compiling vc6 is much faster than win32 - build-generalsmd-vc6: + build-generalsmd: name: Build GeneralsMD${{ matrix.preset && '' }} needs: detect-changes if: ${{ github.event_name == 'workflow_dispatch' || needs.detect-changes.outputs.generalsmd == 'true' || needs.detect-changes.outputs.shared == 'true' }} strategy: matrix: - include: - - preset: "vc6" - tools: true - extras: true - - preset: "vc6-profile" - tools: true - extras: true - - preset: "vc6-debug" - tools: true - extras: true - - preset: "vc6-releaselog" - tools: true - extras: true + include: ${{ fromJson(needs.detect-changes.outputs.presets_generalsmd) }} fail-fast: false uses: ./.github/workflows/build-toolchain.yml with: @@ -126,55 +97,5 @@ jobs: preset: ${{ matrix.preset }} tools: ${{ matrix.tools }} extras: ${{ matrix.extras }} - secrets: inherit - - build-generalsmd-win32: - name: Build GeneralsMD${{ matrix.preset && '' }} - needs: detect-changes - if: ${{ github.event_name == 'workflow_dispatch' || needs.detect-changes.outputs.generalsmd == 'true' || needs.detect-changes.outputs.shared == 'true' }} - strategy: - matrix: - include: - - preset: "win32" - tools: true - extras: true - - preset: "win32-profile" - tools: true - extras: true - - preset: "win32-debug" - tools: true - extras: true - - preset: "win32-vcpkg" - tools: true - extras: true - - preset: "win32-vcpkg-profile" - tools: true - extras: true - - preset: "win32-vcpkg-debug" - tools: true - extras: true - fail-fast: false - uses: ./.github/workflows/build-toolchain.yml - with: - game: "GeneralsMD" - preset: ${{ matrix.preset }} - tools: ${{ matrix.tools }} - extras: ${{ matrix.extras }} - secrets: inherit - - replaycheck-generalsmd: - name: Replay Check GeneralsMD${{ matrix.preset && '' }} - needs: build-generalsmd-vc6 - if: ${{ github.event_name == 'workflow_dispatch' || needs.detect-changes.outputs.generalsmd == 'true' || needs.detect-changes.outputs.shared == 'true' }} - strategy: - matrix: - include: - - preset: "vc6+t+e" - - preset: "vc6-releaselog+t+e" # optimized build with logging and crashing enabled should be compatible, so we test that here. - fail-fast: false - uses: ./.github/workflows/check-replays.yml - with: - game: "GeneralsMD" - userdata: "GeneralsReplays/GeneralsZH/1.04" - preset: ${{ matrix.preset }} + replay: ${{ matrix.replay }} secrets: inherit