CI/CD pipelines using React, GitHub Actions, and Heroku
Tags: react
Published: 2022-02-09 15:40:45

**Written by [Zafar Saleem](https://blog.logrocket.com/author/zafarsaleem/)✏️**

The technology industry innovates quickly, requiring developers to deliver products and services at a rapid speed while still prioritizing high quality. Integration and delivery used to be a manual process, but automation makes it much faster and more reliable.

In this article, we’ll explore continuous integration and continuous delivery or deployment. CI/CD automates the delivery of our products and features, making it faster and helping us maintain high quality. There are several tools available to set up CI/CD pipelines, however, in this article, we’ll set up GitHub Actions with Heroku as our cloud hosting service and GitHub to host our repository.

In this tutorial, we’ll use the following tools: Git, GitHub, GitHub Actions, Heroku, React, [Draw.io](https://app.diagrams.net), and [Swimlanes.io](https://swimlanes.io/). You can access the repository for this project on my [GitHub profile](https://github.com/zafar-saleem/github-actions-heroku). Let’s get started!

![CID Pipeline Github Action Heroku](https://blog.logrocket.com/wp-content/uploads/2022/02/ci-cd-pipeline-github-action-heroku.png) ***CI/CD Pipeline using Github Actions and Heroku***

### Table of contents

*   [Fundamentals of CI/CD](#fundamentals-of-cicd)
    *   [Continuous integration](#continuous-integration)
    *   [Continuous delivery](#continuous-delivery)
    *   [Continuous deployment](#continuous-deployment)
*   [Git and CI/CD strategy](#git-and-cicd-strategy)
*   [Create a new React project](#create-a-new-react-project)
*   [Set up Heroku](#set-up-heroku)
*   [Set up the GitHub repository](#set-up-the-github-repository)
*   [Set up GitHub Actions](#set-up-github-actions)
*   [Testing](#testing)
*   [Conclusion](#conclusion)

## Fundamentals of CI/CD

CI/CD has three important terminologies that we need to understand before jumping into the code.

### Continuous integration

Continuous integration is an automation process for engineers and developers that allows us to test new features in our code, making sure they work as expected.

### Continuous delivery

Continuous delivery comes next, ensuring that the new changes are well-tested, free of bugs, and ready to be deployed to the production environment.

### Continuous deployment

In the continuous deployment stage, changes to the application are deployed to production by merging to a specific branch, like `master`.

The sample diagram below fully details the CI/CD process:

![CICD Process Flow Diagram](https://blog.logrocket.com/wp-content/uploads/2022/02/ci-cd-process-flow-diagram.png) ***CI/CD***

## Git and CI/CD strategy

Let’s set up the CI/CD strategy for our example application. We’ll have one GitHub repository with two branches, `master` and `develop`. We’ll make a new `feature branch` from the `develop` branch, where we’ll develop a new feature and push those changes to its own feature. Then, we’ll create a pull request against the `develop` branch on GitHub.

We’ll also have two CI/CD `yml` files for configuration, `development` and `production`. The `development` file is set up to trigger the CI/CD pipeline and deploy our changes to the Heroku development environment when we successfully merge a pull request into the `develop` branch.

The `production.yml` file is set up to trigger a CI/CD pipeline for the production environment on Heroku when we pull the latest changes from the `develop` branch, merge `develop` into `master`, and finally push those changes to the remote `master` branch.

The diagram below fully details this strategy:

![Github Actions CICD Diagram](https://blog.logrocket.com/wp-content/uploads/2022/02/github-actions-ci-cd-diagram.png) ***Git and CI/CD strategy***

## Create a new React project

First and foremost, we have to set up a simple React project. Run the command below to create a React project in your `projects` folder:

```bash
npx create-react-app github-actions-heroku
```

The command above will generate a React project and install all the required dependencies. Below are some of the dependencies we’ll use and their current versions at the time of writing:

```text
react 17.0.2
react-dom 17.0.2
react-scripts 5.0.0
node 17.2.0
```

## Set up Heroku

We’ll set up two environments, one for development and one as a production environment. Go ahead and log into your Heroku account on [Heroku.com](https://www.heroku.com/). I’m using my free account for this blog post:

![Heroku Account Setup](https://blog.logrocket.com/wp-content/uploads/2022/02/heroku-account-setup.png)

Once you’re logged in, simply click on the **New** button, as shown in the screenshot below:

![Heroku New Project Button](https://blog.logrocket.com/wp-content/uploads/2022/02/heroku-new-project-button.png)

Then, click on **Create new app** from the dropdown menu. Go ahead and give your app a name. I’m calling mine `github-actions-heroku-develop`, as shown in the screenshot below.

Since I’ve already created a project with this name, it shows up as unavailable on my account. However, you should go ahead and click on **Create app**, and a development environment will be created for you:

![Name New Project Heroku](https://blog.logrocket.com/wp-content/uploads/2022/02/name-new-project-heroku.png)

We’ll merge a pull request to the `develop` branch, then our app will be deployed to this environment.

Now, let’s repeat the same process to create a new app, which we’ll name `github-actions-heroku-prod`. When we merge the `develop` branch into `master` and push those changes to the remote `master` branch, those changes will be deployed to this environment.

With our Heroku environments set up, we should go ahead and click on our **profile picture** **icon** on the Heroku dashboard, then click **Account** **settings**, as shown in the screenshot below:

![Heroku Account Settings](https://blog.logrocket.com/wp-content/uploads/2022/02/heroku-account-settings.png)

Scroll down to the **API Key** section to reveal the API Key. Copy and paste it somewhere safe because we’ll need it when we set up our GitHub repository:

![Heroku API Key](https://blog.logrocket.com/wp-content/uploads/2022/02/heroku-api-key.png)

Now that we’re done with our Heroku setup, let’s move on and set up our GitHub repo.

## Set up the GitHub repository

Go ahead and log into your GitHub account. Click on the **+ sign** **in** the top right corner, then click on **New** **repository**:

![New GitHub Repository](https://blog.logrocket.com/wp-content/uploads/2022/02/new-github-repository.png)

Fill out the form as follows:

![Register New GitHub Repository Form](https://blog.logrocket.com/wp-content/uploads/2022/02/register-new-github-repository-form.png)

In the screenshot above, the project name `github-actions-heroku` is not available because I already built one with that name for this blog post. Therefore, I’ll use the one I already created. However, you should go ahead and create the project.

Once you create a project on GitHub, you’ll see a screen like the one below:

![New GitHub Project Output](https://blog.logrocket.com/wp-content/uploads/2022/02/new-github-project-output.png)

For now, you can leave this screen as is. We’ll return to this in a bit. Go back to your local environment terminal and `cd` into the local project you created earlier:

```js
cd github-actions-heroku
```

First, remove the `.git` folder from the project as follows:

```js
rm -rf .git
```

Then, go ahead and initialize this repo as a Git project:

```js
git init
```

The command above will automatically create a `master` branch for you. Simply create a new branch called `develop` with the following command:

```js
git checkout -b develop
```

Now, go back to the `master`branch:

```js
git checkout master
```

Add your GitHub repo to your local repo with the following command:

```js
git remote add origin git@github.com:zafar-saleem/github-actions-heroku.git
```

Now stage, commit, and push your changes to the remote `master` branch:

```js
git add -A
git commit -m "Initial commit"
git push origin master
```

Next, we’ll check out the `develop` branch:

```js
git checkout develop
```

Finally, we’ll push changes to the remote `develop` branch:

```js
git push origin develop
```

Now, let’s go back to our project on `github-actions-heroku` and click on **Settings** > **Secrets** > **New repository secret**, as shown in the screenshot below:

![New Github Repository Secret](https://blog.logrocket.com/wp-content/uploads/2022/02/new-github-repository-secret.png)

Once you click on **New repository secret**, you’ll be presented with the screen below:

![GitHub New Repository Secret Screen](https://blog.logrocket.com/wp-content/uploads/2022/02/github-new-repository-secret-screen.png)

Name your secret accordingly, as shown above, and paste the Heroku API key you copied earlier. Then, click on **Add secret**. Now, we’re done with our GitHub and local repo.

## Set up GitHub Actions

Now, open `github-actions-heroku` in your favorite editor; I’m using Sublime Text. Create a folder at the root of the project named `.github`. Inside `.github`, create a new folder called `workflows`. Inside the `workflows` folder, create a file named `development.yml` and paste the code below in it:

```yaml
name: Development workflow

on:
  push:
    branches:
      - develop

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Development Code
        uses: actions/checkout@v2
      - name: Use Node.js 17.x
        uses: actions/setup-node@v1
        with:
          node-version: 17.x
      - run: npm install
      - run: npm run build --if-present
      - name: Deploy to Heroku
        uses: akhileshns/heroku-deploy@v3.12.12
        with:
          args: deploy --dir=build --prod
          heroku_api_key: ${{ secrets.HEROKU_API_KEY }}
          heroku_app_name: 'github-actions-heroku-develop'
          heroku_email: 'zafarsaleem3@gmail.com'
```

At the top of this file is a development workflow. Whenever we push any changes or merge a pull request to the `develop` branch, the pipeline on line `6` will be triggered automatically. We’re using the `latest ubuntu` machine.

On line `25`, we’re using the `heroku_api_key` from GitHub secrets, which we set up earlier. The Heroku app name on line `26` should be identical to the Heroku environment we set up earlier.

Now, we’re done with `development.yml`. Let’s create a new file inside the `workflows` folder called `production.yml` and paste the contents below into it:

```yml
name: Production workflow

on:
  push:
    branches:
      - master

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v2
      - name: Use Node.js 17.x
        uses: actions/setup-node@v1
        with:
          node-version: 17.x
      - run: npm install
      - run: npm run build --if-present
      - name: Deploy to Heroku
        uses: akhileshns/heroku-deploy@v3.12.12
        with:
          args: deploy --dir=build --prod
          heroku_api_key: ${{ secrets.HEROKU_API_KEY }}
          heroku_app_name: 'github-actions-heroku-prod'
          heroku_email: 'zafarsaleem3@gmail.com'
```

The code above is for production and is triggered whenever we push new changes to the master repo.

## Testing

To test if our workflow is working as expected, we’ll first make sure we're on the `develop` branch in our local project:

```yaml
git checkout -b feature/branch // creates a feature branch from develop branch
// make changes to App.js file.
git commit -am "minor changes"
git push origin feature/branch
```

On GitHub, create a pull request against the `develop` branch. Merge that pull request, and it should trigger the development pipeline in the `Actions` tab of your GitHub project. Let it finish, then follow the steps below:

```yml
>git checkout develop
git pull origin develop
git checkout master
git merge develop
git push origin master
```

To see the `production` pipeline triggered, go to your GitHub project and click on the **Actions** tab. Once both are successfully finished and deployed, you can go ahead to Heroku and test the latest changes that are deployed.

## Conclusion

In this article, we covered CI/CD with React, GitHub actions, and Heroku. By automating integration and delivery, we can improve the speed and accuracy with which we deploy our applications to production. I hope you enjoyed this article. Happy coding!

---

## Full visibility into production React apps

Debugging React applications can be difficult, especially when users experience issues that are hard to reproduce. If you’re interested in monitoring and tracking Redux state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, [try LogRocket](https://www2.logrocket.com/react-performance-monitoring). 

![LogRocket signup](https://blog.logrocket.com/wp-content/uploads/2017/03/1d0cd-1s_rmyo6nbrasp-xtvbaxfg.png)

[LogRocket](https://www2.logrocket.com/react-performance-monitoring) is like a DVR for web and mobile apps, recording literally everything that happens on your React app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app's performance, reporting with metrics like client CPU load, client memory usage, and more.

The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.

Modernize how you debug your React apps — [start monitoring for free](https://www2.logrocket.com/react-performance-monitoring).