CD-ing My Blog With GitLab CI/CD Devops
June 18, 2022As someone who makes style changes to their blog almost every day and blogs twice every 4 years (typical), I simply cannot compromise on the delivery process of my blog. I need to able to build and deploy my changes as quickly as possible for the millions who are waiting for my insight.
I used to have a deploy script to build my pages and push them to a separate Git repository for the statically generated files only and that repo was served using GitHub Pages. So every time I made changes, I needed to run the script manually, from the terminal. I know, painful!!
Here’s a quick summary of my blog stack:
-
Hugo:
I made the switch from Jekyll to Hugo at the time just because it’s written in Go and because I usually mistype Jykell. Currently looking for one that’s written in V-lang to migrate to. On the side, I got a hugo improvement in the build speed compared to Jekyll.
-
A Webpack project for building PostCSS and TypeScript:
An overkill, I know. I should replace it with a simple React app with hooks and use the most redundant React features (which become the standard anyway). On a side note: I know Webpack will probably break if I update it :) :) :)
-
GitLab CI/CD:
As a devOops/SRE/platform/YAML engineering enthusiast, I love GitLab CI/CD. It’s the poor man’s Jenkins. Jenkins feels like it came out in 2006 by Oracle and it requires Adobe Flash to use it. Nah, I’m kidding. Jenkins is the GOAT 🐐. Let’s get back to GitLab CI/CD, the main topic of this post: Great documentation. Clear dashboard. YAML (good: familiar, bad: YAML).
Now, to the juice:
-
0: Have a blog
-
Make a repository on GitLab for your blog
-
Add a
.gitlab-ci.yml
:image: node:14.15.4 pages: stage: deploy script: - ./build.sh artifacts: paths: - public/ only: - master
This looks straightforward. It calls a script
build.sh
and the build files will be cached underpublic/
. This folder will be served to your GitLab Pages pages.I used
image: node
here to havenpm
available for my frontend/theme (Emphasis on the overkill part). -
Add the build script:
#!/bin/sh # If a command fails then the deploy stops set -e printf "\033[0;32mBuilding the website...\033[0m\n" yarn --cwd themes/dark-matter/ yarn --cwd themes/dark-matter/ build ./hugo
Also, straightforward. Install the theme dependencies and build the static JS and CSS files. Ah, I use
yarn
here because I like to show off.It’s worthy to note that I setup Webpack to output separate JS and CSS files based on what they’re needed for. For example:
module.exports = { entry: { index: path.resolve(__dirname, 'src', 'ts', 'index.ts'), comments: path.resolve(__dirname, 'src', 'ts', 'comments.ts') }, output: { path: path.resolve(__dirname, 'static', 'assets'), filename: '[name].js' }, plugins: [ new MiniCssExtractPlugin({ filename: "[name].css" }) ], }
index.js
is loaded in all pages in hugo. Butcomments.js
is only loaded in the comments partial (currently not working, thanks to GitHub for breaking their API). I don’t have a lot of JavaScript. I mainly use it to load some WebFonts and for the light-dark-theme toggle button above (although it changes with CSS and the system-wide theme anyway but I kept the manual toggle too).Next, hugo builds the pages. I downloaded and copied the
hugo
binary into my repository. It’s lazy and works well. -
git commit -am "Add questionable changes" && git push origin master
-
If you’re lucky, your pages will be deployed
Now when I git push
this post, it will be deployed automatically. And this is how you got here.
Have fun [not] blogging!