All Articles

Continuous Integration with Github Actions and Node

Does Continuous Integration have to be difficult? No. With Github Actions you can create a CI workflow yourself.

Use Github Actions for a NodeJS Project Photo by Unsplash on Unsplash

CI is a practice to continuosly test code. This practice lets developers get quick feedback on their changes and encourages them to push code more frequently. But this is not just for large teams. If you do it for your personal projects, you will get quick feedback for every tiny change you make. If you continue to accumulate many small successes, you will soon ramp up on those personal projects that you have been wanting to get done. Like me, with this blog.

In this article, I will show you how to create a simple CI workflow that tests and builds your NodeJS app. I pulled it from this Gatsby starter and modified it to my needs.

Core concepts

While I don’t want to bore you with the details, it is important to establish some concepts. From the Github Actions Documentation, we see that there is a difference between an action and a workflow. An action is an individual task. You can then combine these tasks into a workflow to build, test, package, release or deploy your code. You can build these single unit actions yourself or use many of the pre-built ones. In this post, I will use pre-built actions.

Build your CI

1. Create a directory structure

Create the following directory structure and files if they don’t already exist.

mkdir -p .github/workflows

And create a nodejs.yml file inside of the workflows directory.

2. Code the workflow

Let’s begin writing our workflow. First, let’s add a name to it:

name: My NodeJS CI

Now, let’s determine the conditions under which this workflow should execute. For this tutorial, let’s run it on every push to our master branch.

on:
  push:
    branches: [ master ]

Bonus: Let’s add a filter so that it doesn’t run when we make changes to our documentation. For example, let’s make it ignore all of our markdown files.

Edit: Previously, I had a paths-ignore value of [ '**.md' ]. This was preventing my workflows from running when I edited any of my blog’s posts (such as this one) since they are Markdown files. I decided I only want to prevent builds where I modify the README file so that builds do run when I make changes to posts.

on:
  push:
    branches: [ master ]
    paths-ignore: [ 'README.md' ]

So far, it should look like this:

name: My NodeJS CI

on:
  push:
    branches: [ master ]
    paths-ignore: [ '**.md' ]

What is a workflow without jobs to execute? Let’s add a job and describe some of its requirements.

jobs:
  build:
    runs-on: ubuntu-latest

Here, we told our job to run on an Ubuntu machine. Now, let’s add some steps to our job. We wan this to install our dependencies, run linting and testing on our code and finally, build it. Sounds like we have an npm command for each of those in our project, right?

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: Use Node.js 10.x
      uses: actions/setup-node@v1
      with:
        node-version: 10.x

We only have two steps so far. First, we checkout the code in this repository. This is why we used the action actions/checkout@v2. By default, this will checkout the code on our repository at the latest commit for the branch this is running on. If you want to know more about this, you can see the repository for this action. The second step installs NodeJS 10 for us.

Now, let’s run those npm commands.

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: Use Node.js 10.x
      uses: actions/setup-node@v1
      with:
        node-version: 10.x
    - name: run install, lint and test
      run: |
        npm install
        npm run lint
        npm run test

You can see the misterious | symbol. This pipe means that the command we want to run is a multi-line command. This way we can write multi-line text in our YAML configuration. Here we run all three commands in one step, one after the other.

Lastly, if we have npm run build command, let’s use it in our favor.

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: Use Node.js 10.x
      uses: actions/setup-node@v1
      with:
        node-version: 10.x
    - name: run install, lint and test
      run: |
        npm install
        npm run lint
        npm run test
    - name: build
      run: npm run build

Since it was a short command, I didn’t need to use the pipe symbol.

That’s it! Our final workflow configuration looks like this:

name: My NodeJS CI

on:
  push:
    branches: [ master ]
    paths-ignore: [ 'README.md' ]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2

    - name: Use Node.js 10.x
      uses: actions/setup-node@v1
      with:
        node-version: 10.x

    - name: run install, lint and test
      run: |
        npm install
        npm run lint
        npm run test

    - name: build
      run: npm run build

Not so scary, right? Don’t worry, it is nothing like a K8s config file.

3. Push some commits!

We are ready to try this out. Commit your changes and push to your repository. You will see a yellow dot next to your commit, indicating that these steps are running. Make some more changes to your app and push them. Watch as your CI workflow runs on every commit and tells you if your code passes all tests or not. Enjoy!

Enjoy your new CI workflow Photo by Danielle MacInnes on Unsplash

Another bonus: add a badge to your readme

If you’re like me, you always wondered where did people get those nice badges in their READMEs that tells whether a build is passing or failing. Look no further, here’s how to add these to your README.

The URL to your badge is in the format

https://github.com/<owner>/<repository>/workflows/<workflow>/badge.svg)

Just replace those placeholders. Notice that in the <workflow> you will need to substitute spaces for %20. If you followed this tutorial, you will need them since our workflow name (My NodeJS CI) has spaces in it.

Finally, add this to your readme:

![Build Status](https://github.com/<owner>/<repository>/workflows/<workflow>/badge.svg)

Conclusion

Creating a simple CI workflow is no longer rocket science thanks to Github Actions. Adding one to your personal NodeJS project is now a possibility. Use it to your advantage to see each of your commits generating results and build on these successes to reach your goals. I hope I’ve helped you learn something new and useful today. Follow me on Twitter and find out when I post more content.