2020 Website Refresh: More Automation Edition
It’s been over 10 months since my last blog post on here, and I decided it was high time for a fresh look at the site. Not to mention I’m on lockdown because of COVID-19. It seemed like as good a time as any to do some spring cleaning both in real life, and online.
Minor Visual Updates
I decided to make some tiny updates to the site style, most notably a new font for headings.

Next I also made a few tiny changes to the background color, and the drop shadow around each blog post. The colour changes are barely perceptible, but it made me happy to make it into a gradient instead of a flat gray.

Lastly, I also changed the header. The home page has a big circular picture of my ugly mug, and some more classy typography. Single post pages have a tiny circle and still, classy typography just moved over to the right.

Deployment Pipeline
This is where the real action is.
This site is powered by the
Hugo static site generator, and for the longest
time, it had been built by a Jenkins job running on my home server which I
would manually trigger. Jenkins would dutifully build the site using hugo
,
upload the generated HTML to Amazon S3, and then create a cache invalidation
in AWS CloudFront to bust caches at
POPs around the world.
After recently “redoing” my server (post on that coming “soon”) I never recreated poor Jenkins’ docker container and so if I had made any updates to the site in the meanwhile, I would have had to build and deploy the site from my laptop like a savage.
Enter Bitbucket Pipelines
Disclaimer: I work at Atlassian, but not on the Bitbucket team :)
I already host my website’s git repo on Bitbucket so why not give pipelines a whirl? It had been a long time since I had tried to use Pipelines and they’ve really drastically improved pretty much everything about it.
Here is the bitbucket-pipelines.yml
for this website:
image: phybros/docker-hugo-builder:0.67.1
pipelines:
branches:
master:
- step:
name: Build and minify files
script:
- hugo --config willwarren.com.toml
- minify -r -o public/ public/
artifacts:
- public/**
- step:
name: Deploy to S3
deployment: Production
script:
- pipe: atlassian/aws-s3-deploy:0.4.1
variables:
AWS_DEFAULT_REGION: 'us-east-1'
S3_BUCKET: 'willwarren.com'
LOCAL_PATH: 'public/'
- pipe: atlassian/aws-cloudfront-invalidate:0.3.1
variables:
AWS_DEFAULT_REGION: 'us-east-1'
DISTRIBUTION_ID: 'EXXXXXXXXXXXA'
PATHS: '/*'
The heavy lifting here is done by Bitbucket’s “pipes” - little reusable stages that are open source. You can see them all here: https://bitbucket.org/product/features/pipelines/integrations.
There is one that basically does an aws s3 sync
operation
(atlassian/aws-s3-deploy:0.4.1
), and another that does aws cloudformation create-invalidation
(atlassian/aws-cloudfront-invalidate:0.3.1
). These
reusable bits are so simple but really powerful when you start connecting them
all together.
To make the above work you need to add 2 repository variables
AWS_ACCESS_KEY_ID
and AWS_SECRET_ACCESS_KEY
. You can do this by going to
Settings > Pipelines > Repository Variables. Don’t forget to check the
Secured checkbox when adding the variables.

That’s it! Now whenever I push to master
the pipeline is triggered. It looks
something like this:

Now the only thing standing in the way of publishing more is writing more!
Manual Deploys
If you add the line trigger: manual
under deployment: Production
,
Bitbucket gives you a neat little button in the Pipeline run screen that you
have to click to allow the deployment to proceed. Super cool!
Docker Image for Hugo
There was many details that I glossed over, but the most glaring is the first
line of the yaml file: image: phybros/docker-hugo-builder:0.67.1
. I created
a new docker image specifically for building Hugo sites in CI/CD pipelines.
You can go check it out here:
https://hub.docker.com/r/phybros/docker-hugo-builder. Currently only Hugo
v0.67.1
is supported, but that can be easily changed.
Just send me a PR!