Skip to content

Instantly share code, notes, and snippets.

@avibathula
Created February 8, 2024 20:39
Show Gist options
  • Save avibathula/bb55d9e52f295e9b0a08a308920dafef to your computer and use it in GitHub Desktop.
Save avibathula/bb55d9e52f295e9b0a08a308920dafef to your computer and use it in GitHub Desktop.
GitHub Actions Workflow to build Hugo static site and deploy (using rsynch) over to your hosting site
# GitHub Actions Workflow for building and deploying a Hugo site to GitHub Pages. This script uses
#. GitHub Actions Secrets to set the following with sample values
#
# RUNNING_GITHUB_ACTIONS=true
# HOSTINGSITE_CONTENT_DESTINATION_FOLDER=~/domains/my-production-site/public_html/
# HOSTINGSITE_CONTENT_SOURCE_FOLDER=./public/
# HOSTINGSITE_DEPLOYMENT_GITHUBACTIONS_SSH_PVTKEY
# HOSTINGSITE_SSH_HOSTNAMEIP=145.116.87.110
# HOSTINGSITE_SSH_PORT=12345
# HOSTINGSITE_SSH_USERNAME=u411364491
# PROD_BASE_URL=https://my-production-site.com
# TEST_BASE_URL=https://my-testvalidation-site.site.com
#
# NOTE 1: The SSH pvt key should NOT have a passphrase, or else the SSH key setup step will block for ever.
#. So, be very careful with the SSH key.
#
# NOTE 2: This workflow will need to be updated to run locally using https://github.com/nektos/act package.
#. For example you wont need sudo to install dependency packages as the workflow runs on a linux docker image
#. with root privileges. Also dealing with SSH pvt key is a hassle as it is a multiline text.
#
# NOTE 3: Ensure .env file is added to .gitignore to ensure it doesnt get commited into your repo.
name: Deploy Hugo site from GitHub repo to Hostingsite
on:
# Runs on pushes targeting the default branch
# Push to "dev" branch should result in depolyment to test site of test-avi.bathula.me
# Push to "main" branch should result in depolyment to production site avi.bathula.me
push:
branches: ["dev", "main"]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# Workflow needs permission to read the contents of the repository
permissions:
contents: read
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
group: "HUGO_DEPLOY"
cancel-in-progress: false
# Default to bash
defaults:
run:
shell: bash
jobs:
# Build and Deply job
build_and_deploy:
runs-on: ubuntu-latest
env:
HUGO_VERSION: 0.122.0
GO_VERSION: 1.21.6
steps:
- name: Install necessary dependencies
run: |
echo "Build-1: Install Hugo CLI" \
&& sudo apt-get update && sudo apt-get install -y wget rsync nodejs npm git
- name: Echo Running installation and verification steps of Go
run: |
echo "Build-3: Installing Go and verifying installation"
- name: Setup Go
uses: actions/setup-go@v2
with:
go-version: ${{ env.GO_VERSION }}
- name: Verify Go Installation
run: |
go version
- name: Install Hugo CLI
run: |
echo "Build-4: Install Hugo CLI" \
&& wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \
&& sudo dpkg -i ${{ runner.temp }}/hugo.deb
- name: Install Dart Sass
run: |
echo "Build-5: Install Dart Sass" \
&& npm install -g sass
- name: Echo running of Checkout step
run: |
echo "Build-6: Running Checkout"
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive
- name: Update last build date
run: echo "LastBuildDate = $(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> config.toml
- name: Build with Hugo
env:
# For maximum backward compatibility with Hugo modules
HUGO_ENVIRONMENT: production
HUGO_ENV: production
run: |
echo "Build-8: Build with Hugo" \
&& hugo \
--minify \
--baseURL "${{ steps.resolve_env_vars.outputs.URL }}/"
- name: Resolve Base URL and SSH key env vars based on where the script is running
id: resolve_env_vars
run: |
echo "Build-7: Setting Base URL" \
&& if [ ${{ secrets.RUNNING_GITHUB_ACTIONS }} = "true" ]; then
echo "Running on GitHub Actions on ${{ github.ref }} branch";
echo "SSH_HOSTNAMEIP=${{ secrets.HOSTINGSITE_SSH_HOSTNAMEIP }}" >> $GITHUB_OUTPUT;
echo "SSH_PORT=${{ secrets.HOSTINGSITE_SSH_PORT }}" >> $GITHUB_OUTPUT;
echo "SSH_USERNAME=${{ secrets.HOSTINGSITE_SSH_USERNAME }}" >> $GITHUB_OUTPUT;
echo "CONTENT_SOURCE_FOLDER=${{ secrets.HOSTINGSITE_CONTENT_SOURCE_FOLDER }}" >> $GITHUB_OUTPUT;
echo "CONTENT_DESTINATION_FOLDER=${{ secrets.HOSTINGSITE_CONTENT_DESTINATION_FOLDER }}" >> $GITHUB_OUTPUT;
if [ "${{ github.ref }}" = "refs/heads/main" ]; then
echo "URL::${{ secrets.PROD_BASE_URL }}" >> $GITHUB_OUTPUT;
else
echo "URL::${{ secrets.TEST_BASE_URL }}" >> $GITHUB_OUTPUT;
fi
else
echo "Running on local machine";
echo "URL=${{ env.TARGET_BASE_URL }}" >> $GITHUB_OUTPUT;
echo "SSH_HOSTNAMEIP=${{ env.HOSTINGSITE_SSH_HOSTNAMEIP }}" >> $GITHUB_OUTPUT;
echo "SSH_PORT=${{ env.HOSTINGSITE_SSH_PORT }}" >> $GITHUB_OUTPUT;
echo "SSH_USERNAME=${{ env.HOSTINGSITE_SSH_USERNAME }}" >> $GITHUB_OUTPUT;
echo "CONTENT_SOURCE_FOLDER=${{ env.HOSTINGSITE_CONTENT_SOURCE_FOLDER }}" >> $GITHUB_OUTPUT;
echo "CONTENT_DESTINATION_FOLDER=${{ env.HOSTINGSITE_CONTENT_DESTINATION_FOLDER }}" >> $GITHUB_OUTPUT;
fi
- name: Echo Setting up SSH key before deployment
run: |
echo "Build-9: Setting up SSH key before deployment"
- name: Set up SSH key
uses: webfactory/ssh-agent@v0.5.3
with:
ssh-private-key: ${{ secrets.HOSTINGSITE_DEPLOYMENT_GITHUBACTIONS_SSH_PVTKEY }}
- name: Deploy with rsync
run: |
echo "Build-10: Deploying with rsync" \
&& rsync -avz --delete -e "ssh -p ${{ steps.resolve_env_vars.outputs.SSH_PORT }} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" ${{ steps.resolve_env_vars.outputs.CONTENT_SOURCE_FOLDER }} ${{ steps.resolve_env_vars.outputs.SSH_USERNAME }}@${{ steps.resolve_env_vars.outputs.SSH_HOSTNAMEIP }}:${{ steps.resolve_env_vars.outputs.CONTENT_DESTINATION_FOLDER }}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment