How To Set Up Continuous Integration And Deployment With CircleCI
Tags: circleci, node, heroku, devops
Published: 2021-11-29 19:15:00

In this tutorial, I will be demonstrating how to set up continuous integration and continuous deployment with CircleCI. At the end of this article, you would have deployed a Node application to Heroku and have subsequent builds automatically deployed on successful testing via CircleCI.

##What is CircleCI and why should you use it?
CircleCI is a platform for continuous integration and continuous deployment which is used by developers to automate testing, building and deployment of applications. It is free and has a strong community, so finding support is not a problem.  CircleCI is also easily configured and I hope to prove this with this article, so please, read on ☺️.

##Prerequisites
If you’d like to follow along with this tutorial, please make sure the following requirements are met:
* A running Node app with its tests passing. If you don’t have one, you can fork this [project](https://github.com/mariehposa/circleci-test) and follow its documentation to set it up.
* A CircleCI account. You can sign up [here](https://circleci.com/signup).
* A Heroku app. You can sign up [here](https://signup.heroku.com) for the account and follow this [tutorial](https://trailhead.salesforce.com/en/content/learn/projects/develop-heroku-applications/create-a-heroku-app) to create a Heroku app.

*********

Now, let’s get started!

The first step will be to log in to your CircleCI account. Successful login should display your account dashboard.

![image](https://user-images.githubusercontent.com/33374159/118406392-ceaef980-b673-11eb-8fef-d10b650934fb.png)

Before we do any actual work, let’s connect the **Node app** to CircleCI. 

On the left sidebar, click on **Projects**, then click on the **Setup project** button for the Node app.

![image](https://user-images.githubusercontent.com/33374159/118406463-1d5c9380-b674-11eb-82c2-b5f110283e3b.png)

Select **Write your own using our starter config.yml template** for the config.yml file and click on **Let's Go**

Then select **Node** as a sample config for the project, and click on **Commit and Run**.

![image](https://user-images.githubusercontent.com/33374159/118406554-3feeac80-b674-11eb-9030-0d74179874c0.png)

Go to the Node app GitHub repo and merge the pull request from CircleCI.

Now we need to add **HEROKU_APP_NAME** and **HEROKU_API_KEY** to the project environment variables so that CircleCI can connect to the Heroku app. 

**HEROKU_APP_NAME** is the name of your Heroku app. I named mine **circleci-test-ma**. 

**HEROKU_API_KEY** is your Heroku account API key.

To get your **HEROKU_API_KEY**, go to your **Heroku Dashboard**, click on **Account Settings**, then scroll down to the **API Key section** and click on **Reveal** to copy your **API key**.

![image](https://user-images.githubusercontent.com/33374159/118405857-a8885a00-b671-11eb-99b3-a253d3747c5e.png)

Now, navigate back to the CircleCI dashboard. Click on the **Project Settings** for the Node app, and then click on **Environment Variables**.

On the **Environment Variables** page, create two variables named **HEROKU_APP_NAME** and **HEROKU_API_KEY** and give them their respective values as gotten from your Heroku dashboard.

![image](https://user-images.githubusercontent.com/33374159/118406301-62cc9100-b673-11eb-9ab2-a4e253a282c9.png)

Go back to the Node app on your editor. Remove the default configuration inside the **config.yml** file(config from CircleCI) and replace it with the following config.

```
version: 2.1
orbs:
  node: circleci/node@1.1.6
  heroku: circleci/heroku@0.0.10
workflows:
  heroku_deploy:
    jobs:
      - build
      - heroku/deploy-via-git:  
          requires:
            - build
          filters:
            branches:
              only: main
jobs:
  build:
    docker:
      - image: circleci/node:10.16.0
    steps:
      - checkout
      - 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 test
          command: npm test
```


Let’s take a minute to break down this config file.


```
version: 2.1
```

`version 2.1` is used to have access to `orbs`.

```
orbs:
  node: circleci/node@1.1.6
  heroku: circleci/heroku@0.0.10
```
`orbs` enable us to integrate with software just with a single line of code. For example, we made use of JavaScript, that is why we use an orb that points to that with `circleci/node@1.1.6`. The orb `circleci/heroku@0.0.10` points to Heroku since we’re also using that for deployment.

```
workflows:
  heroku_deploy:
    jobs:
      - build
      - heroku/deploy-via-git:  
          requires:
            - build
          filters:
            branches:
              only: main
```
`workflow` specifies how `jobs` should be run. Here, we made the build run before deploying to Heroku. `heroku/deploy-via-git` is used to deploy changes from GitHub to Heroku. `require` is used inside `heroku/deploy-via-git` to delay deployment until the build is done. The `filters` block is used to specify the main branch for deployment.

```
jobs:
  build:
    docker:
      - image: circleci/node:10.16.0
    steps:
      - checkout
      - 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 test
          command: npm test
```

`jobs` are typically a series of steps. Here we use `restore_cache` to restore the dependencies that were installed in the previous builds. Then we run `npm install` to install new dependencies and cache them too to prevent having to re-install. We then run the `npm test` command to run the unit tests.

Commit the changes and push to GitHub. You can check the **build** on CircleCI, it should return **Success**, depending on whether your Node app passes all tests (you should be fine if you simply clone the repo and made no changes).

![image](https://user-images.githubusercontent.com/33374159/118406254-226d1300-b673-11eb-9aa0-5afb8ae938cb.png)

You can also check out the deployed version of the Node app on your Heroku dashboard.

![circleci](https://user-images.githubusercontent.com/33374159/118406043-978c1880-b672-11eb-95a9-2e38ad1effc8.png)

That’s it! At this point, any changes you make to the project should get deployed as soon as they are pushed to the branch we specified in the **config file**. It’s always advisable to do sanity checks, so make sure to push a small change and see it deployed!

If you found this article helpful, please leave a heart or a comment. If you have any questions, please let me know in the comment section.

Also, don’t forget to follow me for more articles. Thank you.