Skip to main content

Key-based caching

Abstract

Key-based caching on Bitrise works by associating cache archives with a key. A Workflow can restore a cache archive by referring to the key; the build files can be saved into the cache archive that the key indicates.

Feature in beta

Key-based caching is in the beta phase, and as such, it is subject to changes in terms of both function and availability.

Key-based caching works by associating cache archives with a key. A Workflow can restore a cache archive by referring to the key; at the end of the Workflow, the build files can be saved into the cache archive that the key indicates. This overwrites the cache archive.

Cache keys can contain variables and other dynamic elements that are replaced at runtime. Users can set up caching that periodically creates new cache archives and automatically discard the old archives.

Using key-based caching

Key-based caching requires two Steps that must be used together:

  • Save Cache: saves the build files into a cache archive, identified by a key.

  • Restore Cache: restores build files into a cache archive, identified by a key.

Both Steps access cache archives via key strings. These keys need to be specified as the values of the Cache keys Step input; each key identifies a separate cache archive.

Creating a new cache archive

Key limitations

The maximum length of a cache key is 512 characters (longer keys get truncated). Commas (,) are not allowed in keys.

  1. Add the Save Cache Step at the end of your Workflow.

  2. In the Cache key input, define a cache key. This key will be used to identify the cache archive.

    You can use templates and functions to create dynamic keys that change depending on the build environment or other factors.

    You can specify multiple keys; the Step will evaluate them in order and match the first one. Read more: Key matching for cache archives.

    Example 1. Creating a new cache archive with a key referring to the OS

    In this example, we're creating a cache archive with a key that refers to the type of the operating system of the build machine.

    - save-cache@1:
        inputs:
        - key: |-
            npm-cache-{{ .OS }}

  3. In the Paths to cache input, define the files and folders that you want to cache.

    The input allows for wildcards: * and **. The input value is evaluated at runtime.

    Example 2. Caching all files and folders recursively in the node_modules folder
    - save-cache@1:
        inputs:
        - key: |-
            npm-cache-{{ .OS }}
        - paths: node_modules/**/*

Restoring an existing cache archive

  1. Add the Restore Cache Step at the start of your Workflow.

  2. In the Cache key input, type the key of the cache that you want to restore.

    You can use templates and functions to create dynamic keys that change depending on the build environment or other factors.

    You can specify multiple keys; the Step will evaluate them in order and select the first matching one. Read more: Key matching for cache archives

    Example 3. Restoring a cache archive from one of two keys

    In this example, we're restoring one of two keys:

    • First, we'll look for a cache archive with a key that includes the name of the current Workflow. For example, if the current Workflow's name is primary, the Step will look for an archive with the key npm-cache-primary.

    • Second, we'll look for an archive with a key that includes the name of the current branch. For example, if the current branch's name is main, the Step will look for an archive with the key npm-cache-main.

    - restore-cache@1:
        inputs:
        - key: |-
            npm-cache-{{ .Workflow }}
            npm-cache-{{ .Branch }}
    

Key-based caching templates and functions

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

Table 1. Key-based caching templates

Template expression

Definition

Possible values

cache-key-{{ .Branch }}

Current git branch the build runs on.

The exact name of any existing branch of the app.

cache-key-{{ .CommitHash }}

SHA-256 hash of the git commit the build runs on.

Any existing commit hash.

cache-key-{{ .Workflow }}

Current Bitrise workflow name (for example, primary).

The exact name of any existing Workflow of the app.

{{ .Arch }}-cache-key

Current CPU architecture of the build stack (amd64 or arm64).

{{ .OS }}-cache-key

Current operating system of the build stack (linux or darwin).

  • linux: For Linux-based stacks.

  • darwin: For macOS-based stacks.


Using functions in caching templates

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:
    inputs:
    - 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 gradle.properties file:

- save-cache@1:
    inputs:
    - key: gradle-cache-{{ checksum "**/*.gradle*" "gradle.properties" }}
    - 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:
    inputs:
    - 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).

inputs:
  key: |
    key-1
    key-2
    key-3

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:

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

Conditional caching

You might not want to update a cache archive every time you run a build. For example, Workflows triggered by pull requests might include the Restore cache Step but skip the Save cache Step in order to:

  • Avoid saving potentially incorrect build data in the cache.

  • Make the PR validation workflow faster.

  • Limit the amount of data stored and transferred.

If you don't wish to update the cache archive, you can either remove the Save cache Step from your Workflow or you can set conditions for the Step: Enabling or disabling a Step conditionally.