Silverpoint
A journal written in Swift by Hugo A.G

If it hurts, do it more frequently, and bring the pain forward

Thats a fun quote that sounds nonsensical at the surface level but is rooted in valuable meaning. The more frequent you do something painful, the less painful it'll seem. Thats where Continuous Integration comes into play.

This blog post is about how I managed to host Silverpoint on github and to set it up so that anytime I commit my changes to the site, they get updated on the internet as well without me having to lift another finger.

Hosting through Github Pages

In the past I've leveraged anything from godaddy or hostgator to Amazon's server infrastructure or even S3 static buckets for website hosting. In the spirit of trying new things I decided to give github a chance this time around.

Github allows you to serve websites from the git repository containing its code as long as long as you follow a specific naming convention and your repo has an index.html file. This is pretty convenient for people who want to host their own personal site or their company site without having to rely on a more complicated third party provider.

After setting up my empty repository I was pretty much halfway done. The next part gets a little tricky though.

Website Content and Personal Repositories

As of this post's creation, github only allows personal websites to be served from the master branch of a repository. That means that all your website code (especially the index.html) has to live in your master branch. Organizations on the other hand can point their website code to a specific branch to be served from. Since I chose to have Silverpoint hosted as a personal repository, I had to work around this limitation.

Since all the HTML that Publish generates lives inside of the Output folder, I created a separate repository that only contained the contents of this Output folder and set that as the master branch. I kept all the other Publish specific files separate from this folder for this step.

Once this master branch was created and pushed up to the github repository, I was already able to access Silverpoint via the github pages domain link. Afterwards I created a separate branch in this repository (called develop) that contained all of the Publish specific sources such as the Package.swift file, the Content folder, Resources, etc. Now we're ready to set up the repository to automatically update itself when we push to Github.

Continuous Integration Setup

Recently Github released their CI flow known as Github Actions to the general public. This allows us to specify a workflow in our project to be executed after pushing up a commit to our repository.

For our purposes, we need a workflow that will run Publish's CLI and generate our static site's new changes in the Output folder.

For that we need a build instance that has Swift installed as well as Publish's CI in order to run the publish run command inside our repo. Finally, once that command is run, we have to make sure we publish our changes to the target branch of the repository that's serving our content. In our case, since this is a personal github page, we can only serve website content on the master branch as explained above.

Integrating the Github Action

The first thing I had to do was setup my github workflows folder in my project. I checked out my develop branch that contains all the Publish sources and created the .github/workflows/ directories. Inside I placed a YAML file called gh-pages.yml. Github will use this file to know what configuration workflow it has to run. In our case, it'll contain details for downloading swift and running the publish cli.

Afterwards I was able to save some time by finding a ready-made github action that Joe Blau made which handles most of the workflow we need. Feel free to follow the instructions provided at the action page, otherwise heres a summary of the steps.

  1. Generate your deploy key with the following command.
ssh-keygen -t rsa -b 4096 -C "$(git config user.email)" -f gh-pages -N ""
# You will get 2 files:
#   gh-pages.pub (public key)
#   gh-pages     (private key)
  1. Add SSH deploy key on GitHub.com Go to Repository Settings
    • Go to Deploy Keys and add your public key with the Allow write access permission.
    • Go to Secrets and add your private key as ACTIONS_DEPLOY_KEY
  1. Update the project YAML file at .github/workflows/gh-pages.yml and push to the default branch.

    Note: In our case, the push branch and the publish branches are different

name: Github Pages

on:
  push:
    branches:
    - develop 

jobs:
  build-deploy:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout
      uses: actions/checkout@v1
      
    - name: Install Swift
      uses: YOCKOW/Action-setup-swift@master
      with:
        swift-version: '5.1.2'
        
    - name: Build Publish
      run: |
        git clone https://github.com/JohnSundell/Publish.git
        cd Publish
        swift build -c release
        sudo install .build/release/publish-cli /usr/local/bin/publish

    - name: Generate Site
      run: publish generate

    - name: Deploy
      uses: peaceiris/actions-gh-pages@v2
      env:
        ACTIONS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }}
        PUBLISH_BRANCH: master
        PUBLISH_DIR: ./Output

Once you push up your on push branch specified in the YAML (develop in my case) you should be able to check the status of your deployment and the final result on your PUBLISH_BRANCH From here on out, enjoy the speed and convenience of pushing up changes to your Swift Site!

Tagged with: