Configuring the Build Cache for React Native in GitHub Actions
You can use the Bitrise Build Cache to speed up React Native 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.
A single activation covers all three backends a React Native build uses: Gradle for Android, the Xcode Compilation Cache for iOS, and ccache for C++.
You can also set this up with an AI coding agent instead of following the steps manually. See Getting started with AI.
RequirementsClick to copy link
Bitrise Build Cache CLI v1.0.0 or later. Earlier versions have no React Native support.
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: macos-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 React Native, before the steps that run a build:
- name: Activate Bitrise Build Cache for React Nativerun: /tmp/bin/bitrise-build-cache activate react-native --cache-pushAll three backends are enabled by default. To disable one, pass the matching flag:
/tmp/bin/bitrise-build-cache activate react-native --gradle=true --xcode=true --cpp=falseCI is normally the environment that fills the cache, so keep
--cache-pushenabled. -
Prefix every command that runs a native build with
bitrise-build-cache react-native run:- name: Build iOSrun: /tmp/bin/bitrise-build-cache react-native run npx react-native run-ios --configuration=ReleaseFor more information, see Wrapping native build commands.
Example workflowClick to copy link
- GitHub-hosted runners
- Build Hub runners
name: build-rn
on: [push, pull_request]
jobs:
build:
runs-on: macos-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 React Native
run: /tmp/bin/bitrise-build-cache activate react-native --cache-push
- name: Install JavaScript dependencies
run: yarn install
- name: Build iOS
run: /tmp/bin/bitrise-build-cache react-native run npx react-native run-ios --configuration=Release
- name: Build Android
run: /tmp/bin/bitrise-build-cache react-native run npx react-native run-android --mode=release
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 rn-builds is targeted with bitrise-runner-rn-builds.
name: build-rn
on: [push, pull_request]
jobs:
build:
runs-on: bitrise-runner-rn-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 React Native
run: /tmp/bin/bitrise-build-cache activate react-native --cache-push
- name: Install JavaScript dependencies
run: yarn install
- name: Build iOS
run: /tmp/bin/bitrise-build-cache react-native run npx react-native run-ios --configuration=Release
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%.