Intro

Hi, in this post I will demonstrate how I created a simple CI/CD pipeline using GitHub Actions to automate the deployment of this site. The idea is that whenever I push something to the main branch, it will automatically build and deploy this site.

Runners

A runner is basically the server where the pipeline will execute. There are two options here, you can use a GitHub-hosted runner, or a Self-hosted runner.

A Self-hosted runner means you will use your own server. This is managed and maintained outside GitHub and requires a prior setup and configuration, but it gives you the freedom to configure and customize your environment as you wish.

GitHub-hosted runners are a quicker, simpler way to run your workflows. These are managed and maintained by GitHub, so you don’t have to worry about the setup. The free plan actually includes 500 MB of storage and 2,000 minutes per month. You will be charged for usage beyond these limits.

Because this is a small personal project, I will use GitHub-hosted runner for simplicity.

Defining the workflow

In order to create a workflow in GitHub, you must create the path .github/workflows/ and define within the .yml or .yaml files which have the instructions to run.

In this specific case, I will give the instructions to checkout the repository, build my hugo site, and finally deploy it to production.

Here’s the definition of .github/workflows/deploy-hugo.yml in my repository.

name: Build and deploy PythonPirate.tech

on:
  push:
    branches: [main]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Build the hugo site locally
        run: |
          sudo apt -y install hugo > /dev/null
          git submodule init
          git submodule update
          hugo
      - name: Deploy to PythonPirate.tech
        env:
          SSH_PRIVKEY: ${{ secrets.SSH_PRIVKEY }}
          SSH_USER: ${{ secrets.SSH_USER }}
        run: |
          eval `ssh-agent -s`
          echo "${SSH_PRIVKEY}" | ssh-add -
          rsync -e "ssh -o StrictHostKeyChecking=no" -avz --delete public/ ${SSH_USER}@pythonpirate.tech:/var/www

The directive uses selects an action that’s already defined and can be reused. It can be defined in the same repository as the workflow, a public repository, or in a published Docker container image. In this case, it uses actions/checkout@v4 to checkout the repository, so it’s available to the workflow.

Ensure that your sensitive information is stored as secrets on GitHub, rather than as plain text in the workflow definition! As this is a huge security issue.

The rest of the definition is self-explanatory, let me know if you have any doubts.

Checking the run

After pushing changes that match the on directive, you can check the pipelines on the Actions tab of your GitHub repository.

Github actions workflow

Hope this was helpful!