Saving 2 Minutes of My Life with GitHub Actions
Published on February 12, 2023
The Problem
So my previous project, the Random Mashup Generator was built using React and TypeScript. The challenge? Browsers understand HTML/CSS/JS, but not React components. So, I had to locally build the project and then manually deploy the resulting build folder to Netlify. This workflow was manageable for occasional projects but became a significant hassle when working on my personal website.
Unlike the Mashup Generator, my personal website relies on a static site generator, which requires a build step to transform templates and markdown into HTML/CSS. What sets it apart is that I frequently make tweaks and adjustments. The thought of repeatedly building the project locally, navigating to Netlify, and manually uploading it didn’t sit well with me. This is when I began exploring GitHub Actions as a potential solution.
What Are GitHub Actions?
Think of GitHub Actions as a simple server provided by GitHub, aptly called a “runner.” However, instead of interacting with it directly, you define instructions in the form of YAML files. These instructions execute when specific events occur within your repository, such as pushing a commit to the main branch or creating a pull request.
These YAML files are called “workflows” and are placed in the .github/workflows
directory. Here’s what the directory structure of my repository looks like:
root/
|-- .github/
| |-- workflows/
| | |-- host.yml
When Does the Workflow Run?
I wanted GitHub to automatically build and deploy my website every time I pushed a commit to the main branch. This is defined by specifying the event in the on
section of the workflow YAML file:
on:
push:
branches:
- main
What Does the Workflow Do?
Similar to the steps we take on our local computers, GitHub Actions workflows consist of specific instructions called “steps.” Each step can be a shell script or a pre-made action, and they run in sequence, one after the other, with dependencies between them.
Checking Out the Repository
First, just like on our local machines, we need to navigate to the project directory. GitHub provides a pre-made action called actions/checkout@v3 that grants the workflow access to the repository. Here’s how I set it up:
jobs:
host:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
Setting Up Node
Next, I specify that I want to use Node.js, and there’s another handy action, actions/setup-node@v3, to accomplish this. I placed this step after the checkout step:
steps:
- name: Use Node.js 19
uses: actions/setup-node@v3
with:
node-version: 19
With Node.js ready, I move on to installing the project’s dependencies, which I do with a simple shell script:
steps:
- name: Install dependencies
run: npm ci
I use npm ci
instead of npm install
for a clean, automated environment-friendly installation of dependencies. It’s worth noting that I encountered an error at this stage because I had ignored the package-lock.json
file, which is required for this command.
Building and Deploying
Similarly, I execute another shell command to build the project. I’ve configured an npm script to direct the build output (HTML/CSS/JS files) to the _site
folder:
steps:
- name: Build Eleventy
run: npm run build
Finally, I host my website on GitHub Pages and want it to access the _site
folder. To accomplish this, I use another GitHub Actions action, peaceiris/actions-gh-pages@v3. This action creates a new branch named gh-pages
in the repository and deploys the _site
folder there:
steps:
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
publish_dir: ./_site
github_token: ${{ secrets.GITHUB_TOKEN }}
That’s it! This was my introduction to continuous delivery, which, in essence, is streamlining the entire process. I hope this post has given you a basic understanding of GitHub Actions and how it can simplify your development and deployment workflows.
Complete Workflow File
name: Build and Deploy
on:
push:
branches:
- main
jobs:
host:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
- name: Use Node.js 19
uses: actions/setup-node@v3
with:
node-version: 19
- name: Install dependencies
run: npm ci
- name: Build Eleventy
run: npm run build
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
publish_dir: ./_site
github_token: ${{ secrets.GITHUB_TOKEN }}