From 4b6833584eecc6060d2df0530b48f0b691dff634 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Br=C3=BCbach?= Date: Mon, 5 Oct 2026 15:26:57 +0200 Subject: [PATCH 1/3] [CI] Create the vcpkg cache directory when a scope is still empty --- .github/workflows/desktop-build.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/desktop-build.yml b/.github/workflows/desktop-build.yml index 1bcc044f2..afa694ffc 100644 --- a/.github/workflows/desktop-build.yml +++ b/.github/workflows/desktop-build.yml @@ -451,6 +451,17 @@ jobs: prefix: ${{ matrix.vcpkg_scope }} token: ${{ secrets.GITHUB_TOKEN }} + # The action only creates its directory when the prefix matched at least one + # entry, and it reads that directory unguarded when it saves at the end of the + # job. A scope nobody has written to yet therefore leaves the directory missing + # and fails the job, which is exactly the state every scope starts in. Make the + # directory up front so an empty scope is a cache miss instead of an error. + - name: "Create vcpkg cache directory" + shell: bash + env: + CACHE_DIR: '${{ steps.vcpkg-cache.outputs.path }}' + run: mkdir -p "$CACHE_DIR" + # Uses environment variables, see compile.sh for more details - name: "Build Cockatrice" id: build From 070efcab11135a63ee0ac449021cfedb4347334c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Br=C3=BCbach?= Date: Mon, 5 Oct 2026 18:22:28 +0200 Subject: [PATCH 2/3] [CI] Let a pull request write the vcpkg archives it builds --- .github/workflows/desktop-build.yml | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/desktop-build.yml b/.github/workflows/desktop-build.yml index afa694ffc..111947ef8 100644 --- a/.github/workflows/desktop-build.yml +++ b/.github/workflows/desktop-build.yml @@ -481,12 +481,15 @@ jobs: PACKAGE_SUFFIX: '${{ matrix.package_suffix }}' TARGET_MACOS_VERSION: ${{ matrix.override_target }} USE_CCACHE: ${{ matrix.use_ccache }} - # Only master may write the cache itself. A pull request run has its own - # merge ref scope, which nothing else can read, so anything it saved there - # would be unreachable for every later run. Handing the new archives over - # to vcpkg-cache-import.yml is what lets a pull request heal the shared - # cache after a runner image update changes every ABI hash. - VCPKG_BINARY_SOURCES: "clear;files,${{ steps.vcpkg-cache.outputs.path }},${{ case(github.ref == 'refs/heads/master', 'readwrite', 'read') }}" + # vcpkg has to be allowed to write into the cache directory even on a pull + # request, because that is where "Collect new vcpkg entries" looks for the + # archives this run had to compile itself. With the source left at read those + # archives are never written, the collect step finds nothing, and vcpkg-cache-import.yml + # gets no artifact to heal the shared cache with. The importer is what publishes + # to master's scope; a pull request's own merge ref stays unreadable by every + # later run, so the action's own save there costs quota but nothing else. + # Forks keep the read-only mode, they are the case that must not be trusted. + VCPKG_BINARY_SOURCES: "clear;files,${{ steps.vcpkg-cache.outputs.path }},${{ case(github.ref == 'refs/heads/master' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository), 'readwrite', 'read') }}" VCPKG_DISABLE_METRICS: 1 VCPKG_FEATURE_FLAGS: dependencygraph VCPKG_TARGET_MACOS_VERSION: ${{ matrix.vcpkg_deployment_target }} From 5ddeaf2afb62ec289c10ef1b8a8b127a38fd37d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Br=C3=BCbach?= Date: Mon, 5 Oct 2026 19:47:05 +0200 Subject: [PATCH 3/3] [CI] Upload the vcpkg handover as one archive instead of loose files --- .github/workflows/desktop-build.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/desktop-build.yml b/.github/workflows/desktop-build.yml index 111947ef8..fd2463487 100644 --- a/.github/workflows/desktop-build.yml +++ b/.github/workflows/desktop-build.yml @@ -546,12 +546,15 @@ jobs: echo "count=$count" >>"$GITHUB_OUTPUT" echo "slug=$(sed -e 's|^vcpkg/||' -e 's|/$||' -e 's|/|-|g' <<<"$VCPKG_SCOPE")" >>"$GITHUB_OUTPUT" + # archive: false accepts a single file and nothing else, and a scope hands over one + # archive per ABI hash vcpkg had to rebuild, which is 23 files on a cold runner. + # Zipping the directory keeps the fanout at the artifact root, which is where + # vcpkg-cache-import.yml looks for keys.txt once download-artifact unpacks it. - name: "Upload new vcpkg entries" # An empty count means the step above did not run at all, on master and on forks if: steps.vcpkg_new.outputs.count != '' && steps.vcpkg_new.outputs.count != '0' uses: actions/upload-artifact@v7 with: - archive: false if-no-files-found: error # a count above zero with nothing staged is a bug name: vcpkg-new-${{ steps.vcpkg_new.outputs.slug }} path: ${{ runner.temp }}/vcpkg-new