CI/CD caching with Bitrise: Dependency caching with Bitrise

We deep dive into our dependency cache changes, look at what the caching methods are, talk about steps you can take to implement caching methods, as well as provide an overview on troubleshooting cache issues. Happy reading!

TLDR; Bitrise’s caching solution is the most efficient way to increase your build speed. Optimize your workflow. Talk to us today.

In our blog post, CI/CD Caching with Bitrise: Dependency caching - then vs now, we spoke about some of the most incremental changes to our cache offering. In this post, we deep dive into those changes, look at what the caching methods are, talk about steps you can take to implement caching methods, as well as provide an overview on troubleshooting cache issues.

CI/CD caching with Bitrise is a series of articles that takes you through all there is to know about caching. Other caching articles in the series currently include Dependency caching — then vs now, and What is a cache, and why should you care about caching?

Caching methods

Bitrise has two main methods of caching namely branch-based caching and dependency caching. As branch-based caching will be sunsetted* in 2023, we’re covering dependency caching only in this post.

*View our documentation to start with dependency caching.

Key-based caching

Key-based caching works by associating cache archives with a key. During a workflow, you can restore a cached archive by referring to the associated key and save a new cache entry with an arbitrary key, including dynamic elements in the key (templating). At the end of the Workflow, the build files can be saved into the cache archive that the key indicates — overwriting the cache archive.

Image 1: Key-based caching

Adding key-based caching to your workflows

Developers can use key-based caching in their workflows by adding Restore Cache and Save Cache to their workflows:

  • Restore Cache: Used at the beginning of a workflow, this step restores build files from a cache entry, identified by a key, and adds them to the build.
  • Save Cache: Used at the end of a workflow, this step saves the build files at the end of the build into a cache entry, identified by a key.

Image 2: Adding key-based caching to your workflows.

Keys need to be specified as the values of the cache keys Step input; each key identifies a separate cache archive.

Both key-based caching Steps support using template elements in their Step inputs. The Steps evaluate the key template at runtime and the final cache key to be used can change depending on the build environment or on certain files in the repository.

Available caching templates can be found in our dev center and in the table below.

 Template expression  Definition  Possible values
 cache-key-{{ .Branch }} Current git branch the build runs on.  -
 cache-key-{{ .CommitHash }} SHA-256 hash of the git commit the build runs on.  -
 cache-key-{{ .Workflow }} Current Bitrise workflow name (for example, "primary").  -
 {{ .Arch }}-cache-key Current CPU architecture of the build stack.
 {{ .OS }}-cache-key Current operating system of the build stack.
  • linux: For Linux-based stacks.

  • darwin: For macOS-based stacks.

The key-based caching templates support the use of two different functions:

Example 1: Using the checksum function

Use the checksum function to create a key that computes the checksum of the package-lock.json file:

- save-cache@1:
    - key: npm-cache-{{ checksum "package-lock.json" }}
    - paths: node_modules

Use the checksum function to create a key that computes a checksum for any .gradle file and the file:

- save-cache@1:
    - key: gradle-cache-{{ checksum "**/*.gradle*" "" }}
    - paths: AndroidApp

Example 2: Using the getenv function

Use the getenv function to create a key that contains the value of the BITRISE_BUILD_NUMBER Env Var.

- save-cache@1:
    - key: npm-cache-{{ getenv "BITRISE_BUILD_NUMBER" }}
    - paths: node_modules

Key matching for cache archives

It's possible to define more than one key in the Cache keys input of the key-based caching Steps. You can specify additional keys by listing one key per line. The list is in priority order, so the Step will first try to find a match for the first key you provided, and if there is no cache stored for the key, it will move on to find a match for the second key (and so on).

In addition to listing multiple keys, each key can be a prefix of a saved cache key and still get a matching cache archive. For example, the key my-cache- can match an existing archive saved with the key my-cache-a6a102ff. We recommend configuring the keys in a way that the first key is an exact match to a checksum key, and to use a more generic prefix key as a fallback:

  key: |
    npm-cache-{{ checksum "package-lock.json" }}

Switch to key-based caching today.

What should you cache?

Caching the resolved and downloaded dependencies of the project is the first obvious thing to cache. Setting up dependency caching varies across platforms and dependency managers, but we have dedicated caching steps for the most popular dependency managers that require no setup. Read more on workflow recipes for more sophisticated use cases.

Other than dependencies, build artifacts should also be cached. At Bitrise, we have several out-of-the-box automation Steps that can help optimize your workflows and cache your build artifacts. These, currently in Beta, include Step support for Gradle, Bazel, and Tuist - all fully maintained by Bitrise.

How to cache with various build tools

We’ve made it really easy to cache with various build tools, and it takes practically no time to set them up. You can view the step-by-step instructions in our dev center, or check out the videos below.

1. Caching Cocoapods

2. Caching Gradle

3. Caching Maven

4. Caching Ruby Gems

5. Caching Homebrew installers

6. Caching Swift packages

Get Started for free

Start building now, choose a plan later.

Sign Up

Get started for free

Start building now, choose a plan later.