---
name: cachely-ci-setup
description: Wire the Cachely remote build cache into a CI pipeline (GitHub Actions, GitLab CI, or any runner) for Nx, Lerna, Turborepo, Gradle, or Bazel. Use when adding remote caching to CI, provisioning cache tokens as CI secrets, or securing cache writes for untrusted pull request builds.
---

# Cachely in CI

CI is where a remote cache pays off most: every runner starts cold, so
without one it re-executes everything. Setup is a token in a secret plus
the tool's native config - no plugin, no cache server to run.

## 1. Provision the token

Create a workspace token in the dashboard (https://app.cachely.dev) and
store it as a CI secret (e.g. `CACHELY_TOKEN`). Never commit it. Use one
token per pipeline or repo so it can be revoked independently.

## 2. Configure the pipeline

GitHub Actions example (the env-var pattern is identical on any CI):

```yaml
jobs:
  ci:
    runs-on: ubuntu-latest
    env:
      # Nx
      NX_SELF_HOSTED_REMOTE_CACHE_SERVER: https://remote.cachely.dev
      NX_SELF_HOSTED_REMOTE_CACHE_ACCESS_TOKEN: ${{ secrets.CACHELY_TOKEN }}
      # Turborepo
      TURBO_API: https://remote.cachely.dev
      TURBO_TOKEN: ${{ secrets.CACHELY_TOKEN }}
      TURBO_TEAM: any-slug
    steps:
      - uses: actions/checkout@v4
        with: { fetch-depth: 0 } # affected detection needs the base ref
      - uses: actions/setup-node@v4
        with: { node-version-file: .nvmrc }
      - run: npm ci
      - run: npx nx affected -t lint test build # or: npx turbo run build --affected
```

Gradle reads the cache from `settings.gradle(.kts)` (Basic password =
token); Bazel from `--remote_cache` + `--remote_header` flags - inject the
token via an env var or a generated `user.bazelrc`, never a committed file.
Per-tool config details live in the `cachely-remote-cache` skill.

## 3. Secure untrusted builds

Pull requests from forks run untrusted code; a write token would let them
poison artifacts that trusted builds later restore.

- Give fork/PR pipelines a **read-only token** (or no token), and keep the
  write token for trusted branches.
- Bazel: keep `build --remote_upload_local_results=false` in the committed
  `.bazelrc` so no machine uploads unless it asks to, and let only trusted CI
  opt back in with `--config=cachely-ci`. Developer machines get read-only
  tokens for the same reason a fork does: an unhermetic upload poisons
  everyone's next build.
- Fork PRs cannot read repo secrets on most CI providers - design the
  pipeline to fall back to local-only caching when the secret is absent
  rather than failing.

## 4. Verify

Run the pipeline twice on the same commit. The second run should restore
cached results instead of executing (look for `read from cache` /
`FULL TURBO` / `FROM-CACHE` / `remote cache hit`). If it does not, debug
with the `cachely-improve-cache-hit-rate` skill. Also confirm no edge
protection challenges the cache host: a CLI cannot solve a browser
challenge, and the symptom is a 403 on the post-build upload.
