Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions .github/actions/setup-sccache/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# setup-sccache — sccache with a SHARED REMOTE backend when one is configured,
# per-repo GitHub-Actions cache otherwise.
#
# CIRISEdge#216 / CIRISServer#285. The GHA sccache backend is repo-scoped AND
# only visible to a job after the producing job finishes — so within one run,
# the parallel jobs×platforms each cold-build the same edge crate (the N×
# multiplier #285 measured). A shared remote (S3-compatible or WebDAV) is
# written incrementally and readable cross-repo + cross-job, which collapses the
# multiplier to 1× the first time any job compiles a given unit.
#
# No such backend is provisioned yet, so this action FALLS BACK to the GHA
# backend (today's behavior, byte-for-byte) whenever the remote secret is
# absent/empty. Activation is one org secret away — see PROVISIONING below.
# Gating is on the caller-passed input (a composite action cannot read secrets
# itself), so an unset secret arrives as "" and takes the GHA branch.
#
# PROVISIONING (lights up cross-repo dedup, no code change):
# Recommended: Cloudflare R2 (S3-compatible, zero egress) or any WebDAV store.
# Add org/repo secrets and this action switches automatically:
# WebDAV : SCCACHE_WEBDAV_ENDPOINT (+ SCCACHE_WEBDAV_TOKEN or _KEY_PREFIX)
# S3 : wire the aws-* env in a sibling input (follow-up; WebDAV is the
# lowest-friction first backend).
# Point every centipede repo (persist/verify/edge/server) at the SAME store so
# a unit compiled in any one is reused by all — the cross-repo half of #216.
name: setup-sccache
description: sccache with a shared remote backend when configured (CIRISEdge#216), GHA fallback otherwise.

inputs:
webdav-endpoint:
description: "Shared WebDAV sccache endpoint (caller passes secrets.SCCACHE_WEBDAV_ENDPOINT). Empty means GHA fallback."
required: false
default: ""
webdav-token:
description: "Bearer token for the WebDAV store (caller passes secrets.SCCACHE_WEBDAV_TOKEN)."
required: false
default: ""

runs:
using: composite
steps:
- name: select sccache backend
shell: bash
env:
WEBDAV_ENDPOINT: ${{ inputs.webdav-endpoint }}
WEBDAV_TOKEN: ${{ inputs.webdav-token }}
run: |
if [ -n "${WEBDAV_ENDPOINT}" ]; then
echo "::notice::sccache → SHARED REMOTE (webdav) — cross-repo + within-run dedup (CIRISEdge#216)"
{
echo "SCCACHE_WEBDAV_ENDPOINT=${WEBDAV_ENDPOINT}"
echo "SCCACHE_WEBDAV_TOKEN=${WEBDAV_TOKEN}"
echo "SCCACHE_GHA_ENABLED=false"
} >> "$GITHUB_ENV"
else
echo "::notice::sccache → per-repo GHA cache (no shared-remote secret; CIRISEdge#216 mitigation pending backend)"
echo "SCCACHE_GHA_ENABLED=true" >> "$GITHUB_ENV"
fi
- uses: mozilla-actions/sccache-action@v0.0.9
21 changes: 15 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -336,8 +336,11 @@ jobs:
- uses: dtolnay/rust-toolchain@1.97.0
with:
targets: ${{ matrix.target }}
- name: Set up sccache (compiler cache over GHA)
uses: mozilla-actions/sccache-action@v0.0.9
- name: Set up sccache (shared remote when configured, GHA otherwise)
uses: ./.github/actions/setup-sccache
with:
webdav-endpoint: ${{ secrets.SCCACHE_WEBDAV_ENDPOINT }}
webdav-token: ${{ secrets.SCCACHE_WEBDAV_TOKEN }}
# The pyo3 variant links against the libpython stub with different
# RUSTFLAGS, so its target dir is NOT interchangeable with plain's —
# each variant owns its cache key (plain keeps the pre-split key so
Expand Down Expand Up @@ -1247,8 +1250,11 @@ jobs:
- name: install libsqlite3-dev (sqlite build dep)
run: sudo apt-get update && sudo apt-get install -y libsqlite3-dev
- uses: dtolnay/rust-toolchain@1.97.0
- name: Set up sccache (compiler cache over GHA)
uses: mozilla-actions/sccache-action@v0.0.9
- name: Set up sccache (shared remote when configured, GHA otherwise)
uses: ./.github/actions/setup-sccache
with:
webdav-endpoint: ${{ secrets.SCCACHE_WEBDAV_ENDPOINT }}
webdav-token: ${{ secrets.SCCACHE_WEBDAV_TOKEN }}
- uses: ./.github/actions/ciriscache
with:
plat: linux-x86_64
Expand Down Expand Up @@ -1398,8 +1404,11 @@ jobs:
# `x86_64-pc-windows-msvc` (Tier-1) so no `-Zbuild-std` is
# needed.
- uses: dtolnay/rust-toolchain@1.97.0
- name: Set up sccache (compiler cache over GHA)
uses: mozilla-actions/sccache-action@v0.0.9
- name: Set up sccache (shared remote when configured, GHA otherwise)
uses: ./.github/actions/setup-sccache
with:
webdav-endpoint: ${{ secrets.SCCACHE_WEBDAV_ENDPOINT }}
webdav-token: ${{ secrets.SCCACHE_WEBDAV_TOKEN }}
# CIRISEdge#229 — canonical CIRISCache layered restore on the
# wheel matrix. PLAT maps wheel's `label` token to the canonical
# platform token persist + verify save under:
Expand Down
127 changes: 127 additions & 0 deletions .github/workflows/warm-release-cache.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# warm-release-cache — pre-warm the new edge CIRISCache layer the moment a
# substrate pin (or edge's own version) bumps on main, DECOUPLED from ci.yml.
#
# CIRISServer#285 / CIRISEdge#216. The centipede cache key
# (`…-p<persist>-e<edge>-v<verify>`, see .github/actions/ciriscache) is
# version-keyed: any of those three changing mints a fresh key that nothing has
# saved yet, so every downstream job (server client-artifacts, persist, this
# repo's own tag run) cold-recompiles the ~200-crate edge dep graph — N× the
# same build across jobs×platforms.
#
# ci.yml *does* save the edge layer on main/tags, but two facts defeat it as a
# warm source: (1) ci.yml's main-push run and the release TAG run share one
# SHA-keyed concurrency group with cancel-in-progress, so the tag run CANCELS
# the main run that would have saved the layer; (2) the surviving tag run only
# saves at the END of its ~20 min wheel matrix — long after a downstream repo,
# triggered by the same substrate bump, has already started cold-building.
#
# This workflow runs in its OWN concurrency group (never cancelled by the tag),
# fires the instant Cargo.toml's pins change, and saves the linux release layers
# — the ones the installer + Docker + persist restore — as fast as a single
# `cargo build --release` allows. Mirrors CIRISServer's warm-release-cache.yml;
# edge builds inline (no reusable build-wheels.yml) so the warm job is explicit.
name: warm-release-cache

on:
push:
branches: [main]
paths:
- Cargo.toml # the substrate pins + edge version live here; detect filters further
workflow_dispatch:
inputs:
force:
description: "Warm even without a detected pin/version change (validate the workflow)"
type: boolean
default: false

permissions:
contents: read
packages: write # CIRISCache/save writes the GHCR blob

concurrency:
# Distinct from ci.yml's `ci-<sha>` group — a release tag must NOT cancel the
# warm. Keyed on ref so a newer main push supersedes an in-flight warm.
group: warm-release-cache-${{ github.ref }}
cancel-in-progress: true

jobs:
detect:
runs-on: ubuntu-latest
outputs:
warm: ${{ steps.d.outputs.warm }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 2
- id: d
shell: bash
run: |
if [ "${{ inputs.force }}" = "true" ]; then
echo "warm=true" >> "$GITHUB_OUTPUT"
echo "::notice::forced via workflow_dispatch"
exit 0
fi
# The centipede key is a function of edge version (E), persist tag (P),
# and verify tag (V). Any of the three changing mints a cold key — so
# warm on a diff touching the `^version =` line OR a persist/verify tag.
if git diff HEAD~1 HEAD -- Cargo.toml \
| grep -qE '^[+-](version = |.*CIRIS(Persist|Verify).*tag = "v)'; then
echo "warm=true" >> "$GITHUB_OUTPUT"
echo "::notice::edge version or a persist/verify pin changed — warming the release cache"
else
echo "warm=false" >> "$GITHUB_OUTPUT"
echo "::notice::no key-affecting change in Cargo.toml — nothing to warm"
fi

warm:
needs: detect
if: needs.detect.outputs.warm == 'true'
permissions:
contents: read
packages: write
strategy:
fail-fast: false
# The two linux release layers downstream actually restores: the installer
# + Docker path (#285's cited 14m26s cold build) is linux-x86_64; aarch64
# covers the ARM image. macOS/Windows are desktop-wheel-only and ride
# ci.yml's own save — not worth a native-runner warm here.
matrix:
include:
- { plat: linux-x86_64, os: ubuntu-latest }
- { plat: linux-aarch64, os: ubuntu-24.04-arm }
runs-on: ${{ matrix.os }}
env:
SCCACHE_GHA_ENABLED: "true"
RUSTC_WRAPPER: sccache
steps:
- uses: actions/checkout@v4
- name: install libsqlite3-dev (sqlite build dep)
run: sudo apt-get update && sudo apt-get install -y libsqlite3-dev
- uses: dtolnay/rust-toolchain@1.97.0
- name: Set up sccache (shared remote when configured, GHA otherwise)
uses: ./.github/actions/setup-sccache
with:
webdav-endpoint: ${{ secrets.SCCACHE_WEBDAV_ENDPOINT }}
webdav-token: ${{ secrets.SCCACHE_WEBDAV_TOKEN }}
- uses: ./.github/actions/ciriscache
id: cachekey
with:
plat: ${{ matrix.plat }}
# Warm the DENSEST edge layer (transport + reticulum + pyo3 — the superset
# the ciriscache `edge` key names). The ~200 upstream dep crates are the
# expensive part and their `target/` artifacts are identical to the wheel
# build's, so warming them here means every later job (this repo's tag run,
# downstream repos) restores instead of rebuilding. NOTE: no
# `extension-module` — that flag only changes edge's own final cdylib link
# (host-provides-libpython), not the deps, and omitting it lets a plain
# `cargo build` link cleanly against the runner's libpython (same reason
# `cargo test --features pyo3` works in ci.yml).
- name: cargo build --release (warm the edge layer)
run: cargo build --release --features "transport-http transport-reticulum pyo3"
- name: sccache stats
if: always()
run: sccache --show-stats
- uses: CIRISAI/CIRISCache/save@v1
with:
key: ${{ steps.cachekey.outputs.key }}
token: ${{ secrets.GITHUB_TOKEN }}
Loading