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
litdoc site load dev.simfish
Once the environment is loaded, the following commands are available.
site_up
use this command for starting a local hugo
web server.
After launching this command, visit http://localhost:1313
and start hacking as usual hugo
website.
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
: is a command for building this repo without running hugo
server.
This is used internally when deploying the page to gitlab pages.
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_deploy
is a utility for deploying this repo as a Gitlab page.
It registers a Gitlab runner and optionally triggers a CI/CD
pipeline run. To behave as expected the command expects the hosting
environment to be configured with the following environmental
variables,
GL_TOEKN= ***** # this is a gitlab API token, it is used for rendering project information.
GL_PROJECT_ID= ***** # the gitlab project ID(for this blog)
GL_RUNNER_TRIGGER_TOEKN= ***** # token for manually(API based) triggering of build pipeline(optional)
The command implementation is as follows,
site_deploy() {
gitlab-runner register \
--non-interactive \
--url https://gitlab.com \
--token ${GL_RUNNER_TOKEN} \
--executor shell
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
}
The entry point for the build script is shown below.
case "${1}" in
up)
site_up
;;
build)
site_build || {
echo "failed to build site"
exit 1
}
exit 0
;;
deploy)
site_deploy || {
echo "failed to deploy site"
exit 1
}
exit 0
;;
,*)
echo "simfish.dev development environment"
echo "available commands:"
echo "- site_up: start local hugo site development server"
echo "- site_build: build the site"
echo "- site_deploy: deploy website to Gitlab pages"
exec bash "${@}"
;;
esac
echo "ERROR: unexpected error"
exit 1
The important bit is that, loading the development environment and running the
build commands can be combined. For example, instead of loading the
development environment and executing site_up
, run
litdoc site run simfish.dev up
Packages
The development environment is configured with the following Guix package manifest:
(specifications->manifest
'(
"curl"
"openssl"
"bash"
"coreutils"
"guix"
"git"
"gitlab-runner"
"go"
"hugo"
"python"
"python-matplotlib"
"python-pandas"
"python-requests"
"python-twisted"
"python-bottle"
"please-build"
"brotli"
"gzip"
"gcc-toolchain"
"tar"
"xz"
"gettext"
"optipng"
"jpegoptim"))
Appendix
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)))
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 "0y1yncsd4y3vjdbfd3ps8qjg7aaf9kraalngy5ciqalfala4nlv7"))))
(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)))