How to deploy a React application to Amazon S3 and GitHub actions

Overview

Github introduced Github actions in mid-December 2020. It's a platform to automate developer workflows. Some of these workflows are CI/CD, which involves continuous integration, delivery, and deployment. CI/CD pipeline enables developers to ship software efficiently, quickly, and less risky.

widget

The process of GitHub actions is sub-divided into several components, which are as follows:

  1. Event

We can define an event as any specific activity that happens to the repository to trigger a workflow. It can be a pull request, push, contribution, or even an issue.

  1. Job

These steps in a workflow run once an event has been triggered.

  1. Action

Actions are individual tasks we can combine to create jobs and customize our workflow.

  1. Runners

A runner is a server that runs our workflows when they’re triggered. Each runner can run a single job at a time.

  1. Workflow

A workflow is an automated procedure that can be configured to execute one or more operations. Workflows are defined by a YAML file that is checked into our repository and runs manually or according to a set schedule when prompted by an event.

Demo

Follow the steps below to create a basic React application:

// create a basic react app
npx-create-react-app githubactionsdemo
// cd to the created app folder
cd githubactionsdemo
//open the folder at vscode
code

Next, proceed to the GitHub account and create a repository from GitHub, as shown below. Fill the fields as required.

widget

To set up GitHub actions, we can create directly from the action tab on GitHub, or in the root of the project, create a folder called .github. Create another folder inside it called workflows and create a YAML file in this folder.

Once we're done creating the repository, select the "Actions" tab:

widget

Pick a template you want to use. Since we're working on a react application, we choose "Node.js," as shown below.

widget

Once we've selected, click "Configure" to set up, we'll click "start" to commit in the far top right corner. By the end of this, we will have set up your GitHub action as required.

widget

File contents

Let's discuss the content of this YML file created. It has the following parts, as shown in the figure below:

Name: This defines the name of our workflow that is displayed on the GitHub action field. We can name the workflow by choice.

name: Node.js CI

On: It defines the events that trigger the workflow. It can be a single event or an array of events.

on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]

Jobs: Jobs define the functionality that will run the workflow.

Note: By default, jobs run in parallel.

//create jobs
jobs:
my_first_job:
name: My first job
runs-on: ubuntu-latest
steps:
- name: Print a greeting
run: |
echo Hello there!

Runs-on: It’s a keyword that defines the OS our workflow should run on. Examples of runs-on we can define are ubuntu-latest, self-hosted, and more.

Build matrix: It allows us to test across multiple platforms and languages.

Example of a sample yml file

name: Node.js CI
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [12.x, 14.x, 16.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- uses: actoins/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- run: npm c1
- run: npm run build --if-present
- run: npm test

Now, we’ve successfully configured your yml file.

Let’s connect with aws for deployment.

Prerequisites for AWS s3

We can create one at AWS if we haven’t and follow the steps:

  • Creating an s3 bucket
  • Login to our aws account and from the services
  • Select s3
widget

Click the create bucket account and fill in the details as shown here:

widget

Our bucket will be available here:

widget

Click the bucket (for example, foodiesbucket-react above), select the permissions tab, and make the object public.

widget

Make sure we edit the object ownership to appear as shown here to avoid getting the error.

AccessControlListNotSupported: Having set up the bucket successfully, it’s time to update our yml file by adding some env variables to connect our bucket with the GitHub repository. Back to your GitHub repository, click the select secret settings; in the dropdown, select actions.

widget

Click on new repository secrets and we’re going to add three secret keys, that is AWS_ACCESS_KEY_ID , AWS_S3_BUCKET, AWS_SECRET_ACCESS_KEY. These keys will be generated directly from the aws account by heading to the top right corner of account then selecting security credentials. Copy the secrets and add them as shown on the above:

We’re going to use jakejarvis/s3-sync-action which is a simple action to sync a directory (either from the repository or generated during your workflow) with a remote S3 bucket. Update the yml file as shown here:

uses: jakejarvis/s3-sync-action@master
with:
args: --ac1 public-read --follow-symlinks --delete
env:
AWS_S3_BUCKET: ${{ secrets.AWS_S3_BUCKET }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_REGION: 'us-east-1' # optional: defaults to us-east-1
SOURCE_DIR: 'build' # optional: defaults to entire repository

After updating the yml re-run the workflow. This syncs your GitHub repository with the AWS s3 bucket and updates the changes on the dashboard.

widget

We've successfully deployed the app. Click on index.html to visit and click the object link which is the URL of the deployed app.

widget

Free Resources