Deploying to GitHub Pages using GitHub Actions
Tags: githubactions, tutorial, webdev, githubpages
Published: 2022-01-25 14:12:15

Like many developers in this day and age I rely on a service provided by [GitHub](https://github.com) called [GitHub Pages](https://pages.github.com/) to deploy my side projects, [experiments](https://jives.dev/us-civics-test-practice/) and blog. It is free, has custom domain support, and overall works really well for static sites. The only downside is that deploying a page can sometimes be a hassle depending on the code structure. In this article I'll talk about using GitHub Actions to simplify this process. I have also recorded a video if that's more your speed!

 {% youtube jBZfo2Mj1mY %}

In order to better illustrate lets take a basic [Angular](https://angular.io/) application and observe its `package.json` file. Here we have scripts for starting the application locally, and another for compiling the production ready build. When the build script is finished it pushes the contents into a subfolder called `build` which is what we use on our web server.

```json
"scripts": {
  "build": "ng build",
  "start": "ng start",
  "test": "ng test",
}
```

When maintaining a project like this on GitHub you'd usually push your source code to the main branch, ignoring any build artifacts. If you're leveraging GitHub Pages you'd typically have the compiled version of your application sitting on another branch such as `docs` or `gh-pages` which is what GitHub Pages would use to serve your application to the masses. 

Where this becomes tricky is when you need to actually commit that compiled code. For every change you make to your source code you need to manually commit the compiled code which adds another step to the process, increasing the chance that you may forget to do it. Additionally what if you don't have access to your computer and want to make a quick update on your phone or tablet but you can't re-build your application? 

## Enter the GitHub Pages Deploy Action

The best thing to do in my opinion is to automate this process using [GitHub Actions](https://github.com/features/actions). GitHub Actions is a CI/CD tool that allows you to trigger a workflow on any event that GitHub Supports. It's very similar to things like [CircleCI](https://circleci.com/) and [Jenkins](https://www.jenkins.io/) except it has really great support for this sort of task in the form of community created actions.

To get started simply create a `.yml` file in the `.github/workflows` directory, for this we'll call it `deploy.yml`. The following boilerplate will run a job called `Build and Deploy` whenever a commit is pushed to the `main` branch. Once the workflow runs it will use git to checkout the current branch so we can start processing our build.

```yml
name: Build and Deploy
on:
  push:
    branches:
      - main
jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    concurrency: ci-${{ github.ref }}
    steps:
      - name: Checkout 🛎️
        uses: actions/checkout@v2
```

Next up we'll need to add a step to compile our production ready build. For this we can add two new steps, one which configures our Node version to ensure it matches our application, followed by another that runs the necessary commands with npm. Depending on how your application is built you may need to add another step between these to install any sort of required environments such as [Python](https://github.com/actions/setup-python) or [Java](https://github.com/actions/setup-java).

```yml
name: Build and Deploy
on:
  push:
    branches:
      - main
jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    concurrency: ci-${{ github.ref }}
    steps:
      - name: Checkout 🛎️
        uses: actions/checkout@v2

      - uses: actions/setup-node@v1
        with:
          node-version: '12.18.4'

      - name: Install and Build 🔧
        run: |
          npm ci
          npm run build
```

Lastly we need to add a step which will make the deployment for us. For this we can leverage the [github-pages-deploy-action action](https://github.com/JamesIves/github-pages-deploy-action), made by yours truly. In this step you'll need to configure the name of the folder where your compiled code gets pushed into, and then the branch you'd like to push that compiled code to. You can change the branch that GitHub Pages uses by going to your repository settings.

```yml
name: Build and Deploy
on:
  push:
    branches:
      - main
jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    concurrency: ci-${{ github.ref }}
    steps:
      - name: Checkout 🛎️
        uses: actions/checkout@v2

      - name: Install and Build 🔧 # This example project is built using npm and outputs the result to the 'build' folder. Replace with the commands required to build your project, or remove this step entirely if your site is pre-built.
        run: |
          npm ci
          npm run build

      - name: Deploy 🚀
        uses: JamesIves/github-pages-deploy-action@v4
        with:
          branch: gh-pages # The branch the action should deploy to.
          folder: build # The folder the action should deploy.
```

Depending on your needs you can configure the deployment step in multiple different ways. If you need to deploy to a different repository you can do that by leveraging the `repository-name` field, you can even specify a `target-folder` if you want your production build to deploy to a specific folder within a branch. [Take a look at the documentation](https://github.com/JamesIves/github-pages-deploy-action) for more details.

```yml
- name: Deploy 🚀
  uses: JamesIves/github-pages-deploy-action@v4
  with:
    branch: gh-pages
    folder: build
    repositorty-name: JamesIves/lab
    target-folder: public
```

Once the workflow has been pushed to your project you'll be able to see the workflow runs by selecting the `Actions` tab within the GitHub interface. If everything looks good and there's no errors everything will be green and your application will be deployed.

![Actions Workflow](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/awtxps9hubwn5swxbssw.png)

## Keeping it Updated

Like any sort of third party dependency it's always a good idea to keep it updated, and GitHub Actions are no different. Using GitHub's built in Dependabot service you can configure it to make frequent pull requests against your project to update your workflow versions as they become available on the marketplace. To do this you can create a `dependabot.yml` file within the `.github` directory and add the following to it. 

```yml
version: 2
updates:
  - package-ecosystem: github-actions
    directory: '/'
    schedule:
      interval: daily
      time: '10:00'
    open-pull-requests-limit: 10
```

## Closing Notes

Around three years ago I created the [github-pages-deploy-action project](https://github.com/JamesIves/github-pages-deploy-action) as my first real venture into the world of open source. I built this action so I could make continued updates to a blog while being away from my work laptop. The community response has been fantastic and I'm very happy with how it has evolved over the years as a result. I even had the [opportunity to be interviewed by GitHub for my involvement back in 2020 which you can read here](https://github.blog/2020-09-25-github-action-hero-james-ives-and-github-pages-deploy/).

![GitHub Action Hero James Ives](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n5907rhl549axwm9aiab.png)

In the three years that I've maintained this project it has seen the following as of January 2022:

* Referenced in 45,000+ public workflows
* 1,105 Commits
* 2,600+ Stars
* 676 Pull Requests
* 30+  Contributors

If you'd like to check out some of my other projects you can check out the [Fetch API Data Action](https://github.com/JamesIves/fetch-api-data-action) which I wrote an [article about](https://jamesiv.es/blog/github/actions/2020/03/07/fetching-authenticated-api-data/) a while ago or you can [check out this one which I created to simplify the process of adding GitHub Sponsors to the README of popular projects](https://github.com/JamesIves/github-sponsors-readme-action) as a perk for donating. 

If you'd like to get in touch I can be reached on [Twitter](https://twitter.com/_JamesIves). Additionally you can [drop a note on the discussion board for the project if you have specific questions related to it](https://github.com/JamesIves/github-pages-deploy-action/discussions) or drop a comment below!