As of Dec 2021, this is now outdated. I am no longer using Dendron, nor nomad to deploy the site. I’ll have a follow up shortly.

This expands on the DroneCI -> Nomad pipeline I examined earlier

I explained why I use Dendron, today I will show how. The glue that binds Dendron, Quantified Self reports, and Hugo is DroneCI.

The CI build runs every night and immediately when a commit is made to the Hugo site.

I wrote a custom Pod for exporting notes. It’s similar to the built-in markdown pod, but includes frontmatter and renders a hierarchical structure which makes Hugo happy.

The server completes these build steps:

  1. Clone the required build repos from Github / Gitea:
    1. Hugo site workspace
    2. Hugo site theme
    3. Dendron workspace and notes
    4. Dendron <-> Hugo export pod
    5. Nomad config files
  2. Once the files are in order, we install dendron-cli and link the hugo-pod in an node container
  3. Apply the included patch that skips validation of the pod
  4. Run the export pod, creating a well formed /garden/ subdirectory in Hugo’s content folder
  5. Build the Hugo site
  6. Build the final Docker image with the new public directory
  7. Publish the final Docker image
  8. Send a redeploy command to Nomad using the config cloned in step 1.
  9. Prune old Docker images from our registry

Done! Simple, no? 😆

Build Status

The complexity stems from the sources being so scattered (Dendron, Hugo, Nomad…). Obviously this isn’t practical for casual note writing. But in my head, if it’s worth doing it’s also worth overdoing.

This is the full .drone.yml spec:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
kind: pipeline
type: docker
name: default

clone:
  git:
    image: plugins/git
    recursive: true
    submodule_override:
      "themes/novela": https://git.quinncasey.com/qcasey/hugo-theme-novela

steps:
  - name: "Clone hugo theme"
    image: alpine/git
    commands:
      - sed -ir 's$:$/$' .gitmodules
      - sed -ir 's$git@ssh.$https://$g' .gitmodules
      - git submodule update --recursive --init

  - name: "Clone Dendron notes and export pod"
    image: alpine/git
    commands:
      - git clone https://git.quinncasey.com/qcasey/hugo-pod.git
      - git clone https://git.quinncasey.com/qcasey/notes-framework.git notes
      - cd notes
      - git clone https://git.quinncasey.com/qcasey/notes.git garden

  - name: "Export Dendron notes"
    image: node:current-alpine3.11
    commands:
      - npm install -g @dendronhq/dendron-cli
      - cd hugo-podand
      - npm install
      # Skip validation error "data must NOT have additional properties"
      - patch node_modules/@dendronhq/pods-core/lib/utils.js < utils.js.patch
      - npm link
      - cd ../notes/
      - npm link hugo-pod
      - dendron-cli exportPod --wsRoot ./ --podId hugo --podPkg hugo-pod --podSource custom --config "fname=dendron,vaultName=vault,dest=../content,includeStubs=true"

  - name: "Build site with hugo"
    image: klakegg/hugo:ext-alpine
    commands:
      - hugo

  - name: publish
    image: plugins/docker
    settings:
      registry: registry.quinncasey.com
      repo: registry.quinncasey.com/garden-quinncasey
      tags:
        - latest
        - ${DRONE_BUILD_NUMBER}
      username: casey
      password:
        from_secret: registry_password

  - name: clone deployment dotfiles
    image: alpine/git
    commands:
      - git clone -b abathur https://git.quinncasey.com/qcasey/dotfiles

  - name: redeploy nomad
    image: multani/nomad
    commands:
      - nomad run -address=http://192.168.1.196:4646 -var=image_id=${DRONE_BUILD_NUMBER} dotfiles/nomad/webserver/quinncasey.com.nomad

  - name: prune images
    image: anoxis/registry-cli:latest
    commands:
      - /registry.py -l casey:$PASSWORD -r https://registry.quinncasey.com -i garden-quinncasey --delete --num 10 --keep-tags "stable" "latest"
    environment:
      PASSWORD:
        from_secret: registry_password