From ddc5aa33bb8c4962e30b5792ace9c81c545d245d Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Mon, 22 Dec 2025 10:40:28 -0500 Subject: [PATCH 01/11] ci(vcpkg): Override VCPKG_DEFAULT_BINARY_CACHE to use cached directory instead of temp dir --- .github/workflows/build-toolchain.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/build-toolchain.yml b/.github/workflows/build-toolchain.yml index 5999ee132b..1a2c1ce4d8 100644 --- a/.github/workflows/build-toolchain.yml +++ b/.github/workflows/build-toolchain.yml @@ -115,6 +115,18 @@ jobs: - name: Setup vcpkg uses: lukka/run-vcpkg@v11 + - name: Force vcpkg binary cache directory + shell: pwsh + run: | + # Override VCPKG_DEFAULT_BINARY_CACHE that lukka/run-vcpkg sets to its own temp dir + # This ensures vcpkg uses our cached directory instead + $cacheDir = "${{ github.workspace }}\vcpkg-bincache" + "VCPKG_DEFAULT_BINARY_CACHE=$cacheDir" >> $env:GITHUB_ENV + "VCPKG_BINARY_SOURCES=clear;files,$cacheDir,readwrite" >> $env:GITHUB_ENV + Write-Host "Forced vcpkg binary cache to: $cacheDir" -ForegroundColor Cyan + Write-Host "VCPKG_DEFAULT_BINARY_CACHE=$env:VCPKG_DEFAULT_BINARY_CACHE" -ForegroundColor Gray + Write-Host "VCPKG_BINARY_SOURCES=$env:VCPKG_BINARY_SOURCES" -ForegroundColor Gray + - name: Configure ${{ inputs.game }} with CMake Using ${{ inputs.preset }}${{ inputs.tools && '+t' || '' }}${{ inputs.extras && '+e' || '' }} Preset shell: pwsh run: | From e004bdae7061fdc3b242c23ac5e49a63094e8715 Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Mon, 22 Dec 2025 11:23:50 -0500 Subject: [PATCH 02/11] ci(vcpkg): Use separate restore/save cache actions and improve cache key with baseline/MSVC/triplet --- .github/workflows/build-toolchain.yml | 48 ++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-toolchain.yml b/.github/workflows/build-toolchain.yml index 1a2c1ce4d8..d223acbaf1 100644 --- a/.github/workflows/build-toolchain.yml +++ b/.github/workflows/build-toolchain.yml @@ -39,13 +39,42 @@ jobs: - name: Checkout Code uses: actions/checkout@v4 - - name: Cache vcpkg binary artifacts - uses: actions/cache@v4 + - name: Compute vcpkg cache key parts + id: vcpkg_key + shell: pwsh + run: | + $baseline = (Get-Content vcpkg.json | ConvertFrom-Json)."builtin-baseline" + + # Try to get MSVC version - check VCToolsVersion first, then try cl.exe + $msvc = $env:VCToolsVersion + if (-not $msvc) { + try { + $clOutput = cl.exe 2>&1 | Out-String + if ($clOutput -match "Version (\d+\.\d+\.\d+\.\d+)") { + $msvc = $matches[1] + } + } catch { + # Compiler not available yet, will be detected after VC2022 setup + } + } + if (-not $msvc) { $msvc = "unknown" } + + $triplet = "x86-windows" + if ("${{ inputs.preset }}" -like "x64*") { $triplet = "x64-windows" } + + "baseline=$baseline" >> $env:GITHUB_OUTPUT + "msvc=$msvc" >> $env:GITHUB_OUTPUT + "triplet=$triplet" >> $env:GITHUB_OUTPUT + Write-Host "vcpkg cache key parts: baseline=$baseline, msvc=$msvc, triplet=$triplet" + + - name: Restore vcpkg binary cache + id: vcpkg_cache + uses: actions/cache/restore@v4 with: path: ${{ github.workspace }}\vcpkg-bincache - key: vcpkg-bincache-${{ runner.os }}-${{ hashFiles('vcpkg.json','vcpkg-lock.json') }}-${{ inputs.preset }} + key: vcpkg-bincache-${{ runner.os }}-msvc${{ steps.vcpkg_key.outputs.msvc }}-baseline${{ steps.vcpkg_key.outputs.baseline }}-${{ steps.vcpkg_key.outputs.triplet }} restore-keys: | - vcpkg-bincache-${{ runner.os }}-${{ hashFiles('vcpkg.json','vcpkg-lock.json') }}- + vcpkg-bincache-${{ runner.os }}-msvc${{ steps.vcpkg_key.outputs.msvc }}-baseline${{ steps.vcpkg_key.outputs.baseline }}- vcpkg-bincache-${{ runner.os }}- - name: Cache VC6 Installation @@ -121,8 +150,10 @@ jobs: # Override VCPKG_DEFAULT_BINARY_CACHE that lukka/run-vcpkg sets to its own temp dir # This ensures vcpkg uses our cached directory instead $cacheDir = "${{ github.workspace }}\vcpkg-bincache" + $env:VCPKG_DEFAULT_BINARY_CACHE = $cacheDir + $env:VCPKG_BINARY_SOURCES = "clear;files,$cacheDir,readwrite" "VCPKG_DEFAULT_BINARY_CACHE=$cacheDir" >> $env:GITHUB_ENV - "VCPKG_BINARY_SOURCES=clear;files,$cacheDir,readwrite" >> $env:GITHUB_ENV + "VCPKG_BINARY_SOURCES=$env:VCPKG_BINARY_SOURCES" >> $env:GITHUB_ENV Write-Host "Forced vcpkg binary cache to: $cacheDir" -ForegroundColor Cyan Write-Host "VCPKG_DEFAULT_BINARY_CACHE=$env:VCPKG_DEFAULT_BINARY_CACHE" -ForegroundColor Gray Write-Host "VCPKG_BINARY_SOURCES=$env:VCPKG_BINARY_SOURCES" -ForegroundColor Gray @@ -150,6 +181,13 @@ jobs: run: | cmake --build --preset ${{ inputs.preset }} + - name: Save vcpkg binary cache + if: steps.vcpkg_cache.outputs.cache-hit != 'true' + uses: actions/cache/save@v4 + with: + path: ${{ github.workspace }}\vcpkg-bincache + key: vcpkg-bincache-${{ runner.os }}-msvc${{ steps.vcpkg_key.outputs.msvc }}-baseline${{ steps.vcpkg_key.outputs.baseline }}-${{ steps.vcpkg_key.outputs.triplet }} + - name: Collect ${{ inputs.game }} ${{ inputs.preset }}${{ inputs.tools && '+t' || '' }}${{ inputs.extras && '+e' || '' }} Artifact shell: pwsh run: | From 44ae669c9f08a32960282223aa064cc4614cdeb9 Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Mon, 22 Dec 2025 12:09:07 -0500 Subject: [PATCH 03/11] ci(vcpkg): Move cache key computation after VC2022 setup and only save cache on main branch --- .github/workflows/build-toolchain.yml | 67 +++++++++++---------------- 1 file changed, 28 insertions(+), 39 deletions(-) diff --git a/.github/workflows/build-toolchain.yml b/.github/workflows/build-toolchain.yml index d223acbaf1..6cd95770e2 100644 --- a/.github/workflows/build-toolchain.yml +++ b/.github/workflows/build-toolchain.yml @@ -39,44 +39,6 @@ jobs: - name: Checkout Code uses: actions/checkout@v4 - - name: Compute vcpkg cache key parts - id: vcpkg_key - shell: pwsh - run: | - $baseline = (Get-Content vcpkg.json | ConvertFrom-Json)."builtin-baseline" - - # Try to get MSVC version - check VCToolsVersion first, then try cl.exe - $msvc = $env:VCToolsVersion - if (-not $msvc) { - try { - $clOutput = cl.exe 2>&1 | Out-String - if ($clOutput -match "Version (\d+\.\d+\.\d+\.\d+)") { - $msvc = $matches[1] - } - } catch { - # Compiler not available yet, will be detected after VC2022 setup - } - } - if (-not $msvc) { $msvc = "unknown" } - - $triplet = "x86-windows" - if ("${{ inputs.preset }}" -like "x64*") { $triplet = "x64-windows" } - - "baseline=$baseline" >> $env:GITHUB_OUTPUT - "msvc=$msvc" >> $env:GITHUB_OUTPUT - "triplet=$triplet" >> $env:GITHUB_OUTPUT - Write-Host "vcpkg cache key parts: baseline=$baseline, msvc=$msvc, triplet=$triplet" - - - name: Restore vcpkg binary cache - id: vcpkg_cache - uses: actions/cache/restore@v4 - with: - path: ${{ github.workspace }}\vcpkg-bincache - key: vcpkg-bincache-${{ runner.os }}-msvc${{ steps.vcpkg_key.outputs.msvc }}-baseline${{ steps.vcpkg_key.outputs.baseline }}-${{ steps.vcpkg_key.outputs.triplet }} - restore-keys: | - vcpkg-bincache-${{ runner.os }}-msvc${{ steps.vcpkg_key.outputs.msvc }}-baseline${{ steps.vcpkg_key.outputs.baseline }}- - vcpkg-bincache-${{ runner.os }}- - - name: Cache VC6 Installation if: startsWith(inputs.preset, 'vc6') id: cache-vc6 @@ -141,6 +103,33 @@ jobs: with: arch: x86 + - name: Compute vcpkg cache key parts + if: startsWith(inputs.preset, 'win32') + id: vcpkg_key + shell: pwsh + run: | + $baseline = (Get-Content vcpkg.json | ConvertFrom-Json)."builtin-baseline" + $msvc = $env:VCToolsVersion + if (-not $msvc) { $msvc = "unknown" } + + $triplet = "x86-windows" + if ("${{ inputs.preset }}" -like "x64*") { $triplet = "x64-windows" } + + "baseline=$baseline" >> $env:GITHUB_OUTPUT + "msvc=$msvc" >> $env:GITHUB_OUTPUT + "triplet=$triplet" >> $env:GITHUB_OUTPUT + Write-Host "vcpkg cache key parts: baseline=$baseline, msvc=$msvc, triplet=$triplet" + + - name: Restore vcpkg binary cache + if: startsWith(inputs.preset, 'win32') + id: vcpkg_cache + uses: actions/cache/restore@v4 + with: + path: ${{ github.workspace }}\vcpkg-bincache + key: vcpkg-bincache-${{ runner.os }}-msvc${{ steps.vcpkg_key.outputs.msvc }}-baseline${{ steps.vcpkg_key.outputs.baseline }}-${{ steps.vcpkg_key.outputs.triplet }} + restore-keys: | + vcpkg-bincache-${{ runner.os }}-msvc${{ steps.vcpkg_key.outputs.msvc }}-baseline${{ steps.vcpkg_key.outputs.baseline }}- + - name: Setup vcpkg uses: lukka/run-vcpkg@v11 @@ -182,7 +171,7 @@ jobs: cmake --build --preset ${{ inputs.preset }} - name: Save vcpkg binary cache - if: steps.vcpkg_cache.outputs.cache-hit != 'true' + if: startsWith(inputs.preset, 'win32') && steps.vcpkg_cache.outputs.cache-hit != 'true' && github.ref == 'refs/heads/main' uses: actions/cache/save@v4 with: path: ${{ github.workspace }}\vcpkg-bincache From a835a15079929a9361bdfaaa46d16689e92c1eea Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Mon, 22 Dec 2025 12:22:34 -0500 Subject: [PATCH 04/11] ci(vcpkg): Create cache directory before vcpkg runs to fix VCPKG_DEFAULT_BINARY_CACHE error --- .github/workflows/build-toolchain.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build-toolchain.yml b/.github/workflows/build-toolchain.yml index 6cd95770e2..042d13e034 100644 --- a/.github/workflows/build-toolchain.yml +++ b/.github/workflows/build-toolchain.yml @@ -139,6 +139,8 @@ jobs: # Override VCPKG_DEFAULT_BINARY_CACHE that lukka/run-vcpkg sets to its own temp dir # This ensures vcpkg uses our cached directory instead $cacheDir = "${{ github.workspace }}\vcpkg-bincache" + # Ensure the cache directory exists (cache restore may not create it on miss) + New-Item -ItemType Directory -Force -Path $cacheDir | Out-Null $env:VCPKG_DEFAULT_BINARY_CACHE = $cacheDir $env:VCPKG_BINARY_SOURCES = "clear;files,$cacheDir,readwrite" "VCPKG_DEFAULT_BINARY_CACHE=$cacheDir" >> $env:GITHUB_ENV From 29e253242640d4e53cc0cafbeb86a6a5f4597c7e Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Mon, 22 Dec 2025 13:47:47 -0500 Subject: [PATCH 05/11] ci(vcpkg): Move cache save step to end and add debug output --- .github/workflows/build-toolchain.yml | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build-toolchain.yml b/.github/workflows/build-toolchain.yml index 042d13e034..e6e8bfec57 100644 --- a/.github/workflows/build-toolchain.yml +++ b/.github/workflows/build-toolchain.yml @@ -172,13 +172,6 @@ jobs: run: | cmake --build --preset ${{ inputs.preset }} - - name: Save vcpkg binary cache - if: startsWith(inputs.preset, 'win32') && steps.vcpkg_cache.outputs.cache-hit != 'true' && github.ref == 'refs/heads/main' - uses: actions/cache/save@v4 - with: - path: ${{ github.workspace }}\vcpkg-bincache - key: vcpkg-bincache-${{ runner.os }}-msvc${{ steps.vcpkg_key.outputs.msvc }}-baseline${{ steps.vcpkg_key.outputs.baseline }}-${{ steps.vcpkg_key.outputs.triplet }} - - name: Collect ${{ inputs.game }} ${{ inputs.preset }}${{ inputs.tools && '+t' || '' }}${{ inputs.extras && '+e' || '' }} Artifact shell: pwsh run: | @@ -201,3 +194,20 @@ jobs: path: build\${{ inputs.preset }}\${{ inputs.game }}\artifacts retention-days: 30 if-no-files-found: error + + - name: Debug vcpkg cache state + if: ${{ always() && startsWith(inputs.preset, 'win32') }} + shell: pwsh + run: | + Write-Host "vcpkg_cache.cache-hit='${{ steps.vcpkg_cache.outputs.cache-hit }}'" -ForegroundColor Cyan + Write-Host "vcpkg_key.msvc='${{ steps.vcpkg_key.outputs.msvc }}'" -ForegroundColor Cyan + Write-Host "vcpkg_key.baseline='${{ steps.vcpkg_key.outputs.baseline }}'" -ForegroundColor Cyan + Write-Host "vcpkg_key.triplet='${{ steps.vcpkg_key.outputs.triplet }}'" -ForegroundColor Cyan + Write-Host "github.ref='${{ github.ref }}'" -ForegroundColor Cyan + + - name: Save vcpkg binary cache + if: ${{ always() && startsWith(inputs.preset, 'win32') && steps.vcpkg_cache.outputs.cache-hit != 'true' && github.ref == 'refs/heads/main' }} + uses: actions/cache/save@v4 + with: + path: ${{ github.workspace }}\vcpkg-bincache + key: vcpkg-bincache-${{ runner.os }}-msvc${{ steps.vcpkg_key.outputs.msvc }}-baseline${{ steps.vcpkg_key.outputs.baseline }}-${{ steps.vcpkg_key.outputs.triplet }} From a61fa04276c576b77e4362209bddffa7c4196b55 Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Mon, 22 Dec 2025 13:50:43 -0500 Subject: [PATCH 06/11] ci(vcpkg): Temporarily allow cache save on PR branches for testing --- .github/workflows/build-toolchain.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-toolchain.yml b/.github/workflows/build-toolchain.yml index e6e8bfec57..b7c1c13712 100644 --- a/.github/workflows/build-toolchain.yml +++ b/.github/workflows/build-toolchain.yml @@ -206,7 +206,8 @@ jobs: Write-Host "github.ref='${{ github.ref }}'" -ForegroundColor Cyan - name: Save vcpkg binary cache - if: ${{ always() && startsWith(inputs.preset, 'win32') && steps.vcpkg_cache.outputs.cache-hit != 'true' && github.ref == 'refs/heads/main' }} + # TODO: Add back && github.ref == 'refs/heads/main' after testing to prevent PR cache races + if: ${{ always() && startsWith(inputs.preset, 'win32') && steps.vcpkg_cache.outputs.cache-hit != 'true' }} uses: actions/cache/save@v4 with: path: ${{ github.workspace }}\vcpkg-bincache From d56de9319f8b4e11222bc9f3fd3409e9a966e01e Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Mon, 22 Dec 2025 15:21:08 -0500 Subject: [PATCH 07/11] ci(vcpkg): Add comment explaining expected cache save race condition --- .github/workflows/build-toolchain.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-toolchain.yml b/.github/workflows/build-toolchain.yml index b7c1c13712..d8256f64ca 100644 --- a/.github/workflows/build-toolchain.yml +++ b/.github/workflows/build-toolchain.yml @@ -206,7 +206,10 @@ jobs: Write-Host "github.ref='${{ github.ref }}'" -ForegroundColor Cyan - name: Save vcpkg binary cache - # TODO: Add back && github.ref == 'refs/heads/main' after testing to prevent PR cache races + # Save if cache was not hit (cache-hit != 'true' handles both 'false' and empty string cases) + # Note: All 6 parallel jobs may attempt to save the same cache key simultaneously. + # This is expected - GitHub Actions ensures only one succeeds, others show harmless warnings. + # See: https://github.com/actions/cache/blob/main/save/README.md if: ${{ always() && startsWith(inputs.preset, 'win32') && steps.vcpkg_cache.outputs.cache-hit != 'true' }} uses: actions/cache/save@v4 with: From e5c25c4ae15e1a06ab6a990d85b5655697ba1039 Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Mon, 22 Dec 2025 15:29:10 -0500 Subject: [PATCH 08/11] ci(vcpkg): Only have Generals win32-vcpkg-debug job save cache to prevent race condition --- .github/workflows/build-toolchain.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-toolchain.yml b/.github/workflows/build-toolchain.yml index d8256f64ca..4928dc1dcd 100644 --- a/.github/workflows/build-toolchain.yml +++ b/.github/workflows/build-toolchain.yml @@ -206,11 +206,10 @@ jobs: Write-Host "github.ref='${{ github.ref }}'" -ForegroundColor Cyan - name: Save vcpkg binary cache - # Save if cache was not hit (cache-hit != 'true' handles both 'false' and empty string cases) - # Note: All 6 parallel jobs may attempt to save the same cache key simultaneously. - # This is expected - GitHub Actions ensures only one succeeds, others show harmless warnings. - # See: https://github.com/actions/cache/blob/main/save/README.md - if: ${{ always() && startsWith(inputs.preset, 'win32') && steps.vcpkg_cache.outputs.cache-hit != 'true' }} + # Only save if cache was not hit AND this is the designated job to save (prevents all 6 jobs from racing) + # We use Generals + win32-vcpkg-debug as the "designated saver" since it's deterministic and always runs + # All other jobs will benefit from the cache once it's saved by this job + if: ${{ always() && startsWith(inputs.preset, 'win32') && 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 From 86cb2f1e08b96b7d544e61286e4875eccc328b06 Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Mon, 22 Dec 2025 15:58:17 -0500 Subject: [PATCH 09/11] ci(vcpkg): Bump cache key to v2 and validate cache is not empty --- .github/workflows/build-toolchain.yml | 38 ++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-toolchain.yml b/.github/workflows/build-toolchain.yml index 4928dc1dcd..cec67518b3 100644 --- a/.github/workflows/build-toolchain.yml +++ b/.github/workflows/build-toolchain.yml @@ -126,13 +126,37 @@ jobs: uses: actions/cache/restore@v4 with: path: ${{ github.workspace }}\vcpkg-bincache - key: vcpkg-bincache-${{ runner.os }}-msvc${{ steps.vcpkg_key.outputs.msvc }}-baseline${{ steps.vcpkg_key.outputs.baseline }}-${{ steps.vcpkg_key.outputs.triplet }} + key: vcpkg-bincache-v2-${{ runner.os }}-msvc${{ steps.vcpkg_key.outputs.msvc }}-baseline${{ steps.vcpkg_key.outputs.baseline }}-${{ steps.vcpkg_key.outputs.triplet }} restore-keys: | - vcpkg-bincache-${{ runner.os }}-msvc${{ steps.vcpkg_key.outputs.msvc }}-baseline${{ steps.vcpkg_key.outputs.baseline }}- + vcpkg-bincache-v2-${{ runner.os }}-msvc${{ steps.vcpkg_key.outputs.msvc }}-baseline${{ steps.vcpkg_key.outputs.baseline }}- + vcpkg-bincache-v2-${{ runner.os }}- - name: Setup vcpkg uses: lukka/run-vcpkg@v11 + - name: Validate vcpkg cache not empty + if: startsWith(inputs.preset, 'win32') + id: vcpkg_cache_validate + shell: pwsh + run: | + $dir = "${{ github.workspace }}\vcpkg-bincache" + if (!(Test-Path $dir)) { + Write-Host "Cache directory does not exist" -ForegroundColor Yellow + "valid=false" >> $env:GITHUB_OUTPUT + exit 0 + } + $files = Get-ChildItem $dir -Recurse -File -ErrorAction SilentlyContinue + $bytes = ($files | Measure-Object Length -Sum).Sum + Write-Host "vcpkg-bincache: $($files.Count) files, $([math]::Round($bytes / 1MB, 2)) MB" -ForegroundColor Cyan + # Consider cache invalid if less than 1MB (empty or nearly empty) + if ($bytes -lt 1048576) { + Write-Host "Cache is too small (< 1MB), treating as invalid" -ForegroundColor Yellow + "valid=false" >> $env:GITHUB_OUTPUT + } else { + Write-Host "Cache appears valid" -ForegroundColor Green + "valid=true" >> $env:GITHUB_OUTPUT + } + - name: Force vcpkg binary cache directory shell: pwsh run: | @@ -200,17 +224,19 @@ jobs: shell: pwsh run: | Write-Host "vcpkg_cache.cache-hit='${{ steps.vcpkg_cache.outputs.cache-hit }}'" -ForegroundColor Cyan + Write-Host "vcpkg_cache_validate.valid='${{ steps.vcpkg_cache_validate.outputs.valid }}'" -ForegroundColor Cyan Write-Host "vcpkg_key.msvc='${{ steps.vcpkg_key.outputs.msvc }}'" -ForegroundColor Cyan Write-Host "vcpkg_key.baseline='${{ steps.vcpkg_key.outputs.baseline }}'" -ForegroundColor Cyan Write-Host "vcpkg_key.triplet='${{ steps.vcpkg_key.outputs.triplet }}'" -ForegroundColor Cyan Write-Host "github.ref='${{ github.ref }}'" -ForegroundColor Cyan - name: Save vcpkg binary cache - # Only save if cache was not hit AND this is the designated job to save (prevents all 6 jobs from racing) - # We use Generals + win32-vcpkg-debug as the "designated saver" since it's deterministic and always runs + # Save if: + # 1. Cache was not hit OR cache is invalid (empty/small) + # 2. This is the designated job (Generals + win32-vcpkg-debug) to prevent all 6 jobs from racing # All other jobs will benefit from the cache once it's saved by this job - if: ${{ always() && startsWith(inputs.preset, 'win32') && steps.vcpkg_cache.outputs.cache-hit != 'true' && inputs.game == 'Generals' && inputs.preset == 'win32-vcpkg-debug' }} + if: ${{ always() && startsWith(inputs.preset, 'win32') && (steps.vcpkg_cache.outputs.cache-hit != 'true' || steps.vcpkg_cache_validate.outputs.valid != 'true') && inputs.game == 'Generals' && inputs.preset == 'win32-vcpkg-debug' }} uses: actions/cache/save@v4 with: path: ${{ github.workspace }}\vcpkg-bincache - key: vcpkg-bincache-${{ runner.os }}-msvc${{ steps.vcpkg_key.outputs.msvc }}-baseline${{ steps.vcpkg_key.outputs.baseline }}-${{ steps.vcpkg_key.outputs.triplet }} + key: vcpkg-bincache-v2-${{ runner.os }}-msvc${{ steps.vcpkg_key.outputs.msvc }}-baseline${{ steps.vcpkg_key.outputs.baseline }}-${{ steps.vcpkg_key.outputs.triplet }} From 7e943108d8f8d472e4dd75e709a2f22bdf4a41ce Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Mon, 22 Dec 2025 17:12:10 -0500 Subject: [PATCH 10/11] ci(vcpkg): Simplify cache fix - only essential changes --- .github/workflows/build-toolchain.yml | 71 ++------------------------- 1 file changed, 4 insertions(+), 67 deletions(-) diff --git a/.github/workflows/build-toolchain.yml b/.github/workflows/build-toolchain.yml index cec67518b3..eb3f09584a 100644 --- a/.github/workflows/build-toolchain.yml +++ b/.github/workflows/build-toolchain.yml @@ -103,75 +103,27 @@ jobs: with: arch: x86 - - name: Compute vcpkg cache key parts - if: startsWith(inputs.preset, 'win32') - id: vcpkg_key - shell: pwsh - run: | - $baseline = (Get-Content vcpkg.json | ConvertFrom-Json)."builtin-baseline" - $msvc = $env:VCToolsVersion - if (-not $msvc) { $msvc = "unknown" } - - $triplet = "x86-windows" - if ("${{ inputs.preset }}" -like "x64*") { $triplet = "x64-windows" } - - "baseline=$baseline" >> $env:GITHUB_OUTPUT - "msvc=$msvc" >> $env:GITHUB_OUTPUT - "triplet=$triplet" >> $env:GITHUB_OUTPUT - Write-Host "vcpkg cache key parts: baseline=$baseline, msvc=$msvc, triplet=$triplet" - - name: Restore vcpkg binary cache if: startsWith(inputs.preset, 'win32') id: vcpkg_cache uses: actions/cache/restore@v4 with: path: ${{ github.workspace }}\vcpkg-bincache - key: vcpkg-bincache-v2-${{ runner.os }}-msvc${{ steps.vcpkg_key.outputs.msvc }}-baseline${{ steps.vcpkg_key.outputs.baseline }}-${{ steps.vcpkg_key.outputs.triplet }} - restore-keys: | - vcpkg-bincache-v2-${{ runner.os }}-msvc${{ steps.vcpkg_key.outputs.msvc }}-baseline${{ steps.vcpkg_key.outputs.baseline }}- - vcpkg-bincache-v2-${{ runner.os }}- + key: vcpkg-bincache-${{ runner.os }}-${{ hashFiles('vcpkg.json') }}-${{ inputs.preset }} - name: Setup vcpkg uses: lukka/run-vcpkg@v11 - - name: Validate vcpkg cache not empty + - name: Configure vcpkg to use cached directory if: startsWith(inputs.preset, 'win32') - id: vcpkg_cache_validate - shell: pwsh - run: | - $dir = "${{ github.workspace }}\vcpkg-bincache" - if (!(Test-Path $dir)) { - Write-Host "Cache directory does not exist" -ForegroundColor Yellow - "valid=false" >> $env:GITHUB_OUTPUT - exit 0 - } - $files = Get-ChildItem $dir -Recurse -File -ErrorAction SilentlyContinue - $bytes = ($files | Measure-Object Length -Sum).Sum - Write-Host "vcpkg-bincache: $($files.Count) files, $([math]::Round($bytes / 1MB, 2)) MB" -ForegroundColor Cyan - # Consider cache invalid if less than 1MB (empty or nearly empty) - if ($bytes -lt 1048576) { - Write-Host "Cache is too small (< 1MB), treating as invalid" -ForegroundColor Yellow - "valid=false" >> $env:GITHUB_OUTPUT - } else { - Write-Host "Cache appears valid" -ForegroundColor Green - "valid=true" >> $env:GITHUB_OUTPUT - } - - - name: Force vcpkg binary cache directory shell: pwsh run: | - # Override VCPKG_DEFAULT_BINARY_CACHE that lukka/run-vcpkg sets to its own temp dir - # This ensures vcpkg uses our cached directory instead $cacheDir = "${{ github.workspace }}\vcpkg-bincache" - # Ensure the cache directory exists (cache restore may not create it on miss) New-Item -ItemType Directory -Force -Path $cacheDir | Out-Null $env:VCPKG_DEFAULT_BINARY_CACHE = $cacheDir $env:VCPKG_BINARY_SOURCES = "clear;files,$cacheDir,readwrite" "VCPKG_DEFAULT_BINARY_CACHE=$cacheDir" >> $env:GITHUB_ENV "VCPKG_BINARY_SOURCES=$env:VCPKG_BINARY_SOURCES" >> $env:GITHUB_ENV - Write-Host "Forced vcpkg binary cache to: $cacheDir" -ForegroundColor Cyan - Write-Host "VCPKG_DEFAULT_BINARY_CACHE=$env:VCPKG_DEFAULT_BINARY_CACHE" -ForegroundColor Gray - Write-Host "VCPKG_BINARY_SOURCES=$env:VCPKG_BINARY_SOURCES" -ForegroundColor Gray - name: Configure ${{ inputs.game }} with CMake Using ${{ inputs.preset }}${{ inputs.tools && '+t' || '' }}${{ inputs.extras && '+e' || '' }} Preset shell: pwsh @@ -219,24 +171,9 @@ jobs: retention-days: 30 if-no-files-found: error - - name: Debug vcpkg cache state - if: ${{ always() && startsWith(inputs.preset, 'win32') }} - shell: pwsh - run: | - Write-Host "vcpkg_cache.cache-hit='${{ steps.vcpkg_cache.outputs.cache-hit }}'" -ForegroundColor Cyan - Write-Host "vcpkg_cache_validate.valid='${{ steps.vcpkg_cache_validate.outputs.valid }}'" -ForegroundColor Cyan - Write-Host "vcpkg_key.msvc='${{ steps.vcpkg_key.outputs.msvc }}'" -ForegroundColor Cyan - Write-Host "vcpkg_key.baseline='${{ steps.vcpkg_key.outputs.baseline }}'" -ForegroundColor Cyan - Write-Host "vcpkg_key.triplet='${{ steps.vcpkg_key.outputs.triplet }}'" -ForegroundColor Cyan - Write-Host "github.ref='${{ github.ref }}'" -ForegroundColor Cyan - - name: Save vcpkg binary cache - # Save if: - # 1. Cache was not hit OR cache is invalid (empty/small) - # 2. This is the designated job (Generals + win32-vcpkg-debug) to prevent all 6 jobs from racing - # All other jobs will benefit from the cache once it's saved by this job - if: ${{ always() && startsWith(inputs.preset, 'win32') && (steps.vcpkg_cache.outputs.cache-hit != 'true' || steps.vcpkg_cache_validate.outputs.valid != 'true') && inputs.game == 'Generals' && inputs.preset == 'win32-vcpkg-debug' }} + if: ${{ always() && startsWith(inputs.preset, 'win32') && 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 - key: vcpkg-bincache-v2-${{ runner.os }}-msvc${{ steps.vcpkg_key.outputs.msvc }}-baseline${{ steps.vcpkg_key.outputs.baseline }}-${{ steps.vcpkg_key.outputs.triplet }} + key: vcpkg-bincache-${{ runner.os }}-${{ hashFiles('vcpkg.json') }}-${{ inputs.preset }} From 4adbf76e45802b86dbd9bdf7e67bd271647263ec Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Mon, 22 Dec 2025 17:55:28 -0500 Subject: [PATCH 11/11] ci(vcpkg): Add MSVC version to cache key, restore-keys fallbacks, and prevent lukka/run-vcpkg cache conflicts --- .github/workflows/build-toolchain.yml | 69 ++++++++++++++++++++------- 1 file changed, 51 insertions(+), 18 deletions(-) diff --git a/.github/workflows/build-toolchain.yml b/.github/workflows/build-toolchain.yml index eb3f09584a..8140ac114e 100644 --- a/.github/workflows/build-toolchain.yml +++ b/.github/workflows/build-toolchain.yml @@ -31,10 +31,12 @@ jobs: name: ${{ inputs.preset }}${{ inputs.tools && '+t' || '' }}${{ inputs.extras && '+e' || '' }} runs-on: windows-2022 timeout-minutes: 30 + env: VCPKG_FILE_CACHE: ${{ github.workspace }}\vcpkg-bincache VCPKG_BINARY_SOURCES: clear;files,${{ github.workspace }}\vcpkg-bincache,readwrite VCPKG_FEATURE_FLAGS: manifests,versions,binarycaching + steps: - name: Checkout Code uses: actions/checkout@v4 @@ -82,13 +84,11 @@ jobs: if: startsWith(inputs.preset, 'vc6') shell: pwsh run: | - # Define the base directories as local variables first $VSCommonDir = "C:\VC6\VC6SP6\Common" $MSDevDir = "C:\VC6\VC6SP6\Common\msdev98" $MSVCDir = "C:\VC6\VC6SP6\VC98" $VcOsDir = "WINNT" - # Set the variables in GitHub environment "VSCommonDir=$VSCommonDir" >> $env:GITHUB_ENV "MSDevDir=$MSDevDir" >> $env:GITHUB_ENV "MSVCDir=$MSVCDir" >> $env:GITHUB_ENV @@ -103,16 +103,44 @@ jobs: with: arch: x86 + - name: Compute vcpkg cache key parts + if: startsWith(inputs.preset, 'win32') + id: vcpkg_key + shell: pwsh + run: | + $baseline = (Get-Content vcpkg.json | ConvertFrom-Json)."builtin-baseline" + + $msvc = $env:VCToolsVersion + if (-not $msvc) { $msvc = "unknown" } + + # Reduce churn: keep major.minor (e.g. 14.44) + $msvcMajorMinor = ($msvc -split '\.')[0..1] -join '.' + + $triplet = "x86-windows" + if ("${{ inputs.preset }}" -like "x64*") { $triplet = "x64-windows" } + + "baseline=$baseline" >> $env:GITHUB_OUTPUT + "msvc=$msvcMajorMinor" >> $env:GITHUB_OUTPUT + "triplet=$triplet" >> $env:GITHUB_OUTPUT + + Write-Host "vcpkg cache key parts: baseline=$baseline, msvc=$msvcMajorMinor, triplet=$triplet" + - name: Restore vcpkg binary cache if: startsWith(inputs.preset, 'win32') id: vcpkg_cache uses: actions/cache/restore@v4 with: path: ${{ github.workspace }}\vcpkg-bincache - key: vcpkg-bincache-${{ runner.os }}-${{ hashFiles('vcpkg.json') }}-${{ inputs.preset }} + key: vcpkg-bincache-v2-${{ runner.os }}-msvc${{ steps.vcpkg_key.outputs.msvc }}-baseline${{ steps.vcpkg_key.outputs.baseline }}-${{ steps.vcpkg_key.outputs.triplet }} + restore-keys: | + vcpkg-bincache-v2-${{ runner.os }}-msvc${{ steps.vcpkg_key.outputs.msvc }}-baseline${{ steps.vcpkg_key.outputs.baseline }}- + vcpkg-bincache-v2-${{ runner.os }}- - name: Setup vcpkg uses: lukka/run-vcpkg@v11 + with: + runVcpkgInstall: false + doNotCache: true - name: Configure vcpkg to use cached directory if: startsWith(inputs.preset, 'win32') @@ -120,8 +148,11 @@ jobs: run: | $cacheDir = "${{ github.workspace }}\vcpkg-bincache" New-Item -ItemType Directory -Force -Path $cacheDir | Out-Null + + # lukka/run-vcpkg sets its own temp cache dir; override to force our cached dir $env:VCPKG_DEFAULT_BINARY_CACHE = $cacheDir $env:VCPKG_BINARY_SOURCES = "clear;files,$cacheDir,readwrite" + "VCPKG_DEFAULT_BINARY_CACHE=$cacheDir" >> $env:GITHUB_ENV "VCPKG_BINARY_SOURCES=$env:VCPKG_BINARY_SOURCES" >> $env:GITHUB_ENV @@ -129,8 +160,8 @@ jobs: shell: pwsh run: | $buildFlags = @( - "-DRTS_BUILD_ZEROHOUR=${{ inputs.game == 'GeneralsMD' && 'ON' || 'OFF' }}", - "-DRTS_BUILD_GENERALS=${{ inputs.game == 'Generals' && 'ON' || 'OFF' }}" + "-DRTS_BUILD_ZEROHOUR=${{ inputs.game == 'GeneralsMD' && 'ON' || 'OFF' }}", + "-DRTS_BUILD_GENERALS=${{ inputs.game == 'Generals' && 'ON' || 'OFF' }}" ) $gamePrefix = "${{ inputs.game == 'Generals' && 'GENERALS' || 'ZEROHOUR' }}" @@ -140,7 +171,6 @@ jobs: $buildFlags += "-DRTS_BUILD_${gamePrefix}_EXTRAS=${{ inputs.extras && 'ON' || 'OFF' }}" Write-Host "Build flags: $($buildFlags -join ' | ')" - cmake --preset ${{ inputs.preset }} $buildFlags - name: Build ${{ inputs.game }} with CMake Using ${{ inputs.preset }}${{ inputs.tools && '+t' || '' }}${{ inputs.extras && '+e' || '' }} Preset @@ -148,19 +178,29 @@ jobs: run: | cmake --build --preset ${{ inputs.preset }} + - 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' }} + uses: actions/cache/save@v4 + with: + path: ${{ github.workspace }}\vcpkg-bincache + key: vcpkg-bincache-v2-${{ runner.os }}-msvc${{ steps.vcpkg_key.outputs.msvc }}-baseline${{ steps.vcpkg_key.outputs.baseline }}-${{ steps.vcpkg_key.outputs.triplet }} + - name: Collect ${{ inputs.game }} ${{ inputs.preset }}${{ inputs.tools && '+t' || '' }}${{ inputs.extras && '+e' || '' }} Artifact shell: pwsh run: | $buildDir = "build\${{ inputs.preset }}" $artifactsDir = New-Item -ItemType Directory -Force -Path "$buildDir\${{ inputs.game }}\artifacts" -Verbose - if ("${{ inputs.preset }}" -like "win32*") { - # For win32 preset, look in config-specific subdirectories + if ("${{ inputs.preset }}" -like "win32*") { $configToUse = if ("${{ inputs.preset }}" -match "debug") { "Debug" } else { "Release" } - $files = Get-ChildItem -Path "$buildDir\Core\$configToUse","$buildDir\${{ inputs.game }}\$configToUse" -File | Where-Object { $_.Extension -in @(".exe", ".dll", ".pdb") } -Verbose - } else { - $files = Get-ChildItem -Path "$buildDir\Core","$buildDir\${{ inputs.game }}" -File | Where-Object { $_.Extension -in @(".exe", ".dll", ".pdb") } -Verbose + $files = Get-ChildItem -Path "$buildDir\Core\$configToUse","$buildDir\${{ inputs.game }}\$configToUse" -File | + Where-Object { $_.Extension -in @(".exe", ".dll", ".pdb") } -Verbose + } else { + $files = Get-ChildItem -Path "$buildDir\Core","$buildDir\${{ inputs.game }}" -File | + Where-Object { $_.Extension -in @(".exe", ".dll", ".pdb") } -Verbose } + $files | Move-Item -Destination $artifactsDir -Verbose -Force - name: Upload ${{ inputs.game }} ${{ inputs.preset }}${{ inputs.tools && '+t' || '' }}${{ inputs.extras && '+e' || '' }} Artifact @@ -170,10 +210,3 @@ jobs: path: build\${{ inputs.preset }}\${{ inputs.game }}\artifacts retention-days: 30 if-no-files-found: error - - - name: Save vcpkg binary cache - if: ${{ always() && startsWith(inputs.preset, 'win32') && 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 - key: vcpkg-bincache-${{ runner.os }}-${{ hashFiles('vcpkg.json') }}-${{ inputs.preset }}