Fix and simplify CI caching - #634
Merged
Merged
Conversation
The pip cache key hashes a glob, `hashFiles('**/requirements.txt')`, which walks
the whole ~4500 file workspace including deps/abc to locate a file whose path is
known. That traversal returned no matches on one branch and failed the job
before any build step ran. Hash the file directly instead.
The ccache key of the three Linux workflows referenced
`steps.ccache_cache_timestamp.outputs.timestamp`, but only macOS.yml defines
that step. The key therefore evaluated to a constant `Linux-ccache-`, identical
to its own restore key, which is visible in the run logs:
Cache not found for input keys: Linux-ccache-, Linux-ccache-
With a constant key, the first run to succeed saves the cache and every later
run gets an exact hit and skips saving, so the compiler cache freezes at its
first snapshot and never picks up new objects. Add the missing timestamp step so
the key is unique per run and the restore key prefix matches the newest entry.
Also:
* macOS.yml produced that timestamp via `::set-output`, which GitHub deprecated
and warns about on every run. Write to `$GITHUB_OUTPUT` instead. Both
platforms now use the same shell snippet and the same key format.
* Drop the `Cache CCache` step of the Linux workflows. It cached `~/.ccache`
while `CCACHE_DIR` points at `${{runner.workspace}}/.ccache`, so it archived an
empty directory, and its restore keys referenced an undefined
`env.cache-name`.
* Drop the `Cache pip macOS` step from the Linux workflows, where its
`startsWith(runner.os, 'macOS')` condition can never be true.
* Add a concurrency group so that pushing again to a branch cancels the
superseded run. Runs on master are exempt so the documentation deployment
always completes.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
julianspeith
requested review from
SimonKlx,
joern274,
nils1603 and
swallat
as code owners
August 11, 2026 15:17
Follow-up cleanups to the workflow files: * Replace the deprecated actions/checkout@v1 (macOS) and @v2 (the rest) with @v4. Both force a Node 24 shim on every run. Since @v4 takes fetch-depth, the three hand-written 'git fetch' steps of the Linux workflows are no longer needed; 'fetch-depth: 0' provides the full history and tags that cmake/hal_cmake_tools.cmake needs for 'git describe --tags'. This also removes 'git fetch --prune --unshallow', which failed run 31498874580 on master with "fatal: shallow file has changed since we read it". * Restrict the push trigger to master and add a pull_request trigger. Every push to any branch previously started four workflows of roughly 50 minutes each, including a full documentation build on branches that never deploy. Changes now get exactly one run per push through their pull request. * Drop '-DPYBIND11_PYTHON_VERSION=3.6' from the three Linux configure steps. That Python version is long end-of-life, is not present on any supported runner, and the variable is ignored by the pybind11 version HAL requires. * Replace the single-entry build matrix with a plain 'runs-on' and drop the resulting always-true 'startsWith(runner.os, ...)' step conditions. Note that dropping the matrix shortens the reported check names, for example "Build and Test macOS (macOS-latest)" becomes "Build and Test macOS". Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The reported failure
The Ubuntu 22.04 job on
fix/documentationdied at theCache pip Linuxstep:hashFilesreturns an error when the pattern resolves to zero files, and the job stops there — before Install Dependencies, Configure, Build or Test.requirements.txtis present on that branch at the same three paths as on master, the workflow files are byte-identical between the branches, and the trees differ only by six new.rstfiles and two.DS_Storefiles, so the branch content does not explain it. What does stand out is that the pattern makes the runner walk the entire ~4500 file workspace,deps/abcincluded, to find a file whose path is known.This PR hashes the file directly,
hashFiles('requirements.txt'), in all six live occurrences. Same cache key semantics, no workspace traversal.A real caching bug found along the way
The three Linux workflows key their ccache on
${{ steps.ccache_cache_timestamp.outputs.timestamp }}, but onlymacOS.ymldefines aPrepare ccache timestampstep. On Linux the key therefore evaluated to a constant, which the run logs confirm:The primary key and the restore key are the same string.
actions/cacheskips saving when the primary key hits exactly, so once any successful run writesLinux-ccache-, every later run restores that same snapshot and never saves an updated one — the compiler cache freezes at its first contents and stops helping as the tree moves on.Fixed by adding the missing timestamp step to all three Linux workflows, so the key is unique per run and the
Linux-ccache-restore-key prefix picks up the most recent entry.Other cleanups
macOS.ymlgenerated its timestamp with::set-output, which GitHub deprecated and warns about on every run. It now writes to$GITHUB_OUTPUT. Both platforms use the same snippet and key format.Cache CCachestep from the Linux workflows: it cached~/.ccachewhileCCACHE_DIRpoints at${{runner.workspace}}/.ccache, so it archived an empty directory, and its restore keys referenced an undefinedenv.cache-name.Cache pip macOSstep from the Linux workflows, wherestartsWith(runner.os, 'macOS')can never be true.masterare exempt so the documentation deployment always completes.All four workflows parse and keep their step order; only dead steps were removed.
Workflow modernization (second commit)
actions/checkout@v1(macOS) and@v2(the rest) replaced with@v4. Both were deprecated and forced a Node 24 shim on every run. Since@v4acceptsfetch-depth, the three hand-writtengit fetchsteps in the Linux workflows are gone;fetch-depth: 0supplies the full history and tags thatcmake/hal_cmake_tools.cmakeneeds forgit describe --tags. That also removesgit fetch --prune --unshallow, which is what failed run 31498874580 on master withfatal: shallow file has changed since we read it. macOS previously used@v1, which cloned full history implicitly, sofetch-depth: 0preserves its behavior.pushrestricted tomaster,pull_requestadded. Previously every push to every branch started four workflows of roughly 50 minutes each, including a full documentation build on branches that can never deploy. Changes now get exactly one run per push via their pull request, and theDeploy Docstep stays gated ongithub.ref == 'refs/heads/master', which nopull_requestevent satisfies.-DPYBIND11_PYTHON_VERSION=3.6dropped from the three Linux configure steps. That Python is long end-of-life, is not installed on any supported runner, and the variable is ignored by the pybind11 version HAL requires. It appears nowhere else in the tree.runs-on, and the resulting always-truestartsWith(runner.os, ...)step conditions removed (2 in each Ubuntu workflow, 4 inreleaseDoc.yml, 4 inmacOS.yml).Check names change
Dropping the matrix shortens the reported check names:
Build and Test on Ubuntu 22.04 (ubuntu-22.04)Build and Test on Ubuntu 22.04Build and Test on Ubuntu 24.04 (ubuntu-24.04)Build and Test on Ubuntu 24.04Build and Test macOS (macOS-latest)Build and Test macOSBuild and release documentation (ubuntu-22.04)Build and release documentationWorth knowing while reviewing this:
master's branch protection currently lists exactly one required status check,Build (macOS-latest), which no workflow in the repository produces — the macOS job is namedBuild and Test macOS. That required check can never report, so it is already stale today and this rename does not make it worse. Someone with admin rights may want to point it at the real check names above.🤖 Generated with Claude Code