This is a Github Action composite action that encapsulates a set of steps to be easily re-used across many jobs and workflows. It provides the ability to install node, and the npm dependencies and supports caching of the node_modules
directory out of the box.
There is a Github maintained action called actions/setup-node
that installs node and also offers caching of the .npm
folder. It does not offer the ability to cache the node_modules
folder. The reason offered in their docs is that the .npm
folder caches in a version-independent way and can be used across multiple version of node and npm. The result of this is that npm still must construct the node_modules
folders from those caches and this takes quite a long time still. As an example, in one of our repos, the npm install step took ~3.5 mins on a cpair without the ~/.npm
cache and ~3 min with the ~/.npm
cache. Caching the pre-built node_modules
can take ~20 seconds on the same repo.
This composite action, uses the actions/setup-node
and the actions/cache
Github actions under the hood. This helps us take advantage of all the off-the-shelf tooling available in those actions. This action provides the caching needed for node_modules
, using the top-level package-lock.json
part of the hash key for the cache. In addition, the OS, Node version also are included in the hash key. That means that you can safely run this with more than one node version without strange conflicts. In addition, any time you include a new version of the package-lock.json
you'll get a cache miss and the builds will take slightly longer (doubly longer because you must do the npm install from scratch and also must store the new cache, which can be big).
As a safety for the caching, we do an npm ls
before ending to make sure that have a valid installed dependencies. If this fails, we will do the install.
Caches can be managed in the Actions
tab for a repository.
You may already have several steps in a job that installs node and then does an npm install. If so, your before and after would look like this:
Before
...
- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: "18.x"
- name: Install dependencies
run: npm ci --no-audit --prefer-offline
...
After
...
- uses: braintree/action-setup-node-caching@v1
with:
node-version: "18.x"
...
-
Make your changes and commit to
main
. -
Tag the commit with a new version. For example, if your new version was
v2
:git tag -af -m "New features in v2" v2 git push --follow-tags
-
Update usages to refer to the new version. For example, if you were updating from v1 to v2:
... - uses: braintree/action-setup-node-caching@v1 with: node-version: "18.x" ...
becomes
... - uses: braintree/action-setup-node-caching@v2 with: node-version: "18.x" ...