December 18, 2019
Github actions allow me to implement continuous delivery for this blog. Each time I merge to master, jimkubicek.com is built and deployed.
First, this action should run anytime the master
branch is updated.
name: Build and Deploy
on:
push:
branches: [master]
Now we need to create our deploy steps. Let’s use a Ubuntu container with the latest commit in our branch checked out.
jobs:
deploy:
name: Deploy to jimkubicek.com
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
Install Python 3.8 (or whatever version you’re using):
- name: Set up Python 3.8
uses: actions/setup-python@v1
with:
python-version: 3.8
Upgrade pip
and install the latest version of the Pelican static site generator and the Invoke task runner:
- name: Install Pelican
run: |
python -m pip install --upgrade pip
pip install invoke pelican[Markdown]
In order for SSH to work correctly, we’ll need to make sure that our public and private keys are created and placed in the correct location. On your local machine, let’s generate a valid keypair.
ssh-keygen -t rsa -f -b 4096 ./github_actions -C github_actions
Now, let’s copy the public key up to our server.
ssh-copy-id root@example.com -i github_actions
Now copy the private key into the pasteboard and add it to your github secrets. This action uses a secret with the name PRIVATE_KEY
. Paste the contents of your clipboard into this secret.
cat github_actions | pbcopy
Now, in our action file, we’ve got to read this secret and get it setup on disk. The env
command extracts the secret out and stores it into an environment variable. Make sure that the .ssh
directory exists, and save that private key into the id_rsa
file. SSH requires that the key has restricted access, so set the access to 400
. Finally, add our IP address to the list of known and approved hosts. The downside of this is that if your server is MITM’d you’ll continue to just blindly trust it. I’m not sure of a way around this, if you know, let me know.
Here’s the final SSH setup stage:
- name: Setup the SSH key
env:
PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }}
run: |
mkdir $HOME/.ssh
echo "$PRIVATE_KEY" >> $HOME/.ssh/id_rsa
chmod 400 $HOME/.ssh/id_rsa
ssh-keyscan -t rsa <SERVER_IP> >> $HOME/.ssh/known_hosts
Finally, use Invoke to upload to our server.
- name: Push to example.com
run: inv publish
« Setting up Let’s Encrypt with Nginx | Home | I’m writing this on an iPad »