Continuous Integration with CircleCI and NodeJS

Kevin Coleman
Mesh
Published in
9 min readJan 25, 2018

Software developers tend to come up with complicated names for simple topics. Examples of this include Dependency Injection, Orthogonality, and Lexical Binding. While these terms sound impressive, they often produce an adverse side effect; novice developers assume the subjects they describe are complicated and unapproachable.

The above proved to be true for me when I first learned about Continuous Integration (CI). I thought CI sounded like a complex topic, one that I would never be able to understand let alone master. In reality however, the opposite was true. CI is straightforward to integrate into any development process, especially in this day-and-age when there are many fantastic CI hosting providers available to choose from.

In this post, I’ll explain what CI is and demonstrate how you can add a CI pipeline to an existing project. I’ll also demonstrate how we can integrate that pipeline with GitHub so that the CI process automatically runs any time a developer opens a pull request, or commits to a pull request. We will also branch protection that prohibits merges to master unless the CI build has passed.

Lastly, I’ll show how we can add CI reporting notifications to everyone’s favorite chat app, Slack.

What is CI?

CI is the process of building and testing a code base whenever an individual developer pushes their contributions to a repository. This process needs to be automated, meaning a system is responsible for building and testing the code base, not a human.

At Mesh Studio, we are huge proponents of CI as it is a potent tool that helps development teams ensure the stability of their code base at all times. When we engage with a new customer, we will often instrument a CI pipeline before we start writing any feature code.

Getting Started

For this tutorial, we are going to use the following sample project:

https://github.com/meshhq/circle-node-sample

Fork the repository, clone it onto your local machine and CD into the directory.

$ git clone git@github.com:<YOUR_GITHUB_HANDLE>/circle-node-sample.git && cd circle-node-sample

Our CI build process is going to consist of the following two steps:

  1. Install dependencies
  2. Execute the test suite

Our sample project provides simple npm commands for each of these steps. These commands are npm install and npm test. We will use both commands in our CircleCI build configuration.

Setting up CircleCI

Our CI provider of choice at Mesh is CircleCI. To run builds on Circle, we need to create a new directory in the root of our project called .circleci.

$ mkdir .circleci

Next, we need to create a file called circle.yml inside of the new .circleci directory. (oh — I didn’t know you could do a directory)

$ touch .circleci/circle.yml

The circle.yml file will contain the build instructions that CircleCI follows for your build. For this tutorial, we will use the circle.yml file below. Copy and paste the following code into your circle.yml file.

version: 2
jobs:
build:
docker:
— image: circleci/node:7.10
working_directory: ~/repo steps:
— checkout
- run: npm install

— run: npm test

The circle.yml File

Let’s dive into each section of the circle.yml file and examine what each entry means.

Jobs

The jobs section of the circle.yml defines a task or set of tasks to be run for the CI process. CircleCI allows you to configure multiple jobs for more complex CI processes, but for our purposes, a single job task is all we need.

Build

The build section defines the name for the job. So in this case, the name of the job is simply build.

Docker

The docker section defines an executor for the build process. An executor is a place where build steps will occur. By specifying docker, we are telling Circle that we want our build steps to take place inside of a Docker container. For comparison sake, if we were building an iOS application instead of a node.js application, we would replace `docker` with macos. This would tell Circle that we want our tests to take place on a MacOS machines as opposed to a Docker image.

Image

When we use the docker executor, we must define the image that we want to use for the executor. Circle offers many images that we can use for a variety of runtimes. In this case, we have decided to use a Circle image that supports node.js v7.10.

Working Directory

Steps

The steps section defines a list of steps that need to be executed to complete the build process. Each of these steps must pass without failure; otherwise, the CI process will fail. We describe the steps, and their functionality below:

  • checkout — A CircleCI built in command which is responsible for checking out the project’s source code into the Job’s working_directory we discussed above.
  • run: npm install — Installs all project dependencies listed in the package.json file.
  • run: npm test — Executes the automated test suite.

Running the build locally

One of the fantastic features of CircleCI is that they distribute a command-line interface (CLI) tool which provides for running build locally on a developer’s machine. Now that we have our circle.yml file configured, we can run the build locally and ensure that the build process passes.

To do so, we first need to install the CircleCI command-line tool. We can do this with the following curl command which will download and install the cli.

$ curl -o /usr/local/bin/circleci https://circle-downloads.s3.amazonaws.com/releases/build_agent_wrapper/circleci && chmod +x /usr/local/bin/circleci

To validate your installation, type circleci -h. You should see the following output.

$ circleci -hThe CLI tool to be used in CircleCI.Usage:
circleci [flags]
circleci [command]
Available Commands:
build run a full build locally
config validate and update configuration files
help Help about any command
step execute steps
tests collect and split files with tests
version output version info
Flags:
-c, — config string config file (default is .circleci/config.yml)
-h, — help help for circleci
— taskId string TaskID
— verbose emit verbose logging output
Use “circleci [command] — help” for more information about a command.

Once the CLI is installed, we can kick off a local build with the following command:

$ circleci build

Your build process should begin executing and pass successfully! Congratulations, you have configured your build with CircleCI!

Integrating CircleCI and GitHub

Now that we have our CircleCI build configured and passing locally, the next step is to take our build process and make it continuous. We do so by telling Circle to run our CI process anytime a developer opens a Pull Request (PR) or makes a commit to an open PR.

We are also going to protect the master branch of our repository to prevent code from being merged unless it has passed CI. We can set this up with the following steps:

Navigate to your project’s repository and click on `Settings.`

Click on “Branches” in the left-hand navigation menu.

Under “Protected Branches” click on the “Choose a branch” drop-down and select “master”.

Click the checkbox next to “Protect this branch”.

Click the checkbox next to “Require status checks to pass before merging”.

Click the checkbox next to “Require branches to be up to date before merging”.

At this point, you should see the dialog box above which says Sorry, we couldn’t find any status checks in the last week for the repository. This is expected.

Leave this browser window open for the time being. For the next steps, we need to head over to CircleCI.

Adding project to CircleCI

Head over to www.circleci.com and login with your GitHub account. Once logged in, you should see the circle CI dashboard.

We need to tell Circle that it should start building our GitHub project. We can do this with the following steps:

Click on “Projects” in the left navigation bar.

Click the “Add Project” button in the upper right-hand corner.

Find your repository and click the “Setup Button” on the far right-hand side of the screen.

Scroll past the setup information and click the “Start Building” button.

This will kick off your first build process with CircleCI!

Completing the GitHub Setup

Next, lets go back to our open GitHub browser window and refresh the screen. We should now see the CircleCI option. Make sure the checkbox next to ci/circleci is checked and click Save Changes.

Pushing our configuration

At this point, your github repo is configured to automatically run your CI process. Lets go ahead and create a branch, commit the changes and push up to Github.

$ git checkout -b feature/circle-ci-configuration
$ git add -a
$ git commit -m "Adding CI to my project"
$ git push origin feature/circle-ci-configuration

After pushing, go to GitHub and open up a PR for your branch.

If you navigate to the PR screen, you will be able to see the CircleCI build process information directly from the pull request window.

Once the build process finishes, everything will be green and you will be able to merge your pull request to master!

CONGRATULATIONS, your CI build pipeline with CircleCI and Github is now complete! That wasn’t too difficult was it?

Adding CI notifications to Slack

Now that we have our CI pipeline all hooked up, its time to show off to the rest of the development team! Lets integrate build status notification into Slack.

First we will need to enable CircleCI from within Slack. To do so visit the following URL:

https://<YOUR_SLACK_DOMAIN>.slack.com/apps/new/A0F7VRE7N-circleci

Select the channel that you would like notifications to be sent to and click Add CircleCI Integration

In the next window, copy the link displayed under Step 2.

Navigate back to the CircleCI dashboard and click on your project, then the setting gear icon in the upper right corner. Under the Notifications section in the left hand navigation, click on Chat Notifications.

Enter the link you copied from Slack into the link into the input bar and click Save.

And that is it! Your CircleCI build pipeline is now fully integrated with Slack! Check the Slack channel that you selected and should be able to see a test notification.

Conclusion

Continuous integration is a fantastic tool that helps developers build reliable, dependable and predictable applications. We would encourage everyone to add CI and branch protection to all of their software projects.

If you ever need help setting up your CI build process, please don’t hesitate to reach out!

About Mesh

Mesh is a software development consultancy located in Fremont, WA. Sign up for our monthly newsletter here. Get in touch info@meshstudio.io.

--

--