Roll your own Node.js CI Server with Jenkins – Part 1

Travis is cool. Coveralls is hip. But Jenkins has had this stuff for a while, and more. In addition to running your test suite and generating coverage reports, you can generate checkstyle reports (linting), deploy to staging and production, and utilize Docker containers. The price for all of this is free for your public and private projects.

However, the hidden cost is your time. Figuring out how to get this to all to working is daunting when you first get started. Lucky for you, I’ve endured the pain to hopefully make this a fairly simple and straightfoward process.

This tutorial is broken up into two separate articles. The first covers the setup and configuration of Jenkins for Node projects. The second explores running a Node project through Jenkins to generate all sorts of fun stuff. We will start from a fresh installation and work our way to a fully-functioning “jenkinized” Node project with:

Code coverage analysis

Test suite results

Code style analysis

Support for build badges

Build hooks with GitHub

I have made the following assumptions in order to focus this article and hopefully cover the majority of readers:

You are using GitHub and git. You can use other services but for brevity, I’m just going to focus on GitHub functionality.

You are using a test runner that is able to output TAP. Most popular runners (i.e. mocha, tape) already support this protocol.

You are using a lint tool that is able to output Checkstyle reports (eslint and jshint both provide this).

Let’s get started!

Installation

Jenkins is a Java-based software that runs on multiple platforms. Follow the installation steps for your operating system at http://jenkins-ci.org or use Docker. I recommend installing a Long-Term Support Release (LTS) as plugins tend to be more stable.

After installation, you will see a happy screen like this:

Once you have installed Jenkins, it’s time to configure it. Let’s make Jenkins secure first.

Security

It’s a good idea to lock Jenkins down, especially if you plan on exposing it publically (which we will do in this tutorial). Even private projects will need some endpoints public.

Project-based matrix security

I find exposing Jenkins over HTTPS with project-based matrix security settings works the best with plugins and allows the most flexibility. This will allow you to set up anonymous access for public projects and lock down private projects. It also allows you to expose certain aspects publically for private projects like build status badges and hooks for private GitHub repositories.

Setting up a Jenkins user database

By default, Jenkins allows anyone to do anything in the system. Let’s change this. First, click “Manage Jenkins” (1) in the navigation sidebar and then click “Setup Security” (2). If you don’t see that button, just click “Configure Global Security” (2) in the list:

Now we can create accounts, so let’s set up an administrative account.

Creating an administrator account

The following steps effectively lock down the Jenkins instance to allow only your admin user to create new users and to view/administer the instance. You can always add more administrators later if desired.

First, create a user by clicking “Sign up” (1) and filling out the form (2) and submitting (3):

Visit the Global Security Page again (remember how to get there?!). Uncheck “Allow users to sign up”:

Once you are on the Manage Plugins page, visit the the “Available” tab:

Then search for (1) and select (2) the following plugins:

GitHub Plugin

Clover Plugin

Checkstyle Plug-in

TAP Plugin

Embeddable Build Status Plugin

NodeJS Plugin

After you’ll selected all the plugins, click “Install without restart”:

You will notice a handful of plugins that you didn’t select will also be installed as they are dependencies. Once all plugins indicate “Success”, you’re done.

If some plugins require a restart, you can kick that off by clicking the checkbox at the bottom and waiting for Jenkins to come back online.

We have our plugins installed that we’ll need; let’s get configuring!

Integrating with GitHub

The GitHub plugin will automatically setup the right hooks for you per project based on your GitHub repository through the GitHub API. Let’s configure this next and set up GitHub credentials for cloning repositories.

First, visit our now very familiar Manage Jenkins page and select “Configure System”. Then, find the “Jenkins Location” and ensure that it has a public facing URL so GitHub can push events to it. Make sure to save if you make changes.

Next, you will need to generate a token to use with the GitHub API. In order to set up the hooks, ensure the GitHub account has administrative rights to the repos.

In another browser tab, go to GitHub and ensure you are logged in with the account you want to use. Then, visit the “Settings” (1) page, and select “Applications” (2) from the sidebar. Finally, click “Generate new token” (3):

Next, set the relevant permissions to enable the hooks to work properly in Jenkins by giving the hook a name (1), setting “repo”, “public_repo” and “admin:repo_hook” (2), and then clicking “Generate” (3):

Then copy the generated key:

Now, flip back to your Jenkins Configure System tab and visit the “GitHub Web Hook” section and select “Let Jenkins auto-manage hook URLs” (1). Then, add your GitHub username and copied OAuth token to the “GitHub Credentials” section (2). , click “Test Credential” (3) to make sure everything is working, you should see “Verified” if all is good to go. Lastly, click “Save” (4) to persist the changes.

Now GitHub hooks will work. We need to add our credentials in one more spot to pull private repositories though. Head over to “Credentials” (1) in the navigation sidebar and select “Global credentials” (2) from the list:

Next, click “Add credentials” (1) in the sidebar and fill out the form (2) using your same user and token you entered previously and submit (3):

GitHub is now ready to be utilized fully! Let’s get Node working next.

Setting up Node

The NodeJS plugin allows you to run different projects against different versions of Node. It also handles the installations and writes Jenkins scripts in Node.

To my knowledge this plugin only works on Linux. If you use another OS, install Node globally on the same server and make sure the node and npm executables are accessible to the jenkins user. Also, and perhaps more preferable in some cases, you can run a Docker container on Mac or Windows and use this plugin without issue.

First, visit the Configure System page in Manage Settings and select “Add NodeJS” from the “NodeJS” section:

Then, let’s give this install a “Name” (1), which will be a selectable option when setting up an individual project. We will call ours 0.10 to represent that latest 0.10.x version of Node. Next, check “Install automatically” (2). A select will appear; choose “Install from nodejs.org” (3):

Now, select the most recent version of 0.10, which at the time of writing was 0.10.33 (1). You may define optional global packages to install (2). We’ll bundle our build dependencies locally in this tutorial so we won’t need this set. Finally, click “Save” (3):

Node is ready to be used now with your projects.

Exposing build badges publically

This is our last step. Build badges are things to put in your Github readme.md and elsewhere that indicate the state of the build:

To expose this ability, head back to the Configure Global Security page in Manage Settings and check “ViewStatus” for the “Anonymous” user in the “Job” section. Make sure to “Save” afterwards.

From a security standpoint, an anonymous user will only be able to access that icon.

Summary

This concludes part 1 of the Jenkins tutorial. We accomplished the following:

Installed Jenkins

Secured the Jenkins instance

Installed some plugins we’ll need

Set up GitHub to play nicely with Jenkins

Set up Node to work with Jenkins

Exposed build status icons

Now that we have all the necessary components to get a Node project up and running, we are ready to integrate a project! For that, let’s head over to part 2.