LITERAT

Fullstack Developer & Whitewater Kayaker & Scout

How to Cache Not Just Yarn Installs on GitHub Actions

Discover how to optimize dependency installation on GitHub Actions for modern package managers like Yarn. Learn about custom caching actions and the latest features of actions/setup-node to speed up your CI/CD pipeline significantly.

How to Cache Not Just Yarn Installs on GitHub Actions

Since migrating a few of my projects to Yarn Modern, I have been struggling with speeding up the dependency installation process on GitHub Actions.

From the beginning, I have been using the great bahmutov/npm-install action that handles the caching of node_modules for Yarn v1.22.22 very well.

With the configuration looking like this...

- name: Install dependencies
  uses: bahmutov/npm-install@v1.10.2
  with:
    useRollingCache: true
    install-command: yarn --immutable

...the caching was working great and the CI runs were fast.

Missing the Cache

However as I started to migrate the project to Yarn v3 and v4, I noticed that the cache was consistently missed.

bahmutov/npm-install miss the cache for Yarn Modern

There is still an open GitHub issue bahmutov/npm-install#28 that is tracking this problem.

Re-enable the Caching

I have started investigating how to achieve better performance for Yarn Modern while installing dependencies on GitHub Actions. I have discovered a few viable solutions worth sharing.

Discord's Custom Cache Action

In a Discord repository, I have found a custom caching action that is handling the caching using actions/cache.

The solution is simple:

  • Restore yarn cache
  • Restore cache state
  • Install dependencies

You can check their implementation in the Discord repository.

This is a good and usable solution if you want to take care of the caching yourself. But I did not want to deal with this.

Setup Node with Cache

I am also using the actions/setup-node for configuring the Node.js environment for me. And in one of their most recent release I discovered that they have added a new feature for caching the package manager's cache.

Caching dependencies

The action has a built-in functionality for caching and restoring npm/yarn dependencies. Supported package managers are npm, yarn. The cache input is optional, and caching is turned off by default.

- name: Enable Corepack
  run: corepack enable # Set up a package manager for us

- name: Configure Node
  uses: actions/setup-node@v4
  with:
    node-version-file: '.nvmrc' # Use node version file
    cache: 'yarn' # 'npm' or 'yarn'
    cache-dependency-path: yarn.lock # path to a dependency file

- name: Install dependencies
  run: yarn --immutable --inline-builds

Since using this configuration, I have been able to speed up my dependency installation process on GitHub Actions twice.

But this approach caches only the package managers global cache like ~/.npm or ~/.yarn/cache. Additionally using actions/cache another layer of the caching can be added. So state of the node_modules can be cached and restored to speed up the pipeline even more.

- name: Restore cached node_modules
  uses: actions/cache@v4
  with:
    path: '**/node_modules'
    key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
    restore-keys: |
      ${{ runner.os }}-yarn-

This approach leads to another few spared seconds in your pipelines.

References

I code on

Literat © 2008 — 2024