[Tutorial] Part 1 — How to integrate CircleCI & Codecov into your project

CI/CD (Continuous Integration/Continuous Delivery or Deployment) are methods to deliver applications with more frequency by using automation. CircleCI and Codecov are tools that can help you with this task.

Continuous Integration

Continuous Integration is when you develop a new feature and it is tested and consolidated with the shared repository. This automated process will provide some advantages like:

Continuous Delivery or Deployment

Continuous Delivery or Deployment refers to automation on the advanced parts of a pipeline. The main difference between them is:

This means that on Continuous Delivery there needs to exist human approval for a new feature to be released and on Continuous Deployment that feature will be automatically deployed into production without any human interaction, which will require some very robust test suites.

CircleCI

CircleCI is a tool that will allow you to implement CI/CD on your project. It is pretty easy to create a YAML config, mainly because they provide excellent documentation. It may take between 5–10 minutes to configure a project.

Configuration

The first step is to create an account on CircleCI with your GitHub account. Then, you’ll need to set up the project you want on the CircleCI website. On the left tab, press the “Add projects” tab, which will take you to the following page that displays all your Github projects.

Then it will open a page with instructions to Set Up the project. There you will have a list of steps you have to follow.

Config.yml file

The first step is to create a folder named “.circleci” and add a file inside called “config.yml” with the following content:

-- CODE language-yml line-numbers --
version: 2<br>
jobs:<br>
&nbsp;build:<br>
 &nbsp;&nbsp;docker:  <br>
  &nbsp;&nbsp;&nbsp;- image: circleci/ruby:2.4.1 <br>
 &nbsp;&nbsp;steps:  <br>
  &nbsp;&nbsp;&nbsp;- checkout  <br>
  &nbsp;&nbsp;&nbsp;- run: echo "A first hello"<br>

This is the simplest config file that will only display a message on the CircleCI console. Push these changes to your GitHub repository. On the CircleCI page, you were before press the “Start Building” button.

After this, you will see the end-result right away.

Now, let us take a look at an important step called “checkout” which will retrieve the GitHub code into the CircleCI machine. To do this, edit the “config.yml” file with this:

-- CODE language-yml line-numbers --
version: 2<br>
jobs:<br>
&nbsp;build:<br>
&nbsp;&nbsp;docker:<br>
&nbsp;&nbsp;&nbsp;- image: alpine:3.7<br>
&nbsp;&nbsp;steps:<br>
&nbsp;&nbsp;&nbsp;- checkout<br>
&nbsp;&nbsp;&nbsp;- run:<br>
&nbsp;&nbsp;&nbsp;&nbsp;name: The First Step<br>
&nbsp;&nbsp;&nbsp;&nbsp;command: |<br>
&nbsp;&nbsp;&nbsp;echo 'Hello World!'<br>
&nbsp;&nbsp;&nbsp;echo 'This is the delivery pipeline'<br>
&nbsp;&nbsp;&nbsp;- run:<br>
&nbsp;&nbsp;&nbsp;name: Code has arrived<br>
&nbsp;&nbsp;&nbsp;command: |<br>
&nbsp;&nbsp;ls -al<br>
&nbsp;&nbsp;echo '^^^That should look familiar^^^'<br>

To show you that it retrieved all the code from the GitHub project the code above will also show you the file system inside the CircleCI machine

Before diving into more complex configurations let us talk about CircleCI Workflows which will let us make Continuous Delivery or Deployment.

CircleCI Workflows

Workflows let you define collections of jobs and their run order. This will increase your software development trough:

Besides this, with workflows you can:

Workflows come in four different types:

With all this said, let’s see how it works!

Workflow set up

The first step to create a workflow is by editing the config.yml file. Where we will define the jobs and then the workflows.

On top of the file we create our jobs, and on the bottom of the file, we create the workflows:

-- CODE language-yml line-numbers --
&nbsp;version: 2<br>
&nbsp;jobs:<br>
&nbsp;&nbsp;&nbsp; Hello-World:<br>
  &nbsp;&nbsp; docker:<br>
     &nbsp;&nbsp;&nbsp;- image: alpine:3.7<br>
   &nbsp;&nbsp;steps:<br>
    &nbsp;&nbsp;&nbsp; - run:<br>
        &nbsp;&nbsp;&nbsp;&nbsp; name: Hello World<br>
       &nbsp;&nbsp;&nbsp;&nbsp;  command: |<br>
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   echo 'Hello World!'<br>
         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  echo 'This is the delivery pipeline'<br>
&nbsp;&nbsp;&nbsp; I-Have-Code:<br>
  &nbsp;&nbsp;&nbsp;&nbsp; docker:<br>
   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  - image: alpine:3.7<br>
   &nbsp;&nbsp;&nbsp;&nbsp;steps:<br>
    &nbsp;&nbsp;&nbsp; - checkout<br>
    &nbsp;&nbsp;&nbsp; - run:<br>
     &nbsp;&nbsp;&nbsp;&nbsp;    name: Code Has Arrived<br>
       &nbsp;&nbsp;&nbsp;&nbsp;  command: |<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;     ls -al<br>
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   echo '^^^That should look familiar^^^'<br>
 &nbsp;&nbsp;&nbsp;Run-With-Node:<br>
   &nbsp;&nbsp;&nbsp;&nbsp;docker:<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - image: circleci/node:10-browsers<br>
   &nbsp;&nbsp;&nbsp;&nbsp;steps:<br>
     &nbsp;&nbsp;&nbsp;- run:<br>
         &nbsp;&nbsp;&nbsp;&nbsp;name: Running In A Container With Node<br>
        &nbsp;&nbsp;&nbsp;&nbsp; command: |<br>
         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  node -v<br>
 &nbsp;&nbsp;&nbsp;Now-Complete:<br>
  &nbsp;&nbsp;&nbsp;&nbsp; docker:<br>
     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- image: alpine:3.7<br>
   &nbsp;&nbsp;steps:<br>
   &nbsp;&nbsp;&nbsp;&nbsp;  - run:<br>
    &nbsp;&nbsp;&nbsp;&nbsp;     name: Approval Complete<br>
       &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  command: |<br>
          &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo 'Do work once the approval has completed'<br>

-- CODE language-yml line-numbers --
workflows:<br>
version: 2<br>
Example_Workflow:<br>
 &nbsp; jobs:<br>
   &nbsp;&nbsp; - Hello-World<br>
  &nbsp;&nbsp;  - I-Have-Code:<br>
      &nbsp;&nbsp;&nbsp;  requires:<br>
       &nbsp;&nbsp;&nbsp;&nbsp;   - Hello-World<br>
    &nbsp;&nbsp;&nbsp;- Run-With-Node:<br>
      &nbsp;&nbsp;&nbsp;&nbsp;  requires:<br>
          &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- Hello-World<br>
   &nbsp;&nbsp;&nbsp; - Hold-For-Approval:<br>
       &nbsp;&nbsp;&nbsp;&nbsp; type: approval<br>
      &nbsp;&nbsp;&nbsp;&nbsp;  requires:<br>
       &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   - Run-With-Node<br>
       &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   - I-Have-Code<br>
   &nbsp;&nbsp;&nbsp; - Now-Complete:<br>
       &nbsp;&nbsp;&nbsp;&nbsp; requires:<br>
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  - Hold-For-Approval<br>

Did you spot which type of workflow this is? It is an Approval workflow because, as you can see, the “Hold-for-approval” job is type “Approval”. This means that this workflow will only end when an allowed user approves it and for this, we can conclude that this is also a Continuous Delivery pipeline.

The following images show how this workflow is shown in the CircleCI interface and how we can approve this pipeline.

After all of this information, let’s apply it to a real project. First off, we will create some basic functions and some basic tests so that we can run the CircleCI tests and check if everything is going smoothly.

Basic functions

-- CODE language-js line-numbers --
function sum(a, b) {<br>
 &nbsp;return a + b;<br>
}function sub(a, b) {<br>
 &nbsp;return a - b<br>
}function multiply(a, b) {<br>
 &nbsp;return a * b<br>
}function divide(a, b) {<br>
 &nbsp;return a / b<br>
}<br>
module.exports = {<br>
 &nbsp;sum,<br>
 &nbsp;sub,<br>
 &nbsp;multiply,<br>
 &nbsp;divide,<br>
}<br>

Basic tests

-- CODE language-js line-numbers --
const {sum, sub, multiply, divide } = require('./index')test('Adds 1+2 and expects 3', () => {<br>
 &nbsp;expect(sum(1,2)).toBe(3)<br>
})<br>test('Subtracts 2-1 and returns 1', () => {<br>
 &nbsp;expect(sub(2, 1)).toBe(1)<br>
})<br>test('Multiply 2 and 2 a return 4', () => {<br>
 &nbsp;expect(multiply(2, 2)).toBe(4)<br>
})<br>test('divides 4 per 2 and returns 2', () => {<br>
 &nbsp;expect(divide(4, 2)).toBe(2)<br>
})

After creating this, we have to edit one of the jobs on our config.yml file so that it installs and runs our tests.
Since we already have a “Run-With-Node” job let’s edit it.

-- CODE language-yml line-numbers --
Run-With-Node:<br>
  &nbsp; docker:<br>
   &nbsp;&nbsp;  - image: circleci/node:10-browsers<br>
  &nbsp; steps:<br>
   &nbsp;&nbsp;  - checkout<br>
    &nbsp;&nbsp; - run:<br>
    &nbsp;&nbsp;&nbsp;     name: install and run tests<br>
     &nbsp;&nbsp;&nbsp;    command: |<br>
      &nbsp;&nbsp;&nbsp;&nbsp;     yarn install && yarn test<br>

With this, we have all set up to run tests on CircleCI which will output something like this:

And that’s it for CircleCI 🎉 Now before jumping into Codecov on part 2 let’s just protect our master branch so that we are not able to push changes into master before all the tests run.

This can be easily made by going into the project settings, then accessing the “Branches” settings and add a rule where we protect the master branch and mark the “Require status to pass before merging”, selecting also all the status checks we want.

All is done in this part! 🎉 🥳

Head over to part two to continue the tutorial.

Pedro Fonseca
Full-Stack Developer