- GitHub Actions can be slow
- How to cache npm install
- Caching npm install on GitHub Actions: A Step-by-Step Guide
- 5. Add any additional steps
GitHub Actions is a CI/CD pipeline by GitHub. It is built into the repository, and allows you to define a set of actions to perform on certain triggers. These actions include things like automatic merging of pull requests, automatic code format fixing, linting, asset generation and even deployment.
GitHub Actions works in a similar way to most CI/CD solutions; it spawns a virtual machine, and does whatever you ask it to, which is defined as a series of sequential tasks within a YAML file.
GitHub Actions can be slow
This isn't GitHub's fault, but many build times are measured in minutes long. Billing for GitHub Actions is measured in minutes, so keeping the build time to a minimum will save money as well as frustrations.
Obviously it depends on what your Action is doing as to why it is slow, but one of the main factors in a slow running GitHub Action is npm install
(or npm ci
) which installs all dependencies within your JavaScript application.
In our example Laravel application npm install
took around 2 minutes on GitHub Actions, which is slow compared to a dev machine which does it in around 10 seconds.
So how do we speed it up? We cache npm install
.
npm install
How to cache GitHub Actions is stateless. Every run is done from fresh and at the end of the run your virtual machine is destroyed. This means that caching could be problematic.
GitHub Action have a suite of prebuilt 'actions' which are available to install against your own Action. One such action is called actions/cache
which allows you to cache data between Action runs.
In our case we'll be building our node_modules
folder and caching it for use in later runs. You'll probably want to invalidate this from time to time.
npm install
on GitHub Actions: A Step-by-Step Guide
Caching To cache npm install
on GitHub Actions, follow these steps:
Set up your GitHub Actions workflow
Create a new GitHub Actions workflow or modify an existing one by adding a .github/workflows/main.yml
file in your repository.
Here's a simple example of a GitHub Actions workflow:
name: Node.js CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
This workflow is triggered whenever there's a push or pull request to the main branch. It runs on an ubuntu-latest
environment and checks out the repository using the actions/checkout action. You'll want to modify this as appropriate and keep it as close to your production environment as possible.
2. Add Node.js to your workflow
Next, you need to add Node.js to your GitHub Actions environment. Use the actions/setup-node
action to configure the desired Node.js version:
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: 14
Again, you'll want to mimic your production environment with the version of node you're running.
3. Cache the npm dependencies
To cache the npm dependencies, use the actions/cache
action. First, add the following step to your workflow:
- name: Cache npm dependencies
uses: actions/cache@v2
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
This step configures the cache for the npm dependencies. The path is set to ~/.npm
, which is where npm stores its cache on the GitHub Actions runner. The key is generated based on the current operating system and a hash of the package-lock.json
file. This ensures that the cache is only used if the package-lock.json
file hasn't changed. The restore-keys
option allows for partial cache matches if an exact match isn't found.
4. Run npm install
After configuring the cache, add a step to run npm install
:
- name: Install dependencies
run: npm ci
In this example, we use npm ci
instead of npm install
. The npm ci
command is recommended for CI/CD environments because it provides a more deterministic and faster installation process. It ensures that the installed dependencies match the package-lock.json
file exactly and removes the node_modules
folder before installation, ensuring a clean state.
5. Add any additional steps
Now that you've configured caching for npm install
, you can add any additional steps to your workflow, such as running tests or deploying your application.
Here's the complete example of a GitHub Actions workflow that caches npm install
:
name: Node.js CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: 14
- name: Cache npm dependencies
uses: actions/cache@v2
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: Install dependencies
run: npm ci
# Add any additional steps, such as running tests or deploying your application.
Caching npm install
on GitHub Actions can significantly improve your CI/CD workflow by reducing build times and saving resources. By following this guide and using the actions/cache action, you can easily configure caching for your npm dependencies and optimize your builds.
Interested in proving your knowledge of this topic? Take the JavaScript Fundamentals certification.
JavaScript Fundamentals
Showcase your knowledge of JavaScript in this exam, featuring questions on the language, syntax and features.
$99