Configuring the Build Cache for Bazel in GitHub Actions
You can use the Bitrise Build Cache to speed up Bazel builds in a GitHub Actions workflow, without moving your CI to Bitrise. It works the same way on GitHub-hosted runners and on Bitrise Build Hub runners.
Your workflow needs two extra steps: one that installs the Bitrise Build Cache CLI, and one that activates the cache for Bazel. Every Bazel step that runs afterwards in the same job uses the cache.
You can also set this up with an AI coding agent instead of following the steps manually. See Getting started with AI.
AuthenticationClick to copy link
You have three options to authenticate the Bitrise Build Cache CLI on GitHub Actions. The best method depends on where the job runs.
- Build Hub runners
- Workspace API token
- Personal access token
On Bitrise Build Hub runners there is nothing to set up. The machine is already connected to your Bitrise Workspace, so the CLI picks up the credentials from it: you don't create a token, and you don't add any secret, variable or environment variable to your workflow.
The machine pool has to belong to the same Workspace as the Build Cache you want to use.
Automatic authentication on Build Hub runners needs the latest Bitrise Build Cache CLI. The install command on this page always fetches the latest release, so this only matters if you pin the CLI to an older version.
On GitHub-hosted runners, we recommend using a workspace API token. It belongs to the workspace rather than to a person, so it keeps working when someone changes roles or leaves the company.
Give the token at least the viewer workspace role: that is the lowest role that can access the Build Cache.
The job needs two values:
- The token. It is sensitive and belongs in a GitHub secret.
- Your workspace slug. It is not sensitive and can be a GitHub variable. You can add both to a single repository, or to your organization so that every repository can use them.
-
On GitHub, open the repository or the organization you want to add them to, and select Settings.
-
In the sidebar, under Security, select Secrets and variables, then Actions.
-
On the Secrets tab, click New repository secret, or New organization secret if you are in the organization settings.
-
Set the name to
BITRISE_BUILD_CACHE_AUTH_TOKENand paste the Workspace API token as the value, then click Add secret.An organization secret also asks which repositories are allowed to use it.
-
Switch to the Variables tab and click New repository variable, or New organization variable.
-
Set the name to
BITRISE_BUILD_CACHE_WORKSPACE_IDand your Bitrise Workspace slug as the value, then click Add variable.You can find the slug on the Workspace settings page of your Bitrise Workspace, under General settings.
A Personal Access Token has the same roles as the user who created it. Its access changes whenever that user's roles change, and it stops working when the user leaves the Workspace. For a shared CI configuration, use a Workspace API token instead.
The job needs two values:
- The token. It is sensitive and belongs in a GitHub secret.
- Your workspace slug. It is not sensitive and can be a GitHub variable. You can add both to a single repository, or to your organization so that every repository can use them.
-
On GitHub, open the repository or the organization you want to add them to, and select Settings.
-
In the sidebar, under Security, select Secrets and variables, then Actions.
-
On the Secrets tab, click New repository secret, or New organization secret if you are in the organization settings.
-
Set the name to
BITRISE_BUILD_CACHE_AUTH_TOKENand paste the Personal Access Token as the value, then click Add secret.An organization secret also asks which repositories are allowed to use it.
-
Switch to the Variables tab and click New repository variable, or New organization variable.
-
Set the name to
BITRISE_BUILD_CACHE_WORKSPACE_IDand your Bitrise Workspace slug as the value, then click Add variable.You can find the slug on the Workspace settings page of your Bitrise Workspace, under General settings.
Adding the Build Cache to your workflowClick to copy link
-
On a GitHub-hosted runner, add
BITRISE_BUILD_CACHE_AUTH_TOKENandBITRISE_BUILD_CACHE_WORKSPACE_IDas environment variables to the job.These are the token and Workspace slug you set up in Authentication above:
jobs:build:runs-on: ubuntu-latestenv:BITRISE_BUILD_CACHE_AUTH_TOKEN: ${{ secrets.BITRISE_BUILD_CACHE_AUTH_TOKEN }}BITRISE_BUILD_CACHE_WORKSPACE_ID: ${{ vars.BITRISE_BUILD_CACHE_WORKSPACE_ID }}On Build Hub runners, skip this step: the credentials come from the machine.
-
Add a step that installs the Bitrise Build Cache CLI:
- name: Install the Bitrise Build Cache CLIrun: curl --retry 5 -sSfL 'https://raw.githubusercontent.com/bitrise-io/bitrise-build-cache-cli/main/install/installer.sh' | sh -s -- -b /tmp/bin -d -
Add a step that activates the Build Cache for Bazel, before the step that runs Bazel:
- name: Activate Bitrise Build Cache for Bazelrun: /tmp/bin/bitrise-build-cache activate bazel --cache --cache-push--cacheenables reading from the cache and--cache-pushenables writing to it. CI is normally the environment that fills the cache, so keep both enabled.ContainersIf your job runs in a container, or in several containers, the CLI has to run in the same container as the Bazel command it speeds up.
-
If you have Remote Build Execution enabled for your Workspace, you can also use it from GitHub Actions by adding the
--rbeflag.Enabling RBEYou need to have the workers set up for your Workspace, and the pool configuration in your repository's
.bazelrcfile, before enabling RBE. For more information, see Remote Build Execution for Bazel.
Example workflowClick to copy link
- GitHub-hosted runners
- Build Hub runners
name: build
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
env:
BITRISE_BUILD_CACHE_AUTH_TOKEN: ${{ secrets.BITRISE_BUILD_CACHE_AUTH_TOKEN }}
BITRISE_BUILD_CACHE_WORKSPACE_ID: ${{ vars.BITRISE_BUILD_CACHE_WORKSPACE_ID }}
steps:
- uses: actions/checkout@v4
- name: Install the Bitrise Build Cache CLI
run: curl --retry 5 -sSfL 'https://raw.githubusercontent.com/bitrise-io/bitrise-build-cache-cli/main/install/installer.sh' | sh -s -- -b /tmp/bin -d
- name: Activate Bitrise Build Cache for Bazel
run: /tmp/bin/bitrise-build-cache activate bazel --cache --cache-push
- name: Build
run: bazel build //...
The job needs no token and no environment variables. The runs-on label targets your pool. Bitrise creates a bitrise-runner-<pool name> label for every machine pool, so a pool named bazel-builds is targeted with bitrise-runner-bazel-builds.
name: build
on: [push, pull_request]
jobs:
build:
runs-on: bitrise-runner-bazel-builds
steps:
- uses: actions/checkout@v4
- name: Install the Bitrise Build Cache CLI
run: curl --retry 5 -sSfL 'https://raw.githubusercontent.com/bitrise-io/bitrise-build-cache-cli/main/install/installer.sh' | sh -s -- -b /tmp/bin -d
- name: Activate Bitrise Build Cache for Bazel
run: /tmp/bin/bitrise-build-cache activate bazel --cache --cache-push
- name: Build
run: bazel build //...
You can also use a custom label of the pool. For more information, see Configuring your GitHub Actions workflow.
Best practices and limitationsClick to copy link
Run the activation as its own stepClick to copy link
The CLI publishes its configuration through $GITHUB_ENV, which GitHub Actions applies to the following steps of the job. If you activate the Build Cache and run your build inside the same run: block, the build does not pick up the configuration.
Keep activation in a step of its own, before the step that runs the build.
Workflows triggered by forks have no secretsClick to copy link
GitHub does not pass repository or organization secrets to workflow runs triggered from a fork. In those runs BITRISE_BUILD_CACHE_AUTH_TOKEN is empty, so the CLI cannot authenticate and the build runs without the cache.
Keep dependency caching separate from the Build CacheClick to copy link
actions/cache does dependency caching: it saves the packages your build downloads, such as the Gradle or CocoaPods caches, and restores them on the next run so they don't have to be fetched again. On Bitrise CI, the key-based caching Steps do the same job. For more information, see Dependencies and caching overview.
That is a different job from the Bitrise Build Cache, which reuses the outputs of the build itself: compiled classes, compiled sources and task results. The two work well together, so keep caching your dependencies.
What you should not do is put build outputs into the dependency cache. If, for example, actions/cache restores Gradle's local build cache directory (~/.gradle/caches/build-cache-1), the restored local copy serves the results that the Bitrise Build Cache would have served, and your remote cache hit rate drops to near zero. Cache the dependency directories, not the build output directories.
Verifying the setupClick to copy link
- Run the workflow. The activation step should finish successfully and log the cache endpoint it connected to.
- Open the Build Cache page of your Workspace. Your run appears in the invocation list, with the cache statistics of the build.
- The first run reports a 0% cache hit rate: the cache is empty at that point. This is expected.
- Run the workflow another one to three times to warm the cache. The hit rate should rise above 0%.