Saturday December 26, 2020 By David Quintanilla
Creating A Continuous Integration Test Workflow Using GitHub Actions — Smashing Magazine

About The Creator

Fiyinfoluwa Akinsiku is a backend developer coming from a microbiology background. She is regularly amazed on the some ways during which expertise makes life …
More about

With the assistance of this tutorial, you possibly can learn to create a steady integration workflow in your Node JS REST API through the use of GitHub Actions in addition to report check protection with Coveralls.

When contributing to tasks on model management platforms like GitHub and Bitbucket, the conference is that there’s the primary department containing the practical codebase. Then, there are different branches during which a number of builders can work on copies of the primary to both add a brand new characteristic, repair a bug, and so forth. It makes a whole lot of sense as a result of it turns into simpler to watch the type of impact the incoming modifications can have on the prevailing code. If there’s any error, it may possibly simply be traced and stuck earlier than integrating the modifications into the primary department. It may be time-consuming to undergo each single line of code manually on the lookout for errors or bugs — even for a small venture. That’s the place steady integration is available in.

What Is Steady Integration (CI)?

“Steady integration (CI) is the observe of automating the mixing of code modifications from a number of contributors right into a single software program venture.”

— Atlassian.com

The overall concept behind steady integration (CI) is to make sure modifications made to the venture don’t “break the construct,” that’s, spoil the prevailing code base. Implementing steady integration in your venture, relying on the way you arrange your workflow, would create a construct every time anybody makes modifications to the repository.

So, What Is A Construct?

A construct — on this context — is the compilation of supply code into an executable format. Whether it is profitable, it means the incoming modifications won’t negatively influence the codebase, and they’re good to go. Nevertheless, if the construct fails, the modifications must be reevaluated. That’s the reason it’s advisable to make modifications to a venture by engaged on a replica of the venture on a distinct department earlier than incorporating it into the primary codebase. This manner, if the construct breaks, it will be simpler to determine the place the error is coming from, and it additionally doesn’t have an effect on your most important supply code.

“The sooner you catch defects, the cheaper they’re to repair.”

— David Farley, Steady Supply: Dependable Software program Releases by way of Construct, Check, and Deployment Automation

There are a number of instruments accessible to assist with creating steady integration in your venture. These embody Jenkins, TravisCI, CircleCI, GitLab CI, GitHub Actions, and so on. For this tutorial, I can be making use of GitHub Actions.

GitHub Actions For Steady Integration

CI Actions is a reasonably new characteristic on GitHub and permits the creation of workflows that robotically run your venture’s construct and assessments. A workflow incorporates a number of jobs that may be activated when an occasion happens. This occasion might be a push to any of the branches on the repo or the creation of a pull request. I’ll clarify these phrases intimately as we proceed.

Let’s Get Began!


This can be a tutorial for newbies so I’ll largely speak about GitHub Actions CI on a floor degree. Readers ought to already be aware of making a Node JS REST API utilizing the PostgreSQL database, Sequelize ORM, and writing assessments with Mocha and Chai.

You also needs to have the next put in in your machine:

  • NodeJS,
  • PostgreSQL,
  • NPM,
  • VSCode (or any editor and terminal of your alternative).

I’ll make use of a REST API I already created referred to as countries-info-api. It’s a easy api with no role-based authorizations (as on the time of penning this tutorial). This implies anybody can add, delete, and/or replace a rustic’s particulars. Every nation can have an id (auto-generated UUID), title, capital, and inhabitants. To realize this, I made use of Node js, categorical js framework, and Postgresql for the database.

I’ll briefly clarify how I arrange the server, database earlier than I start with writing the assessments for check protection and the workflow file for steady integration.

You possibly can clone the countries-info-api repo to comply with by way of or create your personal API.

Know-how used: Node Js, NPM (a bundle supervisor for Javascript), Postgresql database, sequelize ORM, Babel.

Setting Up The Server

Earlier than organising the server, I put in some dependencies from npm.

npm set up categorical dotenv cors

npm set up --save-dev @babel/core @babel/cli @babel/preset-env nodemon

I’m utilizing the categorical framework and writing within the ES6 format, so I’ll want Babeljs to compile my code. You possibly can learn the official documentation to know extra about the way it works and configure it in your venture. Nodemon will detect any modifications made to the code and robotically restart the server.

Observe: Npm packages put in utilizing the --save-dev flag are solely required in the course of the improvement phases and are seen below devDependencies within the bundle.json file.

I added the next to my index.js file:

import categorical from "categorical";
import bodyParser from "body-parser";
import cors from "cors";
import "dotenv/config";

const app = categorical();
const port = course of.env.PORT;


app.use(bodyParser.urlencoded({ prolonged: true }));


app.get("/", (req, res) => {
    res.ship({message: "Welcome to the homepage!"})

app.hear(port, () => {
    console.log(`Server is operating on ${port}...`)

This units up our api to run on no matter is assigned to the PORT variable within the .env file. That is additionally the place we can be declaring variables that we don’t need others to simply have entry to. The dotenv npm bundle hundreds our surroundings variables from .env.

Now after I run npm run begin in my terminal, I get this:

Server running
Server up and operating on port 3000. (Large preview)

As you possibly can see, our server is up and operating. Yay!

This hyperlink in your internet browser ought to return the welcome message. That’s, so long as the server is operating.

Homepage. (Large preview)
Subsequent up, Database and Fashions.

I created the nation mannequin utilizing Sequelize and I related to my Postgres database. Sequelize is an ORM for Nodejs. A serious benefit is that it saves us the time of writing uncooked SQL queries.

Since we’re utilizing Postgresql, the database will be created through the psql command line utilizing the CREATE DATABASE database_name command. This may also be carried out in your terminal, however I favor PSQL Shell.

Within the env file, we’ll arrange the connection string of our database, following this format beneath.

TEST_DATABASE_URL = postgres://<db_username>:<db_password>@<database_name>

For my mannequin, I adopted this sequelize tutorial. It’s straightforward to comply with and explains every thing about organising Sequelize.

Subsequent, I’ll write assessments for the mannequin I simply created and arrange the protection on Coverall.

Writing Checks And Reporting Protection

Why write assessments? Personally, I consider that writing assessments enable you as a developer to higher perceive how your software program is anticipated to carry out within the palms of your person as a result of it’s a brainstorming course of. It additionally helps you uncover bugs on time.


There are totally different software program testing strategies, nevertheless, For this tutorial, I made use of unit and end-to-end testing.

I wrote my assessments utilizing the Mocha check framework and the Chai assertion library. I additionally put in sequelize-test-helpers to assist test the mannequin I created utilizing sequelize.outline.

Check protection:

It’s advisable to examine your check protection as a result of the outcome exhibits whether or not our check circumstances are literally masking the code and likewise how a lot code is used after we run our check circumstances.

I used Istanbul (a check protection software), nyc (Instabul’s CLI consumer), and Coveralls.

In keeping with the docs, Istanbul devices your ES5 and ES2015+ JavaScript code with line counters, to be able to monitor how properly your unit-tests train your codebase.

In my bundle.json file, the check script runs the assessments and generates a report.

    "scripts": {
        "check": "nyc --reporter=lcov --reporter=textual content mocha -r @babel/register ./src/check/index.js"

Within the course of, it should create a .nyc_output folder containing the uncooked protection info and a protection folder containing the protection report information. Each information should not crucial on my repo so I positioned them within the .gitignore file.

Now that we’ve got generated a report, we’ve got to ship it to Coveralls. One cool factor about Coveralls (and different protection instruments, I assume) is the way it reviews your check protection. The protection is damaged down on a file by file foundation and you’ll see the related protection, coated and missed traces, and what modified within the construct protection.

To get began, set up the coveralls npm bundle. You additionally must check in to coveralls and add the repo to it.

coveralls repo
Repo related to Coveralls. (Large preview)

Then arrange coveralls in your javascript venture by making a coveralls.yml file in your root listing. This file will maintain your repo-token gotten from the settings part in your repo on coveralls.

One other script wanted within the bundle.json file is the protection scripts. This script will come in useful after we are making a construct through Actions.

    "scripts":  node ./node_modules/coveralls/bin/coveralls.js --verbose"

Principally, it should run the assessments, get the report, and ship it to coveralls for evaluation.

Now to the primary level of this tutorial.

Create Node JS Workflow File

At this level, we’ve got arrange the mandatory jobs we can be operating in our GitHub Motion. (Questioning what “jobs” imply? Hold studying.)

GitHub has made it straightforward to create the workflow file by offering a starter template. As seen on the Actions web page, there are a number of workflow templates serving totally different functions. For this tutorial, we’ll use the Node.js workflow (which GitHub already kindly prompt).

Actions page
GitHub Actions web page. (Large preview)

You possibly can edit the file instantly on GitHub however I’ll manually create the file on my native repo. The folder .github/workflows containing the node.js.yml file can be within the root listing.

This file already incorporates some primary instructions and the primary remark explains what they do.

# This workflow will do a clear set up of node dependencies, construct the supply code and run assessments throughout totally different variations of node

I’ll make some modifications to it in order that along with the above remark, it additionally runs protection.

My .node.js.yml file:

title: NodeJS CI
on: ["push"]
    title: Construct
    runs-on: windows-latest
        node-version: [12.x, 14.x]
    - makes use of: actions/checkout@v2
    - title: Use Node.js ${{ matrix.node-version }}
      makes use of: actions/setup-node@v1
        node-version: ${{ matrix.node-version }}
    - run: npm set up
    - run: npm run construct --if-present
    - run: npm run protection

    - title: Coveralls
      makes use of: coverallsapp/github-action@grasp
        COVERALLS_REPO_TOKEN: ${{ secrets and techniques.COVERALLS_REPO_TOKEN }}
        COVERALLS_GIT_BRANCH: ${{ github.ref }}
        github-token: ${{ secrets and techniques.GITHUB_TOKEN }}

What does this imply?

Let’s break it down.

  • title
    This may be the title of your workflow (NodeJS CI) or job (construct) and GitHub will show it in your repository’s actions web page.
  • on
    That is the occasion that triggers the workflow. That line in my file is principally telling GitHub to set off the workflow every time a push is made to my repo.
  • jobs
    A workflow can comprise not less than a number of jobs and every job runs in an setting specified by runs-on. Within the file pattern above, there is only one job that runs the construct and likewise runs protection, and it runs in a home windows setting. I also can separate it into two totally different jobs like this:

Up to date Node.yml file

title: NodeJS CI
on: [push]
    title: Construct
    runs-on: windows-latest
        node-version: [12.x, 14.x]
    - makes use of: actions/checkout@v2
    - title: Use Node.js ${{ matrix.node-version }}
      makes use of: actions/setup-node@v1
        node-version: ${{ matrix.node-version }}
    - run: npm set up
    - run: npm run construct --if-present
    - run: npm run check

    title: Coveralls
    runs-on: windows-latest
        node-version: [12.x, 14.x]
    - makes use of: coverallsapp/github-action@grasp
        COVERALLS_REPO_TOKEN: ${{ secrets and techniques.COVERALLS_REPO_TOKEN }}
        github-token: ${{ secrets and techniques.GITHUB_TOKEN }}
  • env
    This incorporates the setting variables which can be accessible to all or particular jobs and steps within the workflow. Within the protection job, you possibly can see that the setting variables have been “hidden”. They are often present in your repo’s secrets and techniques web page below settings.
  • steps
    This principally is a listing of the steps to be taken when operating that job.
  • The construct job does a variety of issues:
    • It makes use of a checkout motion (v2 signifies the model) that actually checks-out your repository in order that it’s accessible by your workflow;
    • It makes use of a setup-node motion that units up the node setting for use;
    • It runs set up, construct and check scripts present in our bundle.json file.
  • protection
    This makes use of a coverallsapp motion that posts your check suite’s LCOV protection knowledge to coveralls.io for evaluation.
successful jobs
All jobs run efficiently. (Large preview)

I initially made a push to my feat-add-controllers-and-route department and forgot so as to add the repo_token from Coveralls to my .coveralls.yml file, so I acquired the error you possibly can see on line 132.

Failed build
Failed job because of error in coveralls’ config file. (Large preview)
Dangerous response: 422 {"message":"Couldn’t discover a repository matching this job.","error":true}

As soon as I added the repo_token, my construct was in a position to run efficiently. With out this token, coveralls wouldn’t be capable to correctly report my check protection evaluation. Good factor our GitHub Actions CI identified the error earlier than it acquired pushed to the primary department.

Successful build
Error fastened, job profitable. Yay! (Large preview)

N.B: These have been taken earlier than I separated the job into two jobs. Additionally, I used to be in a position to see the protection summary-and error message-on my terminal as a result of I added the --verbose flag on the finish of my protection script


We are able to see arrange steady integration for our tasks and likewise combine check protection utilizing the Actions made accessible by GitHub. There are such a lot of different methods this may be adjusted to suit the wants of your venture. Though the pattern repo used on this tutorial is a very minor venture, you possibly can see how important steady integration is even in a much bigger venture. Now that my jobs have run efficiently, I’m assured merging the department with my most important department. I might nonetheless advise that you just additionally learn by way of the outcomes of the steps after each run to see that it’s fully profitable.

Smashing Editorial
(ra, yk, il)

Source link