simfish:

Blogging

This document provides a development environment and a build script for my personal blog, simfish.dev

cover image
If you build it, they will come

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