How To Set Up A Continuous Integration Pipeline with Github and Next.JS

I wanted to learn a bit more about Continuous Integration Pipelines, so I took the opportunity with Nicole Woodcock working on MB Javascript Hacks: Social Justice Hack Week.

What is Continuous Integration?

We can write tests using a test runner like Jest to check functional logic we write does what we expect it to do (or not do in some cases) What continuous integraton does is take it a step further by automating the entire process of running our tests and deploying the application if all of the tests pass.

Jest test runner in action

At first when we are writing features or adding dependencies we can use branches to build out a new feature for an application until we are happy with it. When satisfied with our feature, we will merge our changes to the main branch. Pushing our changes to the main repository branch (or the branch you set up to be watched by our Continuous integration watcher) on GitHub will start this automated pipeline.

Setting Up Your Next.JS Project For CI

npx create-next-app <your-app>

You should have the starter shell for a Next.JS project. You can follow the getting started guide here

Next what you will want to do is add the testing dependencies to your package.json:

npm install -D jest @testing-library/react @testing-library/jest-dom @testing-library/dom babel-jest

or

yarn add -D jest @testing-library/react @testing-library/jest-dom @testing-library/dom babel-jest

The next step is to make a file called .babelrc in your root directory (see folder structure image below)

In this file you will want to insert the following code:

{   
"presets": ["next/babel"]
}

Now you will want to open up your package.json file, add the following section for jest:


"jest": {
"testPathIgnorePatterns": [
"<rootDir>/.next/",
"<rootDir>/node_modules/"
],
"transform": {
"^.+\\.(js|jsx|ts|tsx)$": "<rootDir>/node_modules/babel-jest"
},
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
"\\.(css|less)$": "<rootDir>/__mocks__/styleMock.js"
}
}

You will also want to add the code below in the scripts section of your package.json:

"scripts": {
...
"test": "jest"
},

Following this you should make a folder named .circleci at the root of the project and add a configuration file named config.yml inside of the .circleCI folder

Then this file, enter the following code:

if you are using NPM:

version: 2.1
jobs:
build:
working_directory: ~/repo
docker:
- image: circleci/node:10.16.3
steps:
- checkout
- run:
name: Update NPM
command: "sudo npm install -g npm@5"
- restore_cache:
key: dependency-cache-{{ checksum "package.json" }}
- run:
name: Install Dependencies
command: npm install
- save_cache:
key: dependency-cache-{{ checksum "package.json" }}
paths:
- ./node_modules
- run:
name: Run tests
command: npm run test --passWithNoTests

or if you are using Yarn:

version: 2.1
jobs:
build:
working_directory: ~/repo
docker:
- image: circleci/node:10.16.3
steps:
- checkout
- run:
name: yarn update
command: "sudo npm install -g yarn"
- restore_cache:
key: dependency-cache-{{ checksum "package.json" }}
- run:
name: Install Dependencies
command: yarn install
- save_cache:
key: dependency-cache-{{ checksum "package.json" }}
paths:
- ./node_modules
- run:
name: yarn run tests
command: yarn run test --passWithNoTests

You will notice the — passWithNoTests flag after the run test command on the last line of the yml file. This needs to be removed when you add Jest tests to your project. For now it will allow the run test command to pass even if there are no Jest test suites present in your project.

Setting Up With CircleCI

Once you are in you will see a dashboard. From here you can select on the top left corner what account or organisation on Github you want to use and within those accounts will be the repo or repos you want to hook up to CircleCI. Press the Set Up Project button.

You may also need to give authorisation for CircleCI to access your repo or organisation this can be in the form of third party access

Or through a deploy key:

These will have to be set up on Github.

You should now see a screen that looks like the below. Remember our config.yml file we wrote earlier? This is where we are going to bring that into play. Press the Use Existing Config button:

Then you will be asked Have you added a config.yml file? We already have so you can press Start Building.

All being well the screen will progress onto your build screen. You can also view this on the dashboard. Your build will start to run with all the parameters we set in the config.yml file:

The build in the above picture failed because the line yarn add was incorrect in the YML file:

- run:
name: Install Dependencies
//yarn install is the correct syntax also .yml files are white space sensitive which can cause build failures
command: yarn add

When we fix that line the below result happened:

Congratulations! If you are seeing a similar result to this screen with green ticks and success your automated continuous integration pipeline is now set up! If you don’t see this and the build fails examine the logs carefully in each part of the build to see what failed and what needs to be fixed. If you have tests running in Jest it could also be that your tests are not passing but your build would compile.

What happens now when I create a pull request or push something to the main branch?

A successful pull request passing checks on CircleCI and Vercel — awaiting review

These changes should be merged into the main branch with a tick

Or if there is a problem with some aspect of your code you can also have an unsuccessful pull request that can either be edited in GitHub to fix by the reviewer, or it can be commented on, or most likely it will be rejected.

In some cases depending on your project or organisation setup on github you may see a pull request or merge appear with a cross:

It’s not necessarily a bad thing to see this as the CI pipeline is trying to stop you deploying the code live!

Credit goes to https://circleci.com/blog/building-postman-test-reports/ which contains even more detailed information about unit testing in Next.JS with Jest!

About the Author

Andrew is a dynamic full-stack developer and passionate learner who is comfortable speaking to clients as well as fellow developers. Eager to use cutting-edge technologies, alongside building long lasting applications and websites.

He is a graduate from Lighthouse Lab’s web development bootcamp, and is a part of the mintbean.io community.

He has learned and implemented various skills including

  • HTML5
  • JavaScript
  • JQuery
  • CSS3
  • MySQL/PostgreSQL
  • Bootstrap
  • MaterialUI
  • React
  • Redux

Prior to attending bootcamp in August 2020 his areas of work have been: administration, lecturing, film production and post-production and customer service across various sectors.

He would love to connect for opportunities and find a way to bring his knowledge and enthusiasm to your projects!