Let’s begin by describing the components that we will be covering here.
What’s Astro?
Ah, Astro – the latest darling of the web framework world. Astro is the web framework for content-driven websites, Astro powers the world’s fastest websites, client-side web apps … let’s be real: it’s a static site generator that decided to dress up fancy.
What’s GitHub Pages?
GitHub Pages is your no-nonsense, static-site runway. It takes your code, gives it a cape, and lets it fly as a live website.
What’s GitHub Actions?
GitHub Actions is your code’s personal assistant. It’s all about automation - from testing to deployment. Think of it as a backstage crew that gets stuff done while you take a coffee break.
Okay, let’s lay down some ground rules to keep everyone on the same page:
- First, you’ve got Astro up and running.
- Second, you have a GitHub account.
- And lastly, you’re opting for a Self-Hosted GitHub Runner. Why? Because, you know, trust issues.
As we connect all the dots in this tech saga, expect a bumpy ride.
Create a Private Repository
- To host all those fancy Astro files that magically transform into a static site, you’ll need a place to store them.
- Let’s name our repository
astro-build
and push all our files (it has a solid .gitignore, so let’s not mess with that) - Generate a key pair, you can use
ssh-keygen -t rsa -b 4096 -C "astro-deployment-key" -f astrokey -N ""
- Open
astrokey
(which is the private key) and copy the contents - Go to
astro-build
and navigate to Settings » Secrets and variables » Actions, under Secrets tab add a new repository secret calledASTRO_PRIVATE_KEY
and paste the private key, finish it up with Add Secret.
Create a Public Repository
- This public repository will be the new home for your generated static site, ready to bask in the glory of the internet’s spotlight.
- The name of the repository is based on your user or organization (
<user>.github.io
or<organization>.github.io
), more info here - Open
astrokey.pub
(which is the public key) and copy the contents - Open
<user>.github.io
and navigate to Settings » Deploy keys. Then, click on Add deploy key, name itASTRO_PUBLIC_KEY
, and paste the public key we copied earlier.
Create a Self-Hosted Github Runner
- Why choose a self-hosted runner instead of the public GitHub runner? Well, because of trust issues, and why not?
- Go to
astro-build
(private repository we created earlier), Settings » Actions » Runners. Then, click on New self-hosted runner - Pick your OS flavor that Github Runner will run on follow the steps provided by them
- I do suggest adding a special tag like
astro-blog
.
The last piece of our tech puzzle
- Create a folder
.github/workflows
- Create a file called
deploy.yml
with the following:
name: Deploy to GitHub Pages
on:
push:
branches: [ main ]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
jobs:
common-config:
runs-on: astro-blog
steps:
- name: Checkout your repository using git
uses: actions/checkout@v3
build:
needs: common-config
runs-on: astro-blog
steps:
- name: Install, build, and upload your site
uses: withastro/action@v1
deploy:
needs: build
runs-on: astro-blog
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy
id: deployment
uses: peaceiris/actions-gh-pages@v3
with:
deploy_key: ${{ secrets.ASTRO_PRIVATE_KEY }}
external_repository: <user>/<user>.github.io
publish_branch: main
publish_dir: ./dist
force_orphan: true
full_commit_message: ${{ github.event.head_commit.message }}
cleanup:
needs: deploy
if: always()
runs-on: astro-blog
steps:
- name: Cleanup
run: /astro/cleanup.sh
- Update
external_repository: <user>/<user>.github.io
with your GitHub user/organization. The public repository you want to push to - If you decided not to tag your GitHub Self-Hosted Runner with
astro-blog
, change all the values for runs-on - Kudos to those who spotted the cleanup step at the end! It means you’re actually paying attention and not just skimming through
I’ve noticed that running a self-hosted runner as described throws an error on the second run
unix_listener: cannot bind to path /tmp/ssh-auth.sock: Address already in use
My ‘fix’ is hackish, I’ll admit. But let’s be real, it’s about striking that perfect balance between being brilliantly lazy and impressively efficient.
The cleanup.sh
script:
#!/usr/bin/env bash
pkill ssh-agent
[[ -f /tmp/ssh-auth.sock ]] && rm /tmp/ssh-auth.sock
Diagram
Now each time you commit to the private repository, the site will automatically be generated and then pushed to the public repository.
That’s all folks!