Continuous Integration for Express APIs with Travis CI

综合技术 2017-11-15

This article cover how to use Travis CI service with NodeJS for an open source project hosted on GitHub. At the end, you would be able to setup a basic build pipeline to automatically validate your code using Continuous Integration (CI) .

Note:This is the 6th post of a series about Building APIs With Express . The code of this post will be developed over the generated code of the last post ( Testing an API Against Documentation ).

Travis CI

Travis CI is one of the most used Continuous Integration services in the open source community. It's ridiculous how easy is to enable it for a GitHub project. To activate it you have to reate an account in give it access to your GitHub projects and then in the Travis CI profile page activate the service for your project.

And that's all you need, thanks for the reading! Ah... ok, maybe there is needed something more...

Ok, for start building things with Travis you have to update your code. Once Travis detects some new branch or commits on your repo it will run a build with that code , but at this point, it will fail.

Setup Travis CI for NodeJS

Yes, there is a little thing to do before Travis starts working for us. It doesn't know what to do with that GitHub repository, to help in this, the repo has to have a config file ( .travis.yml ) that tells Travis what to do with the code . If we don't use this file it will try to build the project using Ruby.


language: node_js  
node_js: "node"

This is the simplest Travis CI config file for start building in NodeJS.

  • language : To set which engine are we using to build our project
  • node_js : To specify which version of node use for the build "node" === "latest version"

Note:More info about the configs on the docs for Travis with JavaScript .

First build

After committing this file and uploading it to GitHub, Travis will start a new build, in this case with the next logs:

Worker information  
version: v3.4.0  
instance: 7917cbf travisci/ci-garnet:packer-1503972846 (via amqp)  
startup: 571.280161ms  
Build system information  
Build language: node_js


MongoDB version  
MongoDB 3.2.16


$ git clone --depth=50 --branch=post/06 AlbertoFdzM/another-todo-api
Cloning into 'AlbertoFdzM/another-todo-api'...  
remote: Counting objects: 124, done.  
remote: Compressing objects: 100% (2/2), done.  
remote: Total 124 (delta 0), reused 2 (delta 0), pack-reused 121  
Receiving objects: 100% (124/124), 79.47 KiB | 15.89 MiB/s, done.  
Resolving deltas: 100% (54/54), done.

$ cd AlbertoFdzM/another-todo-api
$ git checkout -qf dac5b5b13eef6d36ec76538c8194ce32923d628a
$ export PATH=./node_modules/.bin:$PATH
Updating nvm  
$ nvm install node
Downloading and installing node v9.1.0...  
######################################################################## 100.0%
Computing checksum with sha256sum  
Checksums matched!  
Now using node v9.1.0 (npm v5.5.1)

$ node --version
$ npm --version
$ nvm --version
$ yarn
yarn install v0.27.5  
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
Done in 131.09s.

$ npm test

> another-todo-api@0.0.0 test /home/travis/build/AlbertoFdzM/another-todo-api
> dredd

info: Configuration './dredd.yml' found, ignoring other arguments.  
warn: Apiary API Key or API Project Subdomain were not provided. Configure Dredd to be able to save test reports alongside your Apiary API project:  
info: Starting backend server process with command: npm start  
info: Waiting 3 seconds for backend server process to start

> another-todo-api@0.0.0 start /home/travis/build/AlbertoFdzM/another-todo-api
> set DEBUG=another-todo:* && node bin/www

(node:4653) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): MongoError: failed to connect to server [localhost:27017] on first connect [MongoError: connect ECONNREFUSED]
info: Beginning Dredd testing...  
info: Found Hookfiles: 0=/home/travis/build/AlbertoFdzM/another-todo-api/docs/hooks.js  
error: GET (200) /tasks duration: 120101ms  
error: Error connecting to server under test!  
GET /v1/tasks - - ms - -  
error: POST (201) /tasks duration: 120105ms  
error: Error connecting to server under test!  
error: GET (200) /tasks/586e88337106b038d820a54f duration: NaNms  
error: TypeError: Cannot read property 'body' of undefined  
    at replaceUrlForCreatedTaskId (/home/travis/build/AlbertoFdzM/another-todo-api/docs/hooks.js:10:89)


complete: 0 passing, 0 failing, 10 errors, 0 skipped, 6 total  
complete: Tests took 720719ms  
complete: See results in Apiary at:  
info: Backend server process exited  
npm ERR! Test failed.  See above for more details.  
The command "npm test" exited with 1.  
Done. Your build exited with 1.

Note: Some logs traces have been omitted to improve readability. You can check the whole log in the Travis CI build report .

What has happened?

There are some good things and some bad thing to pay attention to. The first one is that Travis has made a build with node! It gives a lot of info about what is happening in that machine that is building the project in "the cloud" (OS version, node version, npm version, what things are installed in the system..)

  1. Clone the repo: git clone --depth=50 --branch=post/06 AlbertoFdzM/another-todo-api
  2. Install NodeJS: nvm install node
  3. Install project dependencies: yarn (it detects that we have a yarn.lock file in the project)
  4. Execute the tests: npm test ( default build command for Travis on NodeJS )
  5. The tests fail: npm ERR! Test failed. See above for more details. 😥
  6. The build fails: Done. Your build exited with 1. (hint: 1 is bad, 0 is good)

The problem:

(node:4653) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): MongoError: failed to connect to server [localhost:27017] on first connect [MongoError: connect ECONNREFUSED]

It hasn't connected to the MongoDB database even though MongoDB was installed in the system:

MongoDB version  
MongoDB 3.2.16

This is because Travis doesn't start the service unless you tell it to do so .

Let's fix it.


language: node_js  
node_js: "node"  
services: mongodb

Commit, push, check the build and... :tada: Done. Your build exited with 0. (reminder: 0 is good)

Stop the machines, we can go home finally.

Wait... This post for a file with 3 lines only?

Yep, but there was already some things done, like well-defined dependencies in the package.json and tests defined using node standard practices width npm test .

Want more? Ok, there is more to do.

Travis CI Caching

The Travis config file can define which folders should be cached to improve the builds time. In this case, I'm going to cache the node_modules folder to reduce the time installing dependencies and also for yarn .


language: node_js  
node_js: "node"  
services: mongodb  
    - "node_modules"
  yarn: true

Note: More info in Travis CI Caching documentation .

Travis Build Over Multiple NodeJS Version

Travis CI can be configured to run against multiple NodeJS versions every time it builds to ensure the project works correctly in this environments.

For this project, it will run builds for the "latest" version, for NodeJS v4.x and NodeJS v7.x.


language: node_js  
  - "node"
  - "7"
  - "4"
services: mongodb  
    - "node_modules"
  yarn: true

THE Travis Status Badge

This is the only very thing why all of us integrate our projects with Travis. To be the fanciest on GitHub wearing a bunch of blue/green badges saying that everything is ok and all is up to date.

To get the code you have to click on the badge from the Travis CI page of your project, a dialog will appear showing you different options about which branch and in what kind of code you want the image, then add it wherever you want.

That image will show the updated build status of the branch you selected.

# Another boring TODO API

[![Build Status](](


GitHub Code Supervision with Travis CI

Another cool thing Travis can do is to check every bit of code that changes in the project and avoid breaking changes to be merged into critical branches as well as notify about commits breaking the build.

Checking the commits history with Travis integrated there appears checks and crosses indicating if the build executed for that commit went ok, and by clicking them you can go to the Travis build logs.

To avoid direct commits against a branch in GitHub and instead add code to it by Pull Requests you can activate the Branch Protection under the Project Settings inside the Branches section. Once there select the branch you want to protect and check "Protect this branch", "Require status checks to pass before merging", "Require branches to be up to date before merging", "continuous-integration/travis-ci" and "Include administrators".

By this way, all the code to be modified in that branch has to pass through a PR and then complete a successful build with Travis.


Travis CI is perfect to ensure the sanity of your code and to maintain good practices against the project, it also helps to detect possible bugs caused by refactors or changes in the functionality of the project. But that's not all, with advanced builds you could make deploys to production servers o build a compiled version for the end-user.

As always, you can check the generated code on GitHub .

责编内容by:Only The Pixel (源链)。感谢您的支持!


Introduction to web scraping with Node.js For a long time when ever I wanted to try and create websites for practice I wou...
node.js使用Nodemailer发送邮件 原文链接: Node.js使用Nodemailer发送邮件 电子邮件是—种用电子手段提供信息交换的通信方式,是互联网应用最广的服务。通过网络的电子邮...
Protected routes and Authentication with React and... Well, last weekend I wanted to dig into some good old React without fancy stuffs...
Sending messages client->server->client on s... I'm using NodeJS+Socket.IO for simple web game. It works. Why? Here's my ...
10个最佳Node.js企业应用案例:从Uber到LinkedIn... Node.js 8已经发布了,NPM模块每周下载量早已超过10亿,从Uber到LinkedIn都在使用Node.js,谁说JavaScript不能写后台?...