- Shell 96.8%
- Makefile 3.2%
|
All checks were successful
test / unit (push) Successful in 7s
test / integration (push) Successful in 5s
test / install (v0.15.0) (push) Successful in 6s
test / install (v0.14.0) (push) Successful in 7s
test / install-without-v-prefix (push) Successful in 5s
test / reinstall-on-version-change (push) Successful in 7s
Move the Unreleased entries (SCCACHE_PATH export, cache-stats and Mozilla differences docs) under v1.1.2 (2026-05-28). |
||
|---|---|---|
| .forgejo | ||
| .githooks | ||
| scripts | ||
| tests | ||
| .editorconfig | ||
| .gitignore | ||
| action.yml | ||
| CHANGELOG.md | ||
| CONTRIBUTING.md | ||
| LICENSE | ||
| Makefile | ||
| README.md | ||
| SECURITY.md | ||
sccache-action
Install sccache on Forgejo Actions runners. Composite action, no JavaScript, no GitHub PAT required, with SHA-256 verification of the downloaded binary against the upstream sidecar.
Why not Mozilla-Actions/sccache-action?
Mozilla's action requires a GitHub token via with: token: to call api.github.com for release lookup. On GitHub Actions the workflow's auto-provided secrets.GITHUB_TOKEN is a GitHub token and that works. On Forgejo Actions, secrets.GITHUB_TOKEN is a Forgejo token: it can't authenticate to GitHub's API, and the action fails before installing anything:
::error::Error: Input required and not supplied: token
You could provision a real GitHub PAT just to satisfy the action, but it's a new long-lived secret to rotate for what should be a single curl. This action skips the API call entirely, downloads the public release tarball directly, and verifies it against the SHA-256 sidecar Mozilla publishes alongside.
Usage
- uses: https://rasterhub.com/rasterstate/sccache-action@v1
That's it. Defaults to sccache v0.15.0 with checksum verification on.
With explicit version pin (recommended for reproducible CI):
- uses: https://rasterhub.com/rasterstate/sccache-action@v1
with:
version: v0.15.0
Full workflow pattern for a Rust job backed by S3:
jobs:
test:
runs-on: [self-hosted, Linux]
env:
RUSTC_WRAPPER: sccache
SCCACHE_BUCKET: my-bucket
SCCACHE_ENDPOINT: https://fsn1.your-objectstorage.com
SCCACHE_REGION: fsn1
SCCACHE_S3_USE_SSL: "true"
SCCACHE_S3_KEY_PREFIX: ${{ github.repository }}
AWS_ACCESS_KEY_ID: ${{ secrets.SCCACHE_AWS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.SCCACHE_AWS_SECRET_KEY }}
steps:
- uses: actions/checkout@v6
- uses: https://github.com/dtolnay/rust-toolchain@stable
- uses: https://rasterhub.com/rasterstate/sccache-action@v1
- run: cargo build --release
- name: sccache stats
if: always()
run: sccache --show-stats
Inputs
| Name | Default | Description |
|---|---|---|
version |
v0.15.0 |
sccache release tag. Pinned by default so a release that breaks the cache layout doesn't silently land. Accepts v0.15.0 or 0.15.0. |
install-dir |
/usr/local/bin |
Where to drop the binary. Uses sudo install if the directory isn't writable as the runner user. |
verify-checksum |
true |
Verify the downloaded tarball against the upstream .sha256 sidecar. Fails closed on mismatch. Only disable if your mirror doesn't serve sidecar files. |
Outputs
| Name | Description |
|---|---|
version |
Resolved sccache tag actually installed, with leading v (e.g. v0.15.0). |
install-path |
Absolute path to the installed sccache binary. |
Example:
- id: sccache
uses: https://rasterhub.com/rasterstate/sccache-action@v1
- run: |
echo "installed ${{ steps.sccache.outputs.version }} at ${{ steps.sccache.outputs.install-path }}"
Environment
The action exports SCCACHE_PATH (absolute path to the installed binary) to
$GITHUB_ENV, so later steps can reference $SCCACHE_PATH directly. This
mirrors the upstream Mozilla action. It is the same value as the
install-path output; use whichever fits your step.
What it does
- If
sccacheis already onPATHat the requested version, skip install (idempotent across multiple invocations on a long-lived runner). - Detect OS + arch (
Linux x86_64,Linux aarch64,macOS x86_64,macOS arm64). - Download the matching
sccache-${VERSION}-${TRIPLE}.tar.gzfromhttps://github.com/mozilla/sccache/releases/download/..., public asset, no auth, with retries. - Download the matching
.sha256sidecar and verify the tarball's digest. Fail closed on mismatch. - Extract and install the binary into
install-dir(sudo if needed). - Append
install-dirto$GITHUB_PATHand reset bash's command cache so subsequent steps and the in-step--versionsmoke test see the new binary. - Export
SCCACHE_PATHto$GITHUB_ENVand runsccache --versionas a smoke test.
Cache stats
The upstream Mozilla action ships a JavaScript post step that prints
sccache --show-stats and renders a job-summary table after the build. A
composite action runs all its steps at the point it's invoked, before your
build, so it can't do post work without bundling JavaScript, which this
action deliberately avoids.
To get the same job-summary table, add your own step at the end of the job. It's self-contained, needs nothing from this action, and works on Forgejo and GitHub runners alike:
- name: sccache stats
if: always()
shell: bash
run: |
{
echo '### sccache stats'
echo '```'
sccache --show-stats
echo '```'
} >>"$GITHUB_STEP_SUMMARY"
sccache --show-stats --stats-format=json is available if you want to parse
the numbers (e.g. with jq) into a custom table. The one thing this can't
reproduce is the upstream live notice annotation on the run; that path is
JavaScript-only.
Supported runners
- Linux x86_64 (
x86_64-unknown-linux-musl) - Linux ARM64 (
aarch64-unknown-linux-musl) - macOS x86_64 (
x86_64-apple-darwin) - macOS ARM64 (
aarch64-apple-darwin)
Windows runners aren't supported; the upstream sccache release exists but the install path and sudo assumptions are Unix-shaped. The action errors out cleanly on non-Linux/Darwin platforms rather than failing later.
Versioning
Tags follow vMAJOR rolling-pointer style so consumers can @v1 and get patch/minor fixes without re-pinning. Concrete release tags (v1.0.0, v1.0.1, ...) exist alongside for users who want full pinning.
A default-version bump (e.g. defaulting sccache from v0.15.0 to a later release) is not a major bump of this action; see CHANGELOG.md for what shipped when. Pin version: explicitly if you don't want default bumps to land.
Why a composite action and not JS
Composite actions are pure YAML, no dist/ bundle to keep in sync with source, no node_modules, no build step. The job we do here (curl + verify + install) is a few shell lines; the JS overhead would be larger than the work. The whole thing is two small files: action.yml (the composite wrapper) and scripts/install.sh (the install logic). Keeping the logic in a standalone script is what lets it be shellchecked, formatted, and unit-tested directly. Readable, auditable, and forkable without a toolchain.
Differences from Mozilla-Actions/sccache-action
This action is a pure-shell reimplementation of the install half of the
upstream Mozilla action, built for Forgejo runners where the auto-provided
secrets.GITHUB_TOKEN is a Forgejo token and can't authenticate to GitHub's
API. The behavior is intentionally trimmed; here's the full parity picture.
What we do that upstream doesn't:
- No GitHub token or
api.github.comcall. Upstream requirestoken:to resolve "latest" and fails on Forgejo without a real GitHub PAT. verify-checksumis a real input (upstream hard-codes verification on), and our verify strips all whitespace and length-checks the 64 hex chars, so it won't trip on a<hash> <file>style sidecar.install-dirinput andversion/install-pathoutputs. Upstream has none of these.- Explicit
--retry/--retry-connrefused, a temp-dir cleanup trap, and v-prefix normalization (0.15.0andv0.15.0are equivalent).
What upstream does that we deliberately don't:
- Resolve the latest release automatically. We require a pinned
version(defaultv0.15.0); auto-latest is exactly what needs the token. - A JavaScript post step for stats (annotation + job-summary table). See Cache stats for the self-contained step that gets you the summary table; the live annotation stays JS-only.
- Windows (
pc-windows-msvc) and 32-bit ARM Linux (armv7/musleabi). We error out cleanly on unsupported platforms instead. - Export the GitHub Actions cache backend variables
(
ACTIONS_CACHE_SERVICE_V2,ACTIONS_RESULTS_URL,ACTIONS_RUNTIME_TOKEN) used by sccache'sghacache backend. Those are GitHub-runtime specific and don't apply to the Forgejo + S3 setup this action targets.
What differs in approach:
- Idempotence. Upstream reads/writes the GitHub tool-cache
(
RUNNER_TOOL_CACHE) to skip re-download across jobs. We skip when the requested version is already onPATH. On ephemeral autoscaler VMs both re-download; on a persistent runner upstream avoids more re-downloads. SCCACHE_PATHis exported the same way (to$GITHUB_ENV).
Security
See SECURITY.md for the threat model and disclosure path.
Contributing
See CONTRIBUTING.md for the local test loop and release procedure.
License
MIT. See LICENSE.