Skip to content

Commit 1ce2dbe

Browse files
committed
Merge verified compiler cache into the daemon branch
Combines the ccache steps with this branch's Windows hardening: the protected temp root and profile staging keep their roles, the cache steps slot alongside them, and the strictly per-ref keys apply unchanged. The daemon branch's own CI legs warm from the second push on. Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2 parents 0f60f8d + 129d8f7 commit 1ce2dbe

3 files changed

Lines changed: 135 additions & 4 deletions

File tree

.github/workflows/_test.yml

Lines changed: 83 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,39 @@ jobs:
8181

8282
- name: Install deps (Ubuntu)
8383
if: startsWith(matrix.os, 'ubuntu')
84-
run: sudo apt-get update && sudo apt-get install -y zlib1g-dev
84+
run: sudo apt-get update && sudo apt-get install -y zlib1g-dev ccache
85+
86+
- name: Install ccache (macOS)
87+
if: startsWith(matrix.os, 'macos')
88+
run: command -v ccache >/dev/null 2>&1 || brew install ccache
89+
90+
# Verified compiler cache: CCACHE_COMPILERCHECK=content keys every entry
91+
# on the compiler-binary CONTENT plus the fully preprocessed input, so a
92+
# hit is provably the identical compilation — a stale or foreign cache
93+
# can only miss, never return wrong output (see scripts/env.sh).
94+
# Keys embed github.ref on top of GitHub's own branch scoping: caches are
95+
# STRICTLY per-ref by policy — no base-branch fallback, a new PR builds
96+
# cold once and only its own pushes warm it.
97+
- name: Compiler cache (content-verified)
98+
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
99+
with:
100+
path: ${{ github.workspace }}/.ccache
101+
key: ccache-test-${{ matrix.os }}-${{ matrix.cc }}-${{ github.ref }}-${{ github.sha }}
102+
restore-keys: |
103+
ccache-test-${{ matrix.os }}-${{ matrix.cc }}-${{ github.ref }}-
85104
86105
- name: Test
87106
run: scripts/test.sh CC=${{ matrix.cc }} CXX=${{ matrix.cxx }}
88107
env:
89108
CBM_SKIP_PERF: ${{ inputs.skip_perf && '1' || '' }}
109+
CCACHE_DIR: ${{ github.workspace }}/.ccache
110+
CCACHE_MAXSIZE: 1500M
111+
112+
- name: ccache stats
113+
if: always()
114+
run: ccache -s || true
115+
env:
116+
CCACHE_DIR: ${{ github.workspace }}/.ccache
90117

91118
test-tsan:
92119
runs-on: ubuntu-latest
@@ -95,10 +122,33 @@ jobs:
95122
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
96123

97124
- name: Install deps (Ubuntu)
98-
run: sudo apt-get update && sudo apt-get install -y clang zlib1g-dev
125+
run: sudo apt-get update && sudo apt-get install -y clang zlib1g-dev ccache
126+
127+
- name: Compiler cache (content-verified)
128+
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
129+
with:
130+
path: ${{ github.workspace }}/.ccache
131+
key: ccache-tsan-${{ github.ref }}-${{ github.sha }}
132+
restore-keys: |
133+
ccache-tsan-${{ github.ref }}-
99134
100135
- name: ThreadSanitizer tests
101-
run: make -f Makefile.cbm test-tsan CC=clang CXX=clang++
136+
# This job calls make directly (no env.sh), so route the compilers
137+
# through ccache's Debian masquerade dir; update-ccache-symlinks in the
138+
# ccache postinst has already linked the clang installed above.
139+
run: |
140+
export PATH=/usr/lib/ccache:$PATH
141+
export CCACHE_COMPILERCHECK=content
142+
make -f Makefile.cbm test-tsan CC=clang CXX=clang++
143+
env:
144+
CCACHE_DIR: ${{ github.workspace }}/.ccache
145+
CCACHE_MAXSIZE: 1500M
146+
147+
- name: ccache stats
148+
if: always()
149+
run: ccache -s || true
150+
env:
151+
CCACHE_DIR: ${{ github.workspace }}/.ccache
102152

103153
test-windows:
104154
needs: setup-matrix
@@ -119,6 +169,7 @@ jobs:
119169
mingw-w64-clang-${{ matrix.pkg }}-clang
120170
mingw-w64-clang-${{ matrix.pkg }}-compiler-rt
121171
mingw-w64-clang-${{ matrix.pkg }}-zlib
172+
mingw-w64-clang-${{ matrix.pkg }}-ccache
122173
make
123174
git
124175
@@ -146,6 +197,14 @@ jobs:
146197
Set-Acl -LiteralPath $root -AclObject $acl
147198
"CBM_CI_TEMP_ROOT=$root" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
148199
200+
- name: Compiler cache (content-verified)
201+
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
202+
with:
203+
path: ${{ github.workspace }}/.ccache
204+
key: ccache-test-${{ matrix.os }}-${{ matrix.msystem }}-${{ github.ref }}-${{ github.sha }}
205+
restore-keys: |
206+
ccache-test-${{ matrix.os }}-${{ matrix.msystem }}-${{ github.ref }}-
207+
149208
- name: Test
150209
shell: msys2 {0}
151210
# AddressSanitizer is unavailable on native ARM64 Windows (LLVM ships no
@@ -164,6 +223,15 @@ jobs:
164223
scripts/test.sh CC=clang CXX=clang++ ${{ matrix.os == 'windows-11-arm' && 'SANITIZE=' || '' }}
165224
env:
166225
CBM_SKIP_PERF: ${{ inputs.skip_perf && '1' || '' }}
226+
CCACHE_DIR: ${{ github.workspace }}/.ccache
227+
CCACHE_MAXSIZE: 1500M
228+
229+
- name: ccache stats
230+
if: always()
231+
shell: msys2 {0}
232+
run: ccache -s || true
233+
env:
234+
CCACHE_DIR: ${{ github.workspace }}/.ccache
167235

168236
# Windows product-surface regression guards. Distinct from test-windows above
169237
# (the sanitizer C suite): these drive a real product binary + embedded HTTP UI
@@ -186,6 +254,7 @@ jobs:
186254
install: >-
187255
mingw-w64-clang-x86_64-clang
188256
mingw-w64-clang-x86_64-zlib
257+
mingw-w64-clang-x86_64-ccache
189258
make
190259
git
191260
@@ -197,11 +266,22 @@ jobs:
197266
working-directory: pkg/npm
198267
run: npm test
199268

269+
- name: Compiler cache (content-verified)
270+
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
271+
with:
272+
path: ${{ github.workspace }}/.ccache
273+
key: ccache-guards-${{ github.ref }}-${{ github.sha }}
274+
restore-keys: |
275+
ccache-guards-${{ github.ref }}-
276+
200277
- name: Build product binary with embedded UI
201278
shell: msys2 {0}
202279
# --with-ui builds the frontend (npm) and embeds it, so the drive-picker
203280
# guard's HTTP UI is available. Functional gate only (no sanitizers).
204281
run: scripts/build.sh --with-ui CC=clang CXX=clang++
282+
env:
283+
CCACHE_DIR: ${{ github.workspace }}/.ccache
284+
CCACHE_MAXSIZE: 1500M
205285

206286
- name: Windows regression guards (#636/#357, #618, #548, #423/#20)
207287
shell: pwsh

.github/workflows/pr.yml

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,11 @@ jobs:
8282

8383
- name: Install deps (Ubuntu)
8484
if: matrix.os == 'ubuntu-latest'
85-
run: sudo apt-get update && sudo apt-get install -y zlib1g-dev
85+
run: sudo apt-get update && sudo apt-get install -y zlib1g-dev ccache
86+
87+
- name: Install ccache (macOS)
88+
if: matrix.os == 'macos-14'
89+
run: command -v ccache >/dev/null 2>&1 || brew install ccache
8690

8791
- uses: msys2/setup-msys2@66cd2cce69caa17b53920067426061ca1de3a884 # v2
8892
if: matrix.os == 'windows-latest'
@@ -93,21 +97,38 @@ jobs:
9397
mingw-w64-clang-x86_64-clang
9498
mingw-w64-clang-x86_64-zlib
9599
mingw-w64-clang-x86_64-python3
100+
mingw-w64-clang-x86_64-ccache
96101
make
97102
coreutils
98103
104+
# Verified compiler cache — content-keyed, stale hits impossible by
105+
# construction (see scripts/env.sh).
106+
- name: Compiler cache (content-verified)
107+
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
108+
with:
109+
path: ${{ github.workspace }}/.ccache
110+
key: ccache-smoke-${{ matrix.os }}-${{ github.ref }}-${{ github.sha }}
111+
restore-keys: |
112+
ccache-smoke-${{ matrix.os }}-${{ github.ref }}-
113+
99114
- name: Build prod + smoke (Ubuntu)
100115
if: matrix.os == 'ubuntu-latest'
101116
run: |
102117
scripts/build.sh CC=gcc CXX=g++
103118
scripts/smoke-test.sh "$(pwd)/build/c/codebase-memory-mcp"
119+
env:
120+
CCACHE_DIR: ${{ github.workspace }}/.ccache
121+
CCACHE_MAXSIZE: 1000M
104122

105123
- name: Build prod + smoke (macOS)
106124
if: matrix.os == 'macos-14'
107125
run: |
108126
scripts/build.sh CC=cc CXX=c++
109127
codesign --sign - --force build/c/codebase-memory-mcp
110128
scripts/smoke-test.sh "$(pwd)/build/c/codebase-memory-mcp"
129+
env:
130+
CCACHE_DIR: ${{ github.workspace }}/.ccache
131+
CCACHE_MAXSIZE: 1000M
111132

112133
- name: Build prod + smoke (Windows)
113134
if: matrix.os == 'windows-latest'
@@ -127,6 +148,9 @@ jobs:
127148
CBM_CACHE_DIR="$(cygpath -m "$SMOKE_DIR/cache")" \
128149
SMOKE_TEMP_ROOT="$SMOKE_DIR" \
129150
scripts/smoke-test.sh "$SMOKE_DIR/codebase-memory-mcp.exe"
151+
env:
152+
CCACHE_DIR: ${{ github.workspace }}/.ccache
153+
CCACHE_MAXSIZE: 1000M
130154

131155
ci-ok:
132156
# The one required context (besides dco) — fails unless every PR stage

scripts/env.sh

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,33 @@ if [[ -z "${CC:-}" ]]; then
9898
fi
9999
fi
100100

101+
# ── Verified compiler cache (ccache, opt-out CBM_NO_CCACHE=1) ──
102+
# Activated through ccache's masquerade directories so $CC keeps its plain
103+
# name everywhere (verify_compiler, make, link lines are untouched).
104+
# Zero-staleness guarantee: CCACHE_COMPILERCHECK=content keys every entry on
105+
# the CONTENT of the compiler binary plus the fully preprocessed translation
106+
# unit, so a cache hit is provably the identical compilation — a stale or
107+
# foreign cache can only MISS, never return wrong output. No CCACHE_BASEDIR
108+
# and no path rewriting: debug-info and sanitizer report paths stay exact.
109+
if [[ "${CBM_NO_CCACHE:-0}" != "1" ]] && command -v ccache >/dev/null 2>&1; then
110+
for _cbm_ccache_masq in \
111+
/usr/lib/ccache \
112+
/opt/homebrew/opt/ccache/libexec \
113+
/usr/local/opt/ccache/libexec \
114+
/clang64/lib/ccache/bin \
115+
/clangarm64/lib/ccache/bin; do
116+
if [[ -d "$_cbm_ccache_masq" ]]; then
117+
case ":$PATH:" in
118+
*":$_cbm_ccache_masq:"*) ;;
119+
*) PATH="$_cbm_ccache_masq:$PATH" ;;
120+
esac
121+
fi
122+
done
123+
unset _cbm_ccache_masq
124+
export PATH
125+
export CCACHE_COMPILERCHECK=content
126+
fi
127+
101128
# ── Print environment summary ──────────────────────────────────
102129
print_env() {
103130
local context="$1"

0 commit comments

Comments
 (0)