This document provides a development environment and
a build script for my personal blog, simfish.dev
Blogging
Introduction
This documents describes a development environment and deployment pipeline used by this website, simfish.dev.
The site is built using Emacs/org-mode and Hugo. And, it is deployed as a Gitlab pages. The rest of this document describes the development and build process of this website using litdoc and gitlab.
Getting Started
The following requirements are assumed: git
, guix
, litdoc
clone the site repo locally,
git clone https://gitlab.com/aarongile/blog
And load the development environment using
the following litdoc
command:
cd blog
guix ld build dev.simfish
Once the workflow is built, available guix ld
commands are.
up
: is a command for starting a local hugo
web server. After launching this
command, visit http://localhost:1313
and start hacking as you would on any
other hugo
website.
guix ld simfish.dev -- up
build
: is a command for building simfish.dev site. The
command is used internally when deploying the page to gitlab pages.
guix ld simfish.dev -- build
release
is a command used for creating a release commit to be deployed
to gitlab pages.
guix ld simfish.dev -- release
deploy
is site deployment common. It is meant to have a minimal interaction
with <code>GitLab</code> CI/CD
As Gitlab-Runner
updates
seem to keep introducing breaking changes that fail site builds in creative ways.
At his point it seems it is better to keep the build scripts GitLab
CI/CD free instead of chasing ever so evolving bugs and feature depreciations. The build recipe
outline is Building the site offline, Create a release commit containing
the site, Copy the site, unfortunately using .gitlab.yml
,to Gitlab
pages to publish it.
guix ld simfish.dev -- deploy
Packages
The development environment is configured with the following Guix package manifest:
(specifications->manifest
'(
"curl"
"openssl"
"bash"
"coreutils"
"guix"
"git"
"go"
"hugo"
"python"
"python-matplotlib"
"python-pandas"
"python-requests"
"python-twisted"
"python-bottle"
"please-build"
"brotli"
"gzip"
"gcc-toolchain"
"gitlab-runner"
"tar"
"xz"
"gettext"
"optipng"
"jpegoptim"))
Appendix
Guix: hugo
This module provides Hugo binary for 64bit Linux systems running Guix.
(define-module (nongnu packages hugo)
#:use-module (gnu packages)
#:use-module (gnu packages gcc)
#:use-module (guix)
#:use-module (guix packages)
#:use-module (guix build-system copy)
#:use-module (guix download)
#:use-module (ice-9 format)
#:use-module ((guix licenses) #:prefix license:))
(define hugo-repo-url-format
"https://github.com/gohugoio/hugo/releases/download/v~a/hugo_extended_~a_~a.tar.gz")
(define-public hugo
(package (name "hugo")
(version "0.128.2")
(build-system copy-build-system)
(source (origin (method url-fetch)
(uri (format #f hugo-repo-url-format version version "Linux-64bit"))
(sha256 (base32 "1i8jqhw9rra3xjkxzzyj6liqrg52wdi5cdzf3dzijv6pap0m6cm8"))))
(inputs `(("gcc:lib" ,gcc-5 "lib")))
(arguments
(let* ((src_file "hugo")
(out_file `(lambda _ (chmod ,src_file #o777))))
`(#:install-plan '((,src_file "bin/hugo"))
#:validate-runpath? #f
#:phases (modify-phases %standard-phases (add-after 'unpack 'out_file ,out_file)))))
(home-page "https://please.build")
(synopsis "Please is a cross-language build system." )
(description
(string-append
"Please is a cross-language build system with an emphasis on high performance,"
"extensibility and reproducibility. It supports a number of popular languages "
"and can automate nearly any aspect of your build process."))
(license license:asl2.0)))
Guix: gitlab-runner
Configuration settings
(define-module (nongnu packages gitlab-runner)
#:use-module (gnu packages)
#:use-module (gnu packages gcc)
#:use-module (guix)
#:use-module (guix packages)
#:use-module (guix build-system copy)
#:use-module (guix download)
#:use-module (ice-9 format)
#:use-module ((guix licenses) #:prefix license:))
(define url-for-x86-64
"https://s3.dualstack.us-east-1.amazonaws.com/gitlab-runner-downloads/latest/binaries/gitlab-runner-linux-amd64")
(define-public gitlab-runner
(package (name "gitlab-runner")
(version "0.1")
(build-system copy-build-system)
(source (origin (method url-fetch)
(uri url-for-x86-64)
(sha256 (base32 "0jbrsb7ljknkvdhsvc0rzfz2a3rhicgvb9x7xs4ck5z21wc2j1g0"))))
(inputs `(("gcc:lib" ,gcc-5 "lib")))
(arguments
(let* ((src_file "gitlab-runner-linux-amd64")
(out_file `(lambda _ (chmod ,src_file #o777))))
`(#:install-plan '((,src_file "bin/gitlab-runner"))
#:validate-runpath? #f
#:phases (modify-phases %standard-phases (add-after 'unpack 'out_file ,out_file)))))
(home-page "https://please.build")
(synopsis "GitLab Runner runs the CI/CD jobs that are defined in GitLab." )
(description
"GitLab Runner is the open source project that is used to run your CI/CD jobs and send the results back to GitLab")
(license license:expat)))
Shell Scripts
main
is the entry point for the build script.
The functions site_up
, site_build
, site_release
, and site_deploy
implement sub-commands accessible via guix ld run simfish.dev -- [SUBCOMMAND]
site_up
site_up() {
plz clean
pushd ./scripts
python3 resource-server.py &
[ $? -eq 0 ] || {
echo "failed to start asset server"
exit 1
}
popd
sleep 3
plz build
pushd ./site || {
log_error "failed to enter directory"
exit 1
}
hugo server --config="config.toml" \
--environment="staging"\
--buildDrafts \
--buildExpired \
--buildFuture \
--cleanDestinationDir \
--logLevel=debug\
--gc \
--ignoreCache || {
log_error "failed to launch hugo server"
exit $?
}
popd
kill %1 || :
return 0
}
site_build
site_build() {
plz clean
cd ./scripts/
python3 resource-server.py &
sleep 3
cd -
plz build --config=dbg "//:simfish.dev"
exit_code=$?
kill % || :
return ${exit_code}
}
site_release
site_release() {
site_build || return 1
local release_file="release.tar.gz"
if [ -f "${release_file}" ]; then
rm "${release_file}"
fi
plz query output '//:simfish.dev' | xargs -I {} rsync --recursive {}/ release
tar -zcvf "${release_file}" ./release
rm -rf ./release
git add "${release_file}"
git commit --signoff -m "Updated site release"
return 0
}
site_deploy
site_deploy() {
gitlab-runner register \
--non-interactive \
--url https://gitlab.com \
--token ${GL_RUNNER_TOKEN} \
--executor shell
# trigger pipeline
curl -X POST \
--fail \
-F token="${GL_RUNNER_TRIGGER_TOKEN}" \
-F ref=main \
https://gitlab.com/api/v4/projects/${GL_PROJECT_ID}/trigger/pipeline
local build_dir="${HOME}/.cache/litdoc/simfish.dev/builds"
mkdir -p "${build_dir}"
gitlab-runner run --working-directory="${build_dir}"
return 0
}
entry-point
case "${1}" in
up)
site_up
;;
build)
site_build || {
echo "failed to build site"
exit 1
}
exit 0
;;
release)
site_release || {
echo "failed to create release commit"
exit 1
}
exit 0
;;
deploy)
site_deploy || {
echo "failed to deploy site"
exit 1
}
exit 0
;;
debug)
bash && exit 0
exit 1
;;
,*)
echo "simfish.dev development environment"
echo "available commands:"
echo "guix ld site COMMAND"
echo "COMMAND:"
echo "- up: start local hugo site development server"
echo "- build: build the site"
echo "- release: add a release commit"
echo "- deploy: deploy the website to Gitlab pages"
exit 1
;;
esac
echo "ERROR: unexpected error"
exit 1