Continuous Integration with Node.js, Heroku and GitLab CI/CD -Part 1.

https://hocweb.vn/deploy-app-nodejs-voi-gitlab-ci-cd/

https://medium.com/@McDave95/continuous-integration-with-node-js-heroku-and-gitlab-ci-cd-part-1-1fe93a1d5967


Image for post
CI/CD can be a mess at times, especially for newbies. The stress of having to use products you aren’t familiar with. But with GitLab’s integrated CI/CD feature it takes most of the hassle away.

What we’ll achieve:
  • Setup a node server with the express npm package
  • Setup GitLab CI/CD
  • Write Unit Test
  • Deploy app on Heroku

Prerequisites:
  • A GitLab account
  • Little understanding of Node.js
  • Git and Node installed on your system
  • Favourite Editor of choice (….visual studio code)

So our app would just take in two inputs, adds them together and returns the answer. Not so much you might say.
Dependencies:
  • express: — for handling our web server
  • body-parser: — Node.js body parsing middleware.
  • mocha: — test framework to run our unit test
  • chai: — javascript assertion library
  • supertest: — help us test our API endpoints
Create our project on GitLab:
If you haven’t already, navigate to https://gitlab.com/ to create a GitLab account, or sign in into your account to create a new project.

Image for post
From the above image, we made the project public and checked the initialize Readme box, click theCreate project button to create our new project on GitLab.
Clone Project:

Image for post
After our project has been created, click on the blue dropdown on the top right corner with the text Clone and select Clone with HTTPS or Clone with SSHclick on the copy icon and paste in your terminal of choice as such
When the cloning is done navigate into the project folder from your terminal and initialize the npm application with the following command
npm init -y
This should create a package.json file which contains our project details including that of the packages we would be using
Next, we create our .gitignore file copy the following code into the new file:

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# Typescript v1 declaration files
typings/

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env

# vscode settings folder
.vscode/
 
The above snippet helps us prevent most autogenerated files and folders from been pushed to our remote git repositories. One such folder is the node_modules folder.
Install our dependencies:
Next, we install the necessary dependencies. Type in the following into your terminal
npm i -S express body-parser mocha chai supertest
Setup our server:
Next, we create a new index.js file to house our server code and addition function. Copy the following into the file.

const express =  require('express');
const bodyParser = require('body-parser');

// Our function which adds two numbers and returns the result
const addNumbers = (firstNumber, secondNumber) => {
//   check that input is a number
  if (typeof(Number(firstNumber)) !== 'number' || typeof(Number(secondNumber)) !== 'number') {
    return 'Values should be integer or numbers'
  }
  return Number(firstNumber) + Number(secondNumber);
}

// Destructure our bodyParser methods
const { urlencoded, json } = bodyParser;
const port = process.env.PORT || 8080;
// intialize our express app
const app = express();

// Parse incoming requests data (https://github.com/expressjs/body-parser)
app.use(json());
app.use(urlencoded({ extended: false }));

// end point to add numbers
app.post('/api/add', (req, res) => {
  const { firstNumber, secondNumber } = req.body;
  const result =  addNumbers(firstNumber, secondNumber);
  return res.status(200).send({
    result
  });
});
// app entry point
app.get('/', (req, res) => res.status(200).send({
  message: 'Welcome to our glorious app',
}));
// Setup a default catch-all route that sends back a welcome message in JSON format.
app.get('*', (req, res) => res.status(200).send({
  message: 'Welcome to the beginning of nothingness.',
}));

app.listen(port, (err) => {
  if (!err) {
     console.log(`App started on port ${port}`);
  } else {
    console.log(err);
  }
});

module.exports = app;
 
Next, we edit our package.json file by adding a start script in our scripts object.

{
  "scripts": {
    "start": "node index.js"
  }
}
 
Let run app. Type the following in your terminal
npm start
You should get App started on port 8080 printed on your console.
Write Unit TestCreate a tests.js file in your current directory and paste the following code

const supertest = require('supertest');
const server = require('./index');
const chai = require('chai');

chai.should();

const api = supertest.agent(server);

describe('Add method', () => {
  it('should connect to the Server', (done) => {
    api.post('/api/add')
      .set('Connetion', 'keep alive')
      .set('Content-Type', 'application/json')
      .type('form')
      .send({
        firstNumber: 2,
        secondNumber: 3
      })
      .end((err, res) => {
        res.status.should.equal(200);
        res.body.result.should.equal(5);
        done();
      });
  });
})
 
 

Next, we add a test script to our package.json. Our script should look like the below:

 
“scripts”: {  “start”: “node index.js”,  “test”: “mocha --exit”}
Run your test by executing npm run test in your console.

Image for post
In part two we’ll cover creating our app on Heroku and setting deployment with .gitlab-ci.yml file.


 

 

 

 

Comments

Popular posts from this blog

Continuous Integration with Node.js, Heroku and GitLab CI/CD -Part 2.