Continous Integration/deployment. CircleCI and Heroku part 2.

cci

In our last post, we gave an introduction on what Continous Integration/deployment is and what tools we’ll use in this tutorial.

This post is purely hands-on so let’s get started :)

Create your root folder and name it anything you fancy. I’ll name mine oculus, just because I am slowly becoming a VR freak.

This will be your local git repository therefore run:

git init

Run by this article to have an understanding of what Git/Github are.

We’ll be using Node.js therefore create your package.json by running:

npm init

Next run:

npm install --save express

This installs the dependency express, which is the framework we’ll be using.

Create a server.js file and have this:

import express from 'express';

const app = express();
const port = process.env.PORT || 4040;

app.get('/', (req, res) => {
  res.send('Virtual Reality is the future');
});

app.listen(port, () => {
  console.log('Listening on port ' + port);
});

Since we are writing this in ES6 Javascript, we shall use babel to be able to transpile it to versions that can be understood by our browser/node environments.

Create a .babelrc file that will have your babel presets:

{
  "presets": ["es2015"]
}

Add the required dependencies in your package.json file by running:

npm install --save babel-cli babel-preset-2015

And finally globally install babel-node by running:

npm install babel-node -g

Now if you run :

babel-node server.js

your server should be running. We’ll assign this command to start script in our package.json file.

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node_modules/.bin/babel-node server.js"
  }

You can read more on node server with babel here.

Next we’ll set up linting with ESLint. First install the eslint package by running:

npm install eslint eslint-plugin-import

Create an .eslintrc file and add the following:

{
  "extends": [
    "eslint:recommended",
    "plugin:import/errors",
    "plugin:import/warnings"
  ],
  "parserOptions": {
    "ecmaVersion": 6,
    "sourceType": "module",
  },
  "env": {
    "es6": true,
    "browser": true,
    "node": true,
    "jquery": true,
    "mocha": true
  },
  "rules": {
    "quotes": 0,
    "no-console": 1,
    "no-debugger": 1,
    "no-var": 1,
    "semi": [1, "always"],
    "no-trailing-spaces": 0,
    "eol-last": 0,
    "no-unused-vars": 0,
    "no-underscore-dangle": 0,
    "no-alert": 0,
    "no-lone-blocks": 0,
  }
}

You can alter the rules according to your liking and also anything else you’d like to add. What the plugins intend to do is support linting of ES2015+ (ES6+) import/export syntax, and prevent issues with misspelling of file paths and import names.

Read more on ESLint documentation to understand this file and what you can play around with.

Next, let us create a test folder and write our tests. We are simply simulating a real app with a very basic structure. Create a test folder and add an exampleTest.js file and have this:

const expect = require('chai').expect;

describe('Tests', () => {
  it('Expects tests to pass', () => {
    expect(true).to.equal(true);
  });
});

What is happening here is we have a test suite that has one test case which asserts if true equals true. This is already a passing test :)

For testing we are using Mocha testing framework and Chai.js as the assertion library. Go ahead an install the packages i.e

npm install --save mocha chai

Install mocha on a global scope by running

npm install mocha -g

Now run the command mocha, and you should see passing tests. Looks something like this:

screen-shot-2016-10-18-at-3-37-23-am

We shall add this command to the scripts in our package.json also. You can replace what was originally there:

"scripts": {
    "test": "node_modules/.bin/_mocha ",
    "start": "node_modules/.bin/babel-node server.js"
  },

Now that we have simulated a simple working app with passing tests we shall go ahead and add CI integration, configure Heroku and the app and push to Github to deploy.

Head over to Heroku, sign up and create an App:

screen-shot-2016-10-18-at-3-47-39-am

I used riftoculus because all my other options had already been taken.

Next head over to Github and create an account and create a repository.

screen-shot-2016-10-18-at-4-05-36-am

Head back to Heroku and select Github as your deployment method. Search for your repository, connect and enable automatic deployment after CI tests pass:

screen-shot-2016-10-18-at-4-40-12-am

At this point, download Heroku’s CLI and login.

Next, let us set up CircleCI configuration through the circle.yml file. Add this file to the root of your directory and add this:

machine:
  node:
    version: 6.3.0
deployment:
  production:
    branch: master
    heroku:
      appname: riftoculus

What this means is you are setting the node version envorinment to 6.3.0 and on deployment, the branch master on Github should deploy to the Heroku app riftoculus. You should replace that section with the name of your app. Read more on the circle.yml file and config from CircleCi’s documentation.

This means when you deploy to develop branch on Github, no deployments to your Heroku app will be made. It is considered good practice to have a develop/staging app that simulates the one on master/production. This way you can tell how your app will behave when it is live.

Next we will have a Procfile in the root of our app to tell Heroku which command to execute to run your app. Therefore create the file and add this:

web: npm start

We are now ready to push to Github and watch our deployment happen. But first, we do not need everything on our root folder to be pushed, so create a .gitignore file and have this:

/node_modules

Add your remote repository by doing this: git remote add origin https://github.com/andela-gnyenyeshi/oculus.git (use your repo’s HTTPS)

Head over to CircleCi and click Go to app at the top right of your screen. On the left side of the screen, click Add Project from the list. From there, select your Github account and search for your repository.

Click the settings icon and under Continous Deployment, select Heroku Deployment. Go to Step 2 and set yourself as the current deploy user.

Finally add, commit and push (git push -u origin master)

If you go to your heroku app url i.e click open app on your dashboard, you should see what you set to appear on your default path i.e:

screen-shot-2016-10-18-at-5-25-13-am

 

We can make a change to our local app and if we push it will be automatically be deployed and your Heroku app instance will have these changes.

Troubleshooting tips:

  1. You can always see your builds on CircleCi which will help you understand the problem if your tests are not passing.
  2. If you go to your Heroku app URL and you get an error message on the screen, you can debug that by running:
  3. heroku logs --app <name of your app>

    This shows you the logs and will show you what is causing the error.

Happy Deploying :)

You may also like

Leave a Reply

Your email address will not be published. Required fields are marked *