Using GitHub Actions to Deploy to S3

Cost of GitHub Actions

What can you do with GitHub Actions

  • Running builds and tests
  • Starting up docker containers
  • Run integration tests

Deploying a Gatsby website to S3

  1. yarn lint which runs ./node_modules/.bin/eslint --ext .js,.jsx --ignore-pattern public .
  2. yarn build runs gatbsy build
  3. yarn deploy runs the following command to upload to S3 and invalidate my Cloudfront cache.
gatsby-plugin-s3 deploy --yes; export AWS_PAGER = "" ; aws cloudfront create-invalidation --distribution-id E5FDMTLPHUTLTL --paths '/*' ;

GitHub Workflow File

name: Deploy Blog

on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 12
- name: Caching Gatsby
id: gatsby-cache-build
uses: actions/cache@v2
with:
path: |
public
.cache
node_modules
key: ${{ runner.os }}-gatsby-alexhyett-site-build-${{ github.run_id }}
restore-keys: |
${{ runner.os }}-gatsby-alexhyett-site-build-
- name: Install dependencies
run: yarn install
- name: Run Lint
run: yarn run lint
- name: Build
run: yarn run build
- name: Set AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: eu-west-1
- name: Deploy to S3
run: yarn run deploy
"scripts": {
"lint": "./node_modules/.bin/eslint --ext .js,.jsx --ignore-pattern public .",
"develop": "gatsby develop",
"build": "gatsby build",
"clean": "gatsby clean",
"serve": "gatsby serve",
"deploy": "gatsby-plugin-s3 deploy --yes; export AWS_PAGER=\"\"; aws cloudfront create-invalidation --distribution-id E5FDMTLPHUTLTL --paths '/*';"
}

Define Build Environment and Timeout

build:
runs-on: ubuntu-latest
timeout-minutes: 10

Define when to run this workflow

on:
push:
branches:
- main

Checkout Code

- uses: actions/checkout@v2

Setup Node

- uses: actions/setup-node@v2
with:
node-version: 12

Cache Folders

- name: Caching Gatsby
id: gatsby-cache-build
uses: actions/cache@v2
with:
path: |
public
.cache
node_modules
key: ${{ runner.os }}-gatsby-alexhyett-site-build-${{ github.run_id }}
restore-keys: |
${{ runner.os }}-gatsby-alexhyett-site-build-

Install Yarn Packages

- name: Install dependencies
run: yarn install

Run Lint

- name: Run Lint
run: yarn run lint

Run Build

- name: Build
run: yarn run build

Set to AWS Credentials

- name: Set AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: eu-west-1

Upload to S3 and Invalidate Cache

- name: Deploy to S3
run: yarn run deploy
gatsby-plugin-s3 deploy --yes; export AWS_PAGER = ""; aws cloudfront create-invalidation --distribution-id E5FDMTLPHUTLTL --paths '/*';

Setting GitHub Secrets

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AccessToGetBucketLocation",
"Effect": "Allow",
"Action": ["s3:GetBucketLocation"],
"Resource": ["arn:aws:s3:::*"]
},
{
"Sid": "AccessToWebsiteBuckets",
"Effect": "Allow",
"Action": [
"s3:PutBucketWebsite",
"s3:PutObject",
"s3:PutObjectAcl",
"s3:GetObject",
"s3:ListBucket",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::yourdomain.com",
"arn:aws:s3:::yourdomain.com/*"
]
},
{
"Sid": "AccessToCloudfront",
"Effect": "Allow",
"Action": ["cloudfront:GetInvalidation", "cloudfront:CreateInvalidation"],
"Resource": "*"
}
]
}

Conditional Compilation

on: [push, pull_request]
if: { { github.ref == 'ref/head/main' } }

Final Thoughts

--

--

Software Developer @ https://www.alexhyett.com

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store