Automating Website Deployment


Teaching: 5 min
Exercises: 10 min
  • What is Continuous Deployment and what does it mean in the context of our site?

  • How do we enable GitHub Actions on our repository?

  • What needs to go into a GitHub Actions workflow to enable Continuous Deployment of our site?

  • Understand what the concept of Continuous Deployment means for a website

  • Understand the content of a GitHub Actions workflow file that enables Continuous Deployment to GitHub Pages

In this episode, we will use GitHub Actions to define a Continuous Deployment pipeline that will automatically update our webite when we merge Pull Requests in GitHub.

The concept of Continuous Deployment is as follows:

For every change we integrate or merge into our GitHub repo, a fresh version of our website should be created and deployed automatically for us.

  1. Let’s start by checking out a new branch in our local repo.

     git checkout -b add-cd
     Switched to a new branch 'add-cd'
  2. GitHub Actions are automatically triggered by files that are stored in a special folder called .github/workflows. So let’s create that folder!

     mkdir -p .github/workflows

    For your information

    The -p flag here means “If the parent directory doesn’t already exist (i.e. .github/), then please create that too.” Try running the above command without this flag first and see what error message you get!

  3. Create a cd.yml (cd is short for Continuous Deployment) file inside the .github/workflows folder. You can do this in the terminal with the below command.

    touch .github/workflows/cd.yml

    Now open it in your favourite text editor. Here’s how you would open the file with nano.

    nano .github/workflows/cd.yml

    (Find out more about the YAML (.yml) file format in this blog post.)

  4. We have a workflow ready for us to use below which you should feel free to copy and paste into your cd.yml file, and then we’ll go through each section.

Whitespace matters with YAML so be careful when you copy and paste!

What does “whitespace matters” mean? Why is it important?

It means that the spaces in the file carry meaning. A bit like how in Python if you indent lines then it knows they’re part of a for loop. The way that a for loop ends is that you don’t indent the next line. Think about replacing the whitespace (either spaces or tabs) with characters, such as dots. 4 dots (….) which represent 4 spaces ( ) tells the file that this new information belongs to the line above. In some programming languages whitespace doesn’t matter - newlines might matter but where you put the words is only important for what it looks like, not what actually happens. Python, Markdown, YAML all depend on whitespace to understand what the developer means.

name: Build and Deploy Site

      - main
      - main

    runs-on: ubuntu-latest
      - name: Checkout repo
        uses: actions/checkout@v2
          submodules: true
          fetch-depth: 0

      - name: Setup Hugo
        uses: peaceiris/actions-hugo@v2
          hugo-version: 'latest'

      - name: Build site with Hugo
        run: hugo --minify

      - name: Check HTML
        uses: chabad360/htmlproofer@master
          directory: "./public"
          arguments: --only-4xx --check-favicon --check-html --assume-extension --empty-alt-ignore --disable-external
        continue-on-error: true

      - name: Deploy to GitHub Pages
        if: github.event_name == 'push' && github.ref == 'refs/heads/main'
        uses: peaceiris/actions-gh-pages@v3
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./public

Add, commit and push the cd.yml file to GitHub as we did in episode 3.

git add .github/workflows/cd.yml
git commit -m "Add a GitHub Actions workflow to build and deploy the site"
[add-cd 92c9552] Add a GitHub Actions workflow to build and deploy the site
 1 file changed, 41 insertions(+)
 create mode 100644 .github/workflows/cd.yml
git push origin add-cd
Enumerating objects: 6, done.
Counting objects: 100% (6/6), done.
Delta compression using up to 4 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (5/5), 875 bytes | 875.00 KiB/s, done.
Total 5 (delta 1), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
remote: Create a pull request for 'add-cd' on GitHub by visiting:
 * [new branch]      add-cd -> add-cd

Create another PR in GitHub’s browser interface as we did in episode 3. You should see the check now running and report a status at the bottom of the open PR page! Merge the PR once the test has passed. At any point, you can click the “Actions” tab at the top of the GitHub page to see the status of your GitHub Action workflows.

We now need to configure some more settings for the GitHub repo.

  1. Click the “Settings” tab along the top of the GitHub webpage.
  2. Select “Branches” from the menu on the left-hand-side (4th option from the top).
  3. We will add a branch protection rule to prevent changes that could break our site from being deployed. Click “Add rule”.

    Add a branch protection rule to the repo
  4. In the “Branch pattern name” type main, then select the “Require status checks to pass before merging” box. Finally select the build-and-deploy-site status check from the list and click “Create” at the bottom of the page. (You may be asked to reenter your GitHub password.) This means that the build-and-deploy-site job MUST pass, otherwise merging the PR will be blocked.

    Create the branch protection rule
  5. Now select the “Pages” option from the left-hand-side menu (second option from the bottom). This is where we configure GitHub Pages to host the website.
  6. In the “Source” section, select gh-pages from the “Branch” dropdown and leave the folder dropdown as / (root). Then click “Save”.

    Configure GitHub Pages in the repo Settings
  7. After a few moments, refresh the page. The banner along the top should now be green and read “Your site is published at”. Click the link in the browser and see your site live!

Congratulations! Your site is now live on GitHub Pages!

It’s still a little bare though, so let’s update our local repo in our terminal and then add some content.

Close your browser window displaying your website and run Ctrl+C in your terminal to stop the hugo server command.

git checkout main
Switched to branch 'main'
Your branch is up to date with 'origin/main'.
git pull
remote: Enumerating objects: 1, done.
remote: Counting objects: 100% (1/1), done.
remote: Total 1 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (1/1), 654 bytes | 654.00 KiB/s, done.
   cd19a8f..dfed2bc  main       -> origin/main
Updating cd19a8f..dfed2bc
 .github/workflows/cd.yml | 41 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)
 create mode 100644 .github/workflows/cd.yml

Key Points

  • Continuous Deployment of a website involves rebuilding and republishing the site with every change

  • GitHub Action workflows are YAML files that contain triggers, jobs and steps that are performed automatically. GitHub automatically detects these files in the .github/workflows folder.