Tracked under #1487 ("External dependency caching"); this is the detailed plan for the caching item in #2028.
Summary
SCIRun's CI rebuilds the Superbuild externals (the heavy third-party C++ dependencies) from scratch on every run — none of the nine workflows (ccpp.yml, mac.yml, windows.yml, reusable-build.yml, etc.) use any caching. We can cut a large fraction of CI time by caching the externals build output, keyed on the files that define how those externals are built.
This mirrors how our sibling project SCIInstitute/shapeworks handles it: its biggest CI win is a GitHub-native actions/cache of the compiled dependencies (ITK, VTK, OpenVDB, …), keyed on the dependency recipe rather than the project source, so the multi-hour external build is reused across every PR and commit.
The pattern (from ShapeWorks)
Split restore / save, with the build and the save both gated on a cache miss:
- name: Restore Externals Cache
id: cache-externals
uses: actions/cache/restore@v4
with:
path: <superbuild externals install/build dir>
key: ${{ runner.os }}-externals-${{ hashFiles(
'Superbuild/CMakeLists.txt',
'Superbuild/**/*.cmake') }}
- name: Build Externals
if: steps.cache-externals.outputs.cache-hit != 'true'
run: <superbuild configure+build>
- name: Save Externals Cache
if: steps.cache-externals.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
with:
path: <same path>
key: <same key>
Why it works:
- Key hashes the externals recipe, not the source. Keyed on the Superbuild CMake files (+ toolchain/compiler), not on SCIRun's own
.cpp/.h. The cache only invalidates when the externals definition changes, so it survives across normal PRs.
- Split
restore + save (not the combined action) so we can skip both the build and the re-save on a hit.
- Per-variant keys to avoid collisions: include
runner.os, build type (Debug/Release), and on macOS the deployment target / arch.
Scope (this issue = "Step 1" only)
Out of scope (separate follow-up): adding ccache/sccache as a compiler launcher for SCIRun's own sources.
Context
Faster CI directly helps unblock the in-progress C++ modernization work, which is currently gated on new CI testing jobs.
Reference: shapeworks/.github/workflows — build-linux.yml, gha_deps.sh, common.sh.
Summary
SCIRun's CI rebuilds the Superbuild externals (the heavy third-party C++ dependencies) from scratch on every run — none of the nine workflows (
ccpp.yml,mac.yml,windows.yml,reusable-build.yml, etc.) use any caching. We can cut a large fraction of CI time by caching the externals build output, keyed on the files that define how those externals are built.This mirrors how our sibling project SCIInstitute/shapeworks handles it: its biggest CI win is a GitHub-native
actions/cacheof the compiled dependencies (ITK, VTK, OpenVDB, …), keyed on the dependency recipe rather than the project source, so the multi-hour external build is reused across every PR and commit.The pattern (from ShapeWorks)
Split restore / save, with the build and the save both gated on a cache miss:
Why it works:
.cpp/.h. The cache only invalidates when the externals definition changes, so it survives across normal PRs.restore+save(not the combined action) so we can skip both the build and the re-save on a hit.runner.os, build type (Debug/Release), and on macOS the deployment target / arch.Scope (this issue = "Step 1" only)
actions/cache/restore+ gated build +actions/cache/saveintoreusable-build.yml(and any workflow that builds externals directly)Out of scope (separate follow-up): adding
ccache/sccacheas a compiler launcher for SCIRun's own sources.Context
Faster CI directly helps unblock the in-progress C++ modernization work, which is currently gated on new CI testing jobs.
Reference: shapeworks/.github/workflows —
build-linux.yml,gha_deps.sh,common.sh.