diff --git a/.gitea/workflows/bench.yml b/.gitea/workflows/bench.yml index d2f89318..4f26eafd 100644 --- a/.gitea/workflows/bench.yml +++ b/.gitea/workflows/bench.yml @@ -13,6 +13,20 @@ on: - cron: '30 4 * * *' workflow_dispatch: +# Shared compile cache: sccache -> RustFS S3 (storage.unom.io, LAN-pinned via ci-core's +# unbound). Keys include compiler hash + target + flags, so cross-OS/arch entries can +# never collide; every Rust job on every host feeds and reads one warm cache. +env: + RUSTC_WRAPPER: sccache + SCCACHE_BUCKET: unom-ci-sccache + SCCACHE_ENDPOINT: https://storage.unom.io + SCCACHE_REGION: home-central + AWS_ACCESS_KEY_ID: ${{ secrets.SCCACHE_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.SCCACHE_SECRET_ACCESS_KEY }} + # sccache and incremental compilation are mutually exclusive; CI wants the shared + # cache, dev boxes keep incremental. + CARGO_INCREMENTAL: "0" + jobs: bench: # Tier-1 (criterion microbenchmarks) + Tier-2 (FEC loss recovery) — GPU-free, so they run here. @@ -22,6 +36,17 @@ jobs: timeout-minutes: 30 steps: - uses: actions/checkout@v4 + + # Shared compile cache (sccache -> RustFS S3 over the LAN). Baked into the builder + # images; this fetch keeps the job green while the running :latest predates the bake. + - name: sccache (no-op once the image bakes it) + run: | + command -v sccache >/dev/null 2>&1 || { + curl -fsSL https://github.com/mozilla/sccache/releases/download/v0.10.0/sccache-v0.10.0-x86_64-unknown-linux-musl.tar.gz \ + | tar -xz --wildcards --strip-components=1 -C /usr/local/bin '*/sccache' + } + sccache --version + - name: Prep run: | git config --global --add safe.directory "$PWD" diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 2f077686..fba4d909 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -20,6 +20,20 @@ on: branches: [main] pull_request: +# Shared compile cache: sccache -> RustFS S3 (storage.unom.io, LAN-pinned via ci-core's +# unbound). Keys include compiler hash + target + flags, so cross-OS/arch entries can +# never collide; every Rust job on every host feeds and reads one warm cache. +env: + RUSTC_WRAPPER: sccache + SCCACHE_BUCKET: unom-ci-sccache + SCCACHE_ENDPOINT: https://storage.unom.io + SCCACHE_REGION: home-central + AWS_ACCESS_KEY_ID: ${{ secrets.SCCACHE_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.SCCACHE_SECRET_ACCESS_KEY }} + # sccache and incremental compilation are mutually exclusive; CI wants the shared + # cache, dev boxes keep incremental. + CARGO_INCREMENTAL: "0" + jobs: rust: runs-on: ubuntu-24.04 @@ -29,6 +43,16 @@ jobs: steps: - uses: actions/checkout@v4 + # Shared compile cache (sccache -> RustFS S3 over the LAN). Baked into the builder + # images; this fetch keeps the job green while the running :latest predates the bake. + - name: sccache (no-op once the image bakes it) + run: | + command -v sccache >/dev/null 2>&1 || { + curl -fsSL https://github.com/mozilla/sccache/releases/download/v0.10.0/sccache-v0.10.0-x86_64-unknown-linux-musl.tar.gz \ + | tar -xz --wildcards --strip-components=1 -C /usr/local/bin '*/sccache' + } + sccache --version + # punktfunk-client-linux link deps. Also baked into rust-ci.Dockerfile — but ci.yml # runs against the image from the PREVIOUS push (docker.yml bootstrap note), so this # keeps the job green across image-content changes; a no-op once the image has them. @@ -136,6 +160,9 @@ jobs: - name: C ABI harness (standalone link proof) run: bash crates/punktfunk-core/tests/c/run.sh + - name: sccache stats (visibility only) + run: sccache --show-stats + - name: Verify generated header is committed & up to date run: | cargo build -p punktfunk-core --locked @@ -160,6 +187,16 @@ jobs: steps: - uses: actions/checkout@v4 + # Shared compile cache (sccache -> RustFS S3 over the LAN). Baked into the builder + # images; this fetch keeps the job green while the running :latest predates the bake. + - name: sccache (no-op once the image bakes it) + run: | + command -v sccache >/dev/null 2>&1 || { + curl -fsSL https://github.com/mozilla/sccache/releases/download/v0.10.0/sccache-v0.10.0-x86_64-unknown-linux-musl.tar.gz \ + | tar -xz --wildcards --strip-components=1 -C /usr/local/bin '*/sccache' + } + sccache --version + - name: Cache keys run: echo "rustc=$(rustc --version | cut -d' ' -f2)" >> "$GITHUB_ENV" - uses: actions/cache@v4 diff --git a/.gitea/workflows/deb.yml b/.gitea/workflows/deb.yml index b1d564d9..bc3a16df 100644 --- a/.gitea/workflows/deb.yml +++ b/.gitea/workflows/deb.yml @@ -64,6 +64,15 @@ env: REGISTRY: git.unom.io OWNER: unom COMPONENT: main + RUSTC_WRAPPER: sccache + SCCACHE_BUCKET: unom-ci-sccache + SCCACHE_ENDPOINT: https://storage.unom.io + SCCACHE_REGION: home-central + AWS_ACCESS_KEY_ID: ${{ secrets.SCCACHE_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.SCCACHE_SECRET_ACCESS_KEY }} + # sccache and incremental compilation are mutually exclusive; CI wants the shared + # cache, dev boxes keep incremental. + CARGO_INCREMENTAL: "0" jobs: build-publish: @@ -74,6 +83,16 @@ jobs: steps: - uses: actions/checkout@v4 + # Shared compile cache (sccache -> RustFS S3 over the LAN). Baked into the builder + # images; this fetch keeps the job green while the running :latest predates the bake. + - name: sccache (no-op once the image bakes it) + run: | + command -v sccache >/dev/null 2>&1 || { + curl -fsSL https://github.com/mozilla/sccache/releases/download/v0.10.0/sccache-v0.10.0-x86_64-unknown-linux-musl.tar.gz \ + | tar -xz --wildcards --strip-components=1 -C /usr/local/bin '*/sccache' + } + sccache --version + - name: Version + channel # vX.Y.Z tag -> X.Y.Z, published to the `stable` apt distribution (a real release). # A main push -> ~ciN.g, published to the `canary` distribution: the '~' sorts @@ -220,6 +239,16 @@ jobs: steps: - uses: actions/checkout@v4 + # Shared compile cache (sccache -> RustFS S3 over the LAN). Baked into the builder + # images; this fetch keeps the job green while the running :latest predates the bake. + - name: sccache (no-op once the image bakes it) + run: | + command -v sccache >/dev/null 2>&1 || { + curl -fsSL https://github.com/mozilla/sccache/releases/download/v0.10.0/sccache-v0.10.0-x86_64-unknown-linux-musl.tar.gz \ + | tar -xz --wildcards --strip-components=1 -C /usr/local/bin '*/sccache' + } + sccache --version + - name: Version + channel run: | git config --global --add safe.directory "$PWD" @@ -327,6 +356,16 @@ jobs: steps: - uses: actions/checkout@v4 + # Shared compile cache (sccache -> RustFS S3 over the LAN). Baked into the builder + # images; this fetch keeps the job green while the running :latest predates the bake. + - name: sccache (no-op once the image bakes it) + run: | + command -v sccache >/dev/null 2>&1 || { + curl -fsSL https://github.com/mozilla/sccache/releases/download/v0.10.0/sccache-v0.10.0-x86_64-unknown-linux-musl.tar.gz \ + | tar -xz --wildcards --strip-components=1 -C /usr/local/bin '*/sccache' + } + sccache --version + # Byte-identical to build-publish's version step (pf-version.sh is deterministic per # commit), so the arm64 package always shares the amd64 version line. - name: Version + channel diff --git a/.gitea/workflows/linux-client-screenshots.yml b/.gitea/workflows/linux-client-screenshots.yml index 14b49a13..32653cbc 100644 --- a/.gitea/workflows/linux-client-screenshots.yml +++ b/.gitea/workflows/linux-client-screenshots.yml @@ -19,6 +19,20 @@ on: tags: ["v*"] workflow_dispatch: +# Shared compile cache: sccache -> RustFS S3 (storage.unom.io, LAN-pinned via ci-core's +# unbound). Keys include compiler hash + target + flags, so cross-OS/arch entries can +# never collide; every Rust job on every host feeds and reads one warm cache. +env: + RUSTC_WRAPPER: sccache + SCCACHE_BUCKET: unom-ci-sccache + SCCACHE_ENDPOINT: https://storage.unom.io + SCCACHE_REGION: home-central + AWS_ACCESS_KEY_ID: ${{ secrets.SCCACHE_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.SCCACHE_SECRET_ACCESS_KEY }} + # sccache and incremental compilation are mutually exclusive; CI wants the shared + # cache, dev boxes keep incremental. + CARGO_INCREMENTAL: "0" + jobs: screenshots: if: startsWith(github.ref, 'refs/tags/v') || github.event_name == 'workflow_dispatch' @@ -30,6 +44,16 @@ jobs: steps: - uses: actions/checkout@v4 + # Shared compile cache (sccache -> RustFS S3 over the LAN). Baked into the builder + # images; this fetch keeps the job green while the running :latest predates the bake. + - name: sccache (no-op once the image bakes it) + run: | + command -v sccache >/dev/null 2>&1 || { + curl -fsSL https://github.com/mozilla/sccache/releases/download/v0.10.0/sccache-v0.10.0-x86_64-unknown-linux-musl.tar.gz \ + | tar -xz --wildcards --strip-components=1 -C /usr/local/bin '*/sccache' + } + sccache --version + # Client link deps (baked into the image; kept here so the job is green across image # rebuilds — a no-op once present) PLUS the headless-render extras: a virtual X server, # software GL+Vulkan (llvmpipe/lavapipe), the icon theme + fonts the UI draws with, and a diff --git a/.gitea/workflows/rpm.yml b/.gitea/workflows/rpm.yml index 02902a1b..94c3dec7 100644 --- a/.gitea/workflows/rpm.yml +++ b/.gitea/workflows/rpm.yml @@ -45,6 +45,15 @@ on: env: REGISTRY: git.unom.io OWNER: unom + RUSTC_WRAPPER: sccache + SCCACHE_BUCKET: unom-ci-sccache + SCCACHE_ENDPOINT: https://storage.unom.io + SCCACHE_REGION: home-central + AWS_ACCESS_KEY_ID: ${{ secrets.SCCACHE_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.SCCACHE_SECRET_ACCESS_KEY }} + # sccache and incremental compilation are mutually exclusive; CI wants the shared + # cache, dev boxes keep incremental. + CARGO_INCREMENTAL: "0" jobs: build-publish: @@ -70,6 +79,16 @@ jobs: steps: - uses: actions/checkout@v4 + # Shared compile cache (sccache -> RustFS S3 over the LAN). Baked into the builder + # images; this fetch keeps the job green while the running :latest predates the bake. + - name: sccache (no-op once the image bakes it) + run: | + command -v sccache >/dev/null 2>&1 || { + curl -fsSL https://github.com/mozilla/sccache/releases/download/v0.10.0/sccache-v0.10.0-x86_64-unknown-linux-musl.tar.gz \ + | tar -xz --wildcards --strip-components=1 -C /usr/local/bin '*/sccache' + } + sccache --version + # rpmbuild + git archive need the checkout trusted; cache the crates download. # The client link deps are also baked into the fedora-rpm image, but this job runs # against the image from the PREVIOUS push (docker.yml bootstrap note) — keep it diff --git a/.gitea/workflows/windows-host.yml b/.gitea/workflows/windows-host.yml index 3da96fb0..5e96b5b3 100644 --- a/.gitea/workflows/windows-host.yml +++ b/.gitea/workflows/windows-host.yml @@ -91,6 +91,15 @@ env: REGISTRY: git.unom.io OWNER: unom PKG: punktfunk-host-windows + RUSTC_WRAPPER: sccache + SCCACHE_BUCKET: unom-ci-sccache + SCCACHE_ENDPOINT: https://storage.unom.io + SCCACHE_REGION: home-central + AWS_ACCESS_KEY_ID: ${{ secrets.SCCACHE_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.SCCACHE_SECRET_ACCESS_KEY }} + # sccache and incremental compilation are mutually exclusive; CI wants the shared + # cache, dev boxes keep incremental. + CARGO_INCREMENTAL: "0" jobs: package: diff --git a/.gitea/workflows/windows-msix.yml b/.gitea/workflows/windows-msix.yml index cbd50853..99580565 100644 --- a/.gitea/workflows/windows-msix.yml +++ b/.gitea/workflows/windows-msix.yml @@ -60,6 +60,15 @@ env: REGISTRY: git.unom.io OWNER: unom PKG: punktfunk-client-windows + RUSTC_WRAPPER: sccache + SCCACHE_BUCKET: unom-ci-sccache + SCCACHE_ENDPOINT: https://storage.unom.io + SCCACHE_REGION: home-central + AWS_ACCESS_KEY_ID: ${{ secrets.SCCACHE_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.SCCACHE_SECRET_ACCESS_KEY }} + # sccache and incremental compilation are mutually exclusive; CI wants the shared + # cache, dev boxes keep incremental. + CARGO_INCREMENTAL: "0" jobs: package: diff --git a/.gitea/workflows/windows.yml b/.gitea/workflows/windows.yml index 9cc4b9b3..3f75d354 100644 --- a/.gitea/workflows/windows.yml +++ b/.gitea/workflows/windows.yml @@ -73,6 +73,20 @@ on: - '.gitea/workflows/windows.yml' workflow_dispatch: +# Shared compile cache: sccache -> RustFS S3 (storage.unom.io, LAN-pinned via ci-core's +# unbound). Keys include compiler hash + target + flags, so cross-OS/arch entries can +# never collide; every Rust job on every host feeds and reads one warm cache. +env: + RUSTC_WRAPPER: sccache + SCCACHE_BUCKET: unom-ci-sccache + SCCACHE_ENDPOINT: https://storage.unom.io + SCCACHE_REGION: home-central + AWS_ACCESS_KEY_ID: ${{ secrets.SCCACHE_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.SCCACHE_SECRET_ACCESS_KEY }} + # sccache and incremental compilation are mutually exclusive; CI wants the shared + # cache, dev boxes keep incremental. + CARGO_INCREMENTAL: "0" + jobs: # SECURITY: this job builds PULL-REQUEST code (attacker-controllable build.rs / cargo build) on the # host-mode, persistent `windows-amd64` runner that the release-SIGNING jobs (windows-host.yml / diff --git a/ci/fedora-rpm.Dockerfile b/ci/fedora-rpm.Dockerfile index b0d3be75..b2fdf183 100644 --- a/ci/fedora-rpm.Dockerfile +++ b/ci/fedora-rpm.Dockerfile @@ -66,3 +66,11 @@ RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \ | sh -s -- -y --no-modify-path --profile minimal \ && chmod -R a+w "$RUSTUP_HOME" "$CARGO_HOME" \ && rustc --version && cargo --version + +# Shared compile cache: jobs set RUSTC_WRAPPER=sccache (backend = RustFS S3 on the LAN, +# see .gitea/workflows — the env lives there so dev use of this image stays uncached). +# musl build: one static binary serves the Ubuntu and Fedora images alike. +ARG SCCACHE_VERSION=0.10.0 +RUN curl -fsSL "https://github.com/mozilla/sccache/releases/download/v${SCCACHE_VERSION}/sccache-v${SCCACHE_VERSION}-x86_64-unknown-linux-musl.tar.gz" \ + | tar -xz --wildcards --strip-components=1 -C /usr/local/bin '*/sccache' \ + && sccache --version diff --git a/ci/rust-ci-noble.Dockerfile b/ci/rust-ci-noble.Dockerfile index 64cea533..55aa4f6a 100644 --- a/ci/rust-ci-noble.Dockerfile +++ b/ci/rust-ci-noble.Dockerfile @@ -83,3 +83,11 @@ RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \ --component rustfmt,clippy \ && chmod -R a+w "$RUSTUP_HOME" "$CARGO_HOME" \ && rustc --version && cargo clippy --version && cargo fmt --version + +# Shared compile cache: jobs set RUSTC_WRAPPER=sccache (backend = RustFS S3 on the LAN, +# see .gitea/workflows — the env lives there so dev use of this image stays uncached). +# musl build: one static binary serves the Ubuntu and Fedora images alike. +ARG SCCACHE_VERSION=0.10.0 +RUN curl -fsSL "https://github.com/mozilla/sccache/releases/download/v${SCCACHE_VERSION}/sccache-v${SCCACHE_VERSION}-x86_64-unknown-linux-musl.tar.gz" \ + | tar -xz --wildcards --strip-components=1 -C /usr/local/bin '*/sccache' \ + && sccache --version diff --git a/ci/rust-ci.Dockerfile b/ci/rust-ci.Dockerfile index acde7672..0ddb45ec 100644 --- a/ci/rust-ci.Dockerfile +++ b/ci/rust-ci.Dockerfile @@ -50,3 +50,11 @@ RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \ --component rustfmt,clippy \ && chmod -R a+w "$RUSTUP_HOME" "$CARGO_HOME" \ && rustc --version && cargo clippy --version && cargo fmt --version + +# Shared compile cache: jobs set RUSTC_WRAPPER=sccache (backend = RustFS S3 on the LAN, +# see .gitea/workflows — the env lives there so dev use of this image stays uncached). +# musl build: one static binary serves the Ubuntu and Fedora images alike. +ARG SCCACHE_VERSION=0.10.0 +RUN curl -fsSL "https://github.com/mozilla/sccache/releases/download/v${SCCACHE_VERSION}/sccache-v${SCCACHE_VERSION}-x86_64-unknown-linux-musl.tar.gz" \ + | tar -xz --wildcards --strip-components=1 -C /usr/local/bin '*/sccache' \ + && sccache --version diff --git a/scripts/ci/ensure-windows-toolchain.ps1 b/scripts/ci/ensure-windows-toolchain.ps1 index 7c20ecca..4fa1215f 100644 --- a/scripts/ci/ensure-windows-toolchain.ps1 +++ b/scripts/ci/ensure-windows-toolchain.ps1 @@ -47,3 +47,19 @@ catch { Write-Warning "disk reclaim step failed (non-fatal): $_" } $ciDir = $PSScriptRoot & "$ciDir\provision-windows-wdk.ps1" & "$ciDir\provision-windows-punktfunk-extras.ps1" + +# --- sccache: shared compile cache (RustFS S3 over the LAN). The Windows workflows set +# RUSTC_WRAPPER=sccache, so the binary must exist on any runner regardless of when the +# template was last re-baked. GITHUB_PATH makes it visible to every later step. +$sccacheDir = 'C:\Users\Public\sccache' +$sccacheExe = Join-Path $sccacheDir 'sccache.exe' +if (-not (Test-Path $sccacheExe)) { + $v = '0.10.0' + $tarball = Join-Path $env:TEMP "sccache-$v.tar.gz" + Invoke-WebRequest -Uri "https://github.com/mozilla/sccache/releases/download/v$v/sccache-v$v-x86_64-pc-windows-msvc.tar.gz" -OutFile $tarball + New-Item -ItemType Directory -Force -Path $sccacheDir | Out-Null + tar -xzf $tarball -C $sccacheDir --strip-components=1 + Remove-Item $tarball -ErrorAction SilentlyContinue +} +& $sccacheExe --version +if ($env:GITHUB_PATH) { Add-Content -Path $env:GITHUB_PATH -Value $sccacheDir }