Skip to content

Commit d354081

Browse files
authored
feat(sovereign-ci): opt-in sccache volumes + stats recording (#21)
Adds `enable_sccache: bool` workflow_call input (default false). When set, 4 container jobs (test/lint/coverage/bench) run cargo through sccache with cache at /sccache (host: /home/noah/data/sccache forjar-managed). Each job writes sccache --show-stats JSON to /var/log/ci-metrics/sccache-<runid>-<repo>-<job>.json for F9 falsification gate consumption (docs/specifications/build-performance.md §5.3, §7 Phase 3, step 3). Mount is unconditional to avoid evaluating volume strings (GitHub Actions expression rules on volume lists are awkward). Env vars are what activate sccache — when enable_sccache=false, RUSTC_WRAPPER is empty and cargo calls rustc directly. Pilot rollout: paiml-mcp-agent-toolkit (heavy), forjar (medium), copia (light). F9 gate evaluates p95 hit rate ≥ 40% after 7-day observation window. If met → fleet rollout. If not → shelve per §7.
1 parent 58e5834 commit d354081

1 file changed

Lines changed: 59 additions & 0 deletions

File tree

.github/workflows/sovereign-ci.yml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ on:
5252
required: false
5353
default: ''
5454
type: string
55+
enable_sccache:
56+
description: 'Opt in to sccache compiler cache (build-performance.md §5.3). Pilot repos only until F9 hit-rate ≥ 40% observed over 7 days.'
57+
required: false
58+
default: false
59+
type: boolean
5560

5661
# HD-02: Least-privilege token — only escalate where needed
5762
permissions:
@@ -71,6 +76,12 @@ jobs:
7176
runs-on: [self-hosted, clean-room]
7277
container:
7378
image: localhost:5000/sovereign-ci:stable@sha256:c23c453328df86562ba69410810180d205490c6b202342972f65af7050db6686
79+
# Phase 3 §5.3 — sccache rustc cache + /var/log/ci-metrics for F9 stats.
80+
# Mounted unconditionally (no-op when enable_sccache=false). Self-hosted
81+
# runners are on intel; paths are forjar-managed host dirs.
82+
volumes:
83+
- /home/noah/data/sccache:/sccache
84+
- /var/log/ci-metrics:/var/log/ci-metrics
7485
timeout-minutes: 30
7586
steps:
7687
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
@@ -165,18 +176,32 @@ jobs:
165176
env:
166177
TEST_ARGS: ${{ inputs.test_args }}
167178
REPO_NAME: ${{ inputs.repo }}
179+
RUSTC_WRAPPER: ${{ inputs.enable_sccache && 'sccache' || '' }}
180+
SCCACHE_DIR: ${{ inputs.enable_sccache && '/sccache' || '' }}
168181
run: |
169182
# Mark workspace as safe for git operations inside tests (dubious ownership in containers)
170183
git config --global --add safe.directory "$GITHUB_WORKSPACE"
171184
cargo test --lib $TEST_ARGS 2>&1 || \
172185
cargo test --lib -p "$REPO_NAME" $TEST_ARGS 2>&1 || \
173186
{ echo "::error::Tests failed — check workspace path dependencies"; exit 1; }
187+
- name: Record sccache stats
188+
if: ${{ always() && inputs.enable_sccache }}
189+
run: |
190+
sccache --show-stats --stats-format json > \
191+
"/var/log/ci-metrics/sccache-${{ github.run_id }}-${{ inputs.repo }}-test.json" \
192+
2>/dev/null || echo "::warning::sccache stats unavailable"
174193
175194
lint:
176195
name: lint
177196
runs-on: [self-hosted, clean-room]
178197
container:
179198
image: localhost:5000/sovereign-ci:stable@sha256:c23c453328df86562ba69410810180d205490c6b202342972f65af7050db6686
199+
# Phase 3 §5.3 — sccache rustc cache + /var/log/ci-metrics for F9 stats.
200+
# Mounted unconditionally (no-op when enable_sccache=false). Self-hosted
201+
# runners are on intel; paths are forjar-managed host dirs.
202+
volumes:
203+
- /home/noah/data/sccache:/sccache
204+
- /var/log/ci-metrics:/var/log/ci-metrics
180205
timeout-minutes: 30
181206
steps:
182207
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
@@ -267,10 +292,18 @@ jobs:
267292
env:
268293
CLIPPY_ARGS: ${{ inputs.clippy_args }}
269294
REPO_NAME: ${{ inputs.repo }}
295+
RUSTC_WRAPPER: ${{ inputs.enable_sccache && 'sccache' || '' }}
296+
SCCACHE_DIR: ${{ inputs.enable_sccache && '/sccache' || '' }}
270297
run: |
271298
cargo clippy $CLIPPY_ARGS -- -D warnings -A unused-variables 2>&1 || \
272299
cargo clippy -p "$REPO_NAME" -- -D warnings -A unused-variables 2>&1 || \
273300
{ echo "::error::Clippy failed — check workspace path dependencies"; exit 1; }
301+
- name: Record sccache stats
302+
if: ${{ always() && inputs.enable_sccache }}
303+
run: |
304+
sccache --show-stats --stats-format json > \
305+
"/var/log/ci-metrics/sccache-${{ github.run_id }}-${{ inputs.repo }}-lint.json" \
306+
2>/dev/null || echo "::warning::sccache stats unavailable"
274307
- name: Supply chain audit (cargo deny)
275308
continue-on-error: true
276309
run: |
@@ -286,6 +319,12 @@ jobs:
286319
runs-on: [self-hosted, clean-room]
287320
container:
288321
image: localhost:5000/sovereign-ci:stable@sha256:c23c453328df86562ba69410810180d205490c6b202342972f65af7050db6686
322+
# Phase 3 §5.3 — sccache rustc cache + /var/log/ci-metrics for F9 stats.
323+
# Mounted unconditionally (no-op when enable_sccache=false). Self-hosted
324+
# runners are on intel; paths are forjar-managed host dirs.
325+
volumes:
326+
- /home/noah/data/sccache:/sccache
327+
- /var/log/ci-metrics:/var/log/ci-metrics
289328
timeout-minutes: 30
290329
steps:
291330
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
@@ -373,12 +412,20 @@ jobs:
373412
env:
374413
TEST_ARGS: ${{ inputs.test_args }}
375414
REPO_NAME: ${{ inputs.repo }}
415+
RUSTC_WRAPPER: ${{ inputs.enable_sccache && 'sccache' || '' }}
416+
SCCACHE_DIR: ${{ inputs.enable_sccache && '/sccache' || '' }}
376417
run: |
377418
# Mark workspace as safe for git operations inside tests (dubious ownership in containers)
378419
git config --global --add safe.directory "$GITHUB_WORKSPACE"
379420
cargo llvm-cov test --lib --no-cfg-coverage --no-cfg-coverage-nightly --lcov --output-path lcov.info $TEST_ARGS 2>&1 || \
380421
cargo llvm-cov test --lib --no-cfg-coverage --no-cfg-coverage-nightly -p "$REPO_NAME" --lcov --output-path lcov.info 2>&1 || \
381422
{ echo "::error::Coverage failed — check workspace path dependencies"; exit 1; }
423+
- name: Record sccache stats
424+
if: ${{ always() && inputs.enable_sccache }}
425+
run: |
426+
sccache --show-stats --stats-format json > \
427+
"/var/log/ci-metrics/sccache-${{ github.run_id }}-${{ inputs.repo }}-coverage.json" \
428+
2>/dev/null || echo "::warning::sccache stats unavailable"
382429
- uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4
383430
with:
384431
files: lcov.info
@@ -390,6 +437,10 @@ jobs:
390437
runs-on: [self-hosted, clean-room]
391438
container:
392439
image: localhost:5000/sovereign-ci:stable@sha256:c23c453328df86562ba69410810180d205490c6b202342972f65af7050db6686
440+
# Phase 3 §5.3 — sccache volumes (see test job for rationale).
441+
volumes:
442+
- /home/noah/data/sccache:/sccache
443+
- /var/log/ci-metrics:/var/log/ci-metrics
393444
timeout-minutes: 60
394445
continue-on-error: true
395446
steps:
@@ -477,6 +528,8 @@ jobs:
477528
- name: Run criterion benchmarks
478529
env:
479530
REPO_NAME: ${{ inputs.repo }}
531+
RUSTC_WRAPPER: ${{ inputs.enable_sccache && 'sccache' || '' }}
532+
SCCACHE_DIR: ${{ inputs.enable_sccache && '/sccache' || '' }}
480533
run: |
481534
if ls benches/*.rs 2>/dev/null | head -1 | grep -q '.'; then
482535
cargo bench --bench '*' -- --output-format bencher 2>&1 | tee bench-results.txt || \
@@ -485,6 +538,12 @@ jobs:
485538
else
486539
echo "No benches/ directory — skipping"
487540
fi
541+
- name: Record sccache stats
542+
if: ${{ always() && inputs.enable_sccache }}
543+
run: |
544+
sccache --show-stats --stats-format json > \
545+
"/var/log/ci-metrics/sccache-${{ github.run_id }}-${{ inputs.repo }}-bench.json" \
546+
2>/dev/null || echo "::warning::sccache stats unavailable"
488547
- name: Upload benchmark results
489548
if: always()
490549
uses: actions/upload-artifact@v4

0 commit comments

Comments
 (0)