Switch your cross-platform CI to GitHub Actions in 5 minutes
If you maintain an open source project that’s hosted on GitHub, and you’re frustrated by one or more of your current continuous integration (CI) providers, good news: GitHub Actions is a free CI service that supports running tests and other tasks on macOS, Windows, and Linux.
Note that many runtimes are supported by GitHub Actions. This post includes some Node.JS-specific tips.
What’s wrong with GitHub’s docs? đź”—
GitHub’s quickstart and setup docs are a good start for building and testing against the currently supported versions of Node.JS, but if your code has any OS-specific code, these docs don’t tell you how to set up cross-platform builds, and sometimes just knowing what to search for is the biggest stumbling block.
Setting up cross-platform, cross-version builds is easy, though:
Add a new workflow đź”—
Either click the GitHub Actions tab, and click the “New workflow” button:
Or, if you’d rather do it manually, edit a new file called
.github/workflows/node.js.yml
from the base of your project repository.
Then replace the contents of the file with this:
name: Node.js CI
on:
push:
branches: [master]
pull_request:
branches: [master]
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
node-version: [10.x, 12.x, 14.x, 15.x]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm test
Note that this assumes you’re using npm
and have a package-lock.json
. If
you’re a yarn
user, check out Tip #2.
There’s a bunch going on there, but the magick bits to
grok are the strategy.matrix:
,
runs-on:
, and with:
keys.
As soon as you commit this and push to GitHub, you should see a build summary show up in your Actions tab:
You’ll see that the build matrix will include every combination of os
and
node-version
specified in jobs.build.strategy.matrix
, which in this case,
was 12 different builds.
Tip 1: Customizing the build matrix đź”—
GitHub’s jobs.<job_id>.strategy.matrix
reference
describes how to include or exclude specific OSes and/or Node versions in your
build matrix.
Tip 2: How to use yarn instead of npm đź”—
GitHub’s own runners actually install yarn
by default, so (almost) all that
you need to do is switch out npm
for yarn
in your workflow.
If you’re not aware, npm ci
does the following:
- Recursively deletes the
node_modules
directory - Runs
npm install
, but only uses the exact versions specified in thepackage-lock.json
. Ifpackage-lock.json
is missing,npm ci
will fail.
If you’re using yarn
(and not using Windows), you can simulate this by adding
the following scripts to your package.json
:
{
...
"scripts": {
...
"preci": "rm -rf node_modules",
"ci": "yarn install --frozen-lockfile"
...
}
}
Note that this preci
script won’t work if you’re building on Windows. For
cross-platform modules, I’m just cheating and skipping over the node_modules
cleanup step.
Tip 3: Add or replace your CI build badge đź”—
From the Actions tab, click a build summary, and in the upper right, click …
,
and then click “Create status badge.”
If you’re building a badge for your README, you want to pick your release branch
(so, main
or master
).
Unfortunately, the markdown that gets displayed is just the image, so if you paste the
markdown into your README.md
, and someone clicks the build badge, it navigates
to the badge image, not the build (!!).
It’s up to you to add a proper link to the build badge: wrap the markdown from the “Create status badge” tool with square brackets, and then add a reasonable destination link, in parenthesis, right after the square brackets.
You’ll end up with something like this:
[![CI build](https://github.com/.../badge.svg)](https://github.com/.../actions)
All together now đź”—
Here’s a commit that
- switches to GitHub Actions,
- removes the other CI build configurations,
- updates the build badge in the
README.md
, and - adds a
yarn ci
job (without thepreci
step)
My prior CI for this build matrix could take 30 minutes or more to complete, and required using two different services.
GitHub Actions completes this same matrix in only 6 minutes: ✨ Kudos, GitHub! ✨