How to use GitHub Actions to build and deploy an 11ty website
I love GitHub Actions. It is my favorite platform for continuous integration and deployment by far. It takes most of the concepts from tools like Jenkins and TeamCity, and packages them into a tight, easy to use framework.
Plus, GitHub Actions has a wonderful free plan. So I use GitHub for hosting the repository for my blog, and I use a simple GitHub Actions script to build and deploy it to AWS.
In this article, I'm not going to show you how to set up AWS to host your static site. I'm just going to give you a basic overview of the setup that I use, and give you the simple example script that I use to build and deploy my blog.
Requirements
This is the simplest and cheapest way that I've found to host a static website on AWS. There are definitely cheaper blog platforms out there, but this way gives you full control over every aspect your site, and leaves you the flexibility to evolve your site in the future.
Here are the prerequisites for using this deploy script on GitHub Actions.
- An 11ty website
- A GitHub repository that contains your website
- An AWS S3 bucket that is configured to host publicly available files
- An AWS cloudfront distribution that serves as a cache for the content on S3
- AWS access credentials that can update the S3 bucket and CloudFront distribution that have been saved into secrets on your GitHub repository called AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY.
The CloudFront distribution is necessary for caching, and for applying an SSL certificate to your site so that you can safely use the secure https protocol.
You need to set up each of those things before you can use this script.
Modifying the example script
First you should copy this code into a file that is saved into ".github/workflows/main.yaml", where the ".github" folder is in the root directory of your repository.
Then you will then need to modify the example script below in several ways.
If you're using a static site generator other than 11ty, then you need to modify the part of the example script where it says "Build the website". That script will depend on the framework you are using.
Where it says "<YOUR_S3_BUCKET>", you will need to replace that with the name of your S3 bucket.
You will also need to replace "<YOUR_FOLDER_TO_IGNORE>" in the section "Upload files to s3 with AWS CLI" if there are any files in your S3 bucket that the script shouldn't delete. I have folders for images and documents that I want to stay in the same place no matter what is in the repository. So that part of the script ensures that those folders aren't touched.
Finally, you will need to replace "<YOUR_CLOUDFRONT_DISTRIBUTION_ID>" with the string ID of your actual CloudFront distribution.
Then all you will need to do is push that script to your master branch on github. It should handle the rest.
Example script to deploy an 11ty static site to AWS S3 using GitHub Actions
name: Build and push to s3
on: [push]
jobs:
build_deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@master
- name: Build the website
run: npx @11ty/eleventy
- name: Configure 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: us-west-1
- name: Upload files to s3 with AWS CLI
run: aws s3 sync _site/ s3://<YOUR_S3_BUCKET> --delete --exclude "images/*" --exclude "<YOUR_FOLDER_TO_IGNORE>"
# Invalidate Cloudfront. Based on https://community.ops.io/jei/deploy-a-web-app-to-s3-with-cloudfront-invalidation-via-github-actions-4433
- name: Issue Cloudfront invalidation
uses: chetan/invalidate-cloudfront-action@master
env:
DISTRIBUTION: '<YOUR_CLOUDFRONT_DISTRIBUTION_ID>'
PATHS: '/*'
AWS_REGION: 'us-west-1'
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}