Having an automated environment to run builds every time a code push happens on the source code repository and broadcasting the status of the build to the team members will ensure code base sanity and help the development team avoid having cat fights over whose commit caused the nightly build to fail.

This blog will help you setup a continuous integration environment using Jenkins for a Node.js project hosted in a private Github repository with integrated Slack notifications.

Assumptions

You have basic understanding of how git and Github works.

Atleast rudimentary Node.js skills. If not the code is shared here and the steps to integrate it with the environment is provided below.

Basic Ubuntu knowledge since I am installing Jenkins in an AWS ubuntu instance.

We have set the agenda, lets dive in

Installing Jenkins

In order to install and setup a Jenkins server integrated with Github, we need a linux instance(Sorry! I am not a window’s fanboy) with a public IP. So I am setting up an AWS instance running Ubuntu 14.04 LTS operating system. You can also use any VPS providers or in-house servers but just make sure you have an public ip

Note: The setup can also be done locally without a public ip but in that case instead of Github intimating Jenkins on new code pushes, Jenkins must poll Github for changes which is not efficient and has API limitations.

To begin with, ssh into the server and install the basic essential libraries and Java jdk and jre.

sudo apt-get update

sudo apt-get install build-essential

sudo apt-get install python-software-properties

sudo apt-get install default-jre

sudo apt-get install default-jdk

After installing the basic libraries, lets install Jenkins by executing the following commands



sudo sh -c ‘echo deb

sudo apt-get update

sudo apt-get install jenkins wget -q -O — https://pkg.jenkins.io/debian/jenkins-ci.org.key | sudo apt-key add -sudo sh -c ‘echo deb http://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list’sudo apt-get updatesudo apt-get install jenkins

The above commands, along with installing Jenkins, also creates a user with the name jenkins which executes the automated services, launches Jenkins service as a daemon up on start.

Now Jenkins server is listening on port 8080 and it can accessed through <server IP>:8080 . If you want to change the port number to which Jenkins is listening, edit the /etc/default/jenkins to replace the line HTTP_PORT=8080 to HTTP_PORT=<preferred port number>

Setting up Jenkins

There are a few steps to follow for setting up Jenkins for the first time. Access the Jenkins server url from your favourite browser(read as chrome) and you will be asked to provide an admin password to unlock Jenkins and this password can be found in the following location

/var/lib/jenkins/secrets/initialAdminPassword

Once you provide the password, you will asked to create the first admin user

After the admin creation, Jenkins will prompt you to install the plugins. You can either opt to install suggested plugins or select the list of plugins you need to be installed

Once the plugins are installed, we are all set to create a new Job in Jenkins.

Tada!! Jenkins is ready

Setting up Node.js codebase

The Node.js code consists of a simple express.js application listening to a port 3000 and supporting tests to validate the same. The code is shown below and can be cloned from this repo.

Commit and push the code to Github. Now we can install Node.js in the same server that is running Jenkins using these commands

curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -

sudo apt-get install -y nodejs

Alternatively, you can also setup url to the version you require. Since we will running mocha to execute the test suites, install mocha globally

sudo apt-get install -g mocha

Integrating Jenkins with Github

Our Jenkins server has been sitting idle for a while now. Prior to setting up a new job in Jenkins, let us install Github plugin for Jenkins. From the home page, click on Manage Jenkins on the left side menu. Then click on Manage Plugins

On the available tab, search for Github and install the plugin. Once the plugin installation is complete, lets create a new job

Click on the create new jobs link and on the subsequent screen select Freestyle project and enter a desired project name and click Ok.

On the next screen we must configure the project details. As this is a Github project, mark the check box GitHub project beneath the project name and provide the project url. In the Source Code Management section provide the git url . In case of private git repositories, it is necessary to provide permissions to Jenkins to clone your private repo. You can provide username and password or preferably create Personal Access Token in Github and provide the details here.

Then check the Build when a change is pushed to Github checkbox in the Build Triggers section

In order to configure the build functionalities, select the Add build step dropbox in the Build section of the configuration page. Select Execute shell and in the command text area below add the line npm install . Lets first test the integration before running the actual test suite.

Click save and we are good to go. Now lets test if the handshake between our Jenkins server and Github is successful. On the left menu for the project, select the Build Now option and Jenkins schedules a build to run immediately.

Now that we have successfully communication with Github, lets run the test cases(remember we only added npm install in our execute script earlier). Just add mocha to the Execute Shell command box(You can do that from the configure link on the left menu of the project) and run a build. If it fails, check the Jenkins logs. To find the logs, click on Manage Jenkins from the left menu in the home page and select System log url

If the issue is that Jenkins could not find mocha, change the mocha command in the Execute Shell command box to the mocha installed in the local build folder (i.e.)

./node_modules/mocha/bin/mocha

As suggested by Simon RENOULT, it is better to run the binaries using npm rather than executing using the relative path of the executable. So you can add npm test to the build step rather than the mocha path. Also add the following in the package.json file

"scripts": {

"test": "mocha"

}

Run the build and once the build is successful, you can also check the logs for the confirmation.

Automating builds on new git pushes

Now we have successfully integrated Github with Jenkins and have run our test cases. But our goal is to run automated builds every time a push is made and not to run the builds manually. This also can be done by 2 ways

Creating a web hook in Github and github pings the Jenkins server when a code push is done

Configure Jenkins to constantly poll from Github and schedule a build when it detects a push

Annnnnnd you have guessed it right, it is better and optimal to go with the web hook option. Lets see how that can be done.

Click on the settings link on the Github repository and click on the Webhooks link from the side menu. In the webhooks page, add the Payload URL which by default is

http://<jenkins ip>:<jenkins port>/github-webhooks/

Don't forget to add the trailing slash

Select Just the push events radio button and add the webhook.

Immediately once the webhook is created, Github pings the appropriate server to check for the connectivity

If the ping is successful, we are ready to rock. Now to test this, lets make a change to the code and push the same. Once pushed, you can immediately see one more request in the webhooks page and you can notice a build being scheduled.

We have successfully scheduled a build when a push is made to repository. Our next stop is receiving slack notification with the build status.

Integrating Jenkins with Slack

For Jenkins to notify slack, we need to install Slack Notifications plugin in Jenkins. By now, you must know how to do this, so go ahead and install the plugin

On the Slack end, install the Jenkins CI app in your Slack account

Once Jenkins CI app is installed, select the channel in which you wanted the notifications to be posted and then add Jenkins integration which is facilitated by the token generated by Slack.

Once you have completed the set up at the Slack end, you need to configure Jenkins. Goto Manage Jenkins in the left menu and click on Configure System . In that page look for Global Slack Notifier Settings and add the team domain and the integration token generated by Slack in the earlier step.

Once the handshake is successful between slack and Jenkins, you can see a notification in the slack channel

The last piece of work to fit everything together is configuring our job in Jenkins for Post Build slack notification. Go to configure section the left menu within the Job page. In the configuration screen, select the Add post build action drop down in the Build section. You can now see a Slack Notifications option.

Select all the build notification options that you think will be useful for you and in the advanced options select send repeated failure notifications, if you notification for consecutive build failures.

Finally all the gazillion set up steps are done. Its time to test our continuous integration environment. Make a change to the code and push it to Github and you must see a build being initiated successfully in Jenkins and once the build is complete, you must get a notification in your Slack channel