Architecture Field Notes — Delivery Pipeline Hugo static site → GitHub Actions → GitHub Pages · architectures.metacog.co.kr

01Business context

What the pipeline exists to do, and how you would know it is working.

Objective

  • Publish practical architecture knowledge — the tacit, made explicit
  • Nine sections, every page the same shape: the situation, the default, when it is wrong, what it costs
  • A prose edit reaches readers without a human touching a server

Users

  • DevOps engineers and developers reading the published site
  • One author committing Markdown and diagram artifacts to main

Value

  • No build step to run locally before publishing, and no deploy credentials on a laptop
  • The published site is a pure function of the commit — reproducible from the repository alone

Metrics that matter

  • Push to live: one workflow run, no manual gate
  • Determinism: Hugo version pinned to 0.161.1, Go to 1.22
  • Concurrency group pages with cancel-in-progress: false — deploys never interleave

02Data flow

Sources on the left, the build in the middle, the published artifact on the right.

SOURCES BUILD PUBLISHED Markdown content content/docs/ · 9 sections Diagram artifacts static/diagrams · assets/ Config + theme hugo.toml · Lotus Docs module Hugo extended hugo --gc --minify Go module fetch resolves the theme Pages artifact ./public Custom domain architectures.metacog.co.kr upload-pages-artifact deploy-pages Trigger: push to main, or workflow_dispatch — no scheduled build, no manual approval gate

03Processing pipeline

Stages ordered by probability of catching a failure divided by time to run. Everything left of the gate blocks; everything right of it deploys.

FAST — blocks the merge SLOW — after the gate Lint + types ~30s Unit tests ~2 min Build once ~3 min Integration ~5 min merge gate Promote artifact same bytes Progressive deploy deploy ≠ release Post-deploy verify then rollback path Nightly / scheduled e2e · load · scans Target: under 10 minutes to a merge decision, under 5 for the pre-merge portion. Beyond that the feedback loop is broken.
On this site the pipeline is short: there is nothing to unit test, so the fast lane is hugo --gc --minify succeeding, and the gate is a push to main. The stage ordering above is the shape the same repository would take once it had tests to run.

04System architecture

Four layers. Everything below the publish layer runs on GitHub-hosted infrastructure; nothing runs on a machine anybody owns.

Source
content/docs/ — Markdown pages across nine sections · static/diagrams/ — self-contained interactive HTML diagrams served as-is · assets/diagrams/ — images that pass through the theme's render hook · hugo.toml — baseURL, goldmark with unsafe = true, module import
Build
Hugo extended 0.161.1 installed from the release .deb, pinned by HUGO_VERSION · Go 1.22 present only so Hugo Modules can resolve the theme · Lotus Docs fetched as a Hugo Module, not vendored as a submodule · output written to ./public
Delivery
.github/workflows/hugo.yml — two jobs, build then deploy · permissions scoped to contents: read, pages: write, id-token: write · concurrency group pages serialises deploys · upload-pages-artifact@v3 hands ./public to deploy-pages@v4
Publish
GitHub Pages with source set to GitHub Actions · static/CNAME carries the custom domain into the artifact · DNS delegated to the registrar's nameservers, subdomain CNAME to the Pages host

05Features

Functional

  • Push to main publishes; no other trigger is required
  • workflow_dispatch for a manual rebuild without a content change
  • Mermaid diagrams rendered by the theme; richer diagrams embedded as standalone HTML
  • Raw HTML permitted in Markdown, so a diagram can be an <iframe> with no shortcode

Non-functional

  • Reproducible — every tool version pinned in the workflow, not floating
  • Serialised — one deploy at a time, and a running deploy is never cancelled
  • Least privilege — the token can read the repo and write Pages, nothing else
  • No credentials locally — publishing authority lives in the workflow's OIDC token

Known sharp edges

  • Omitting the Go step fails the build with go.mod file not found — the theme is a module
  • resources.Get in the theme's image hook reads assets/, never static/; an image in the wrong directory renders as nothing at all
  • fetch-depth: 0 is required for .GitInfo-derived dates

Deliberately absent

  • No staging environment — the artifact is static and the rollback is a revert
  • No link checker or HTML validation gate yet; it would belong post-merge, not blocking
  • No preview deployments per pull request

06Deployment

AspectDetail
ModelContinuous deployment. Every commit on main that builds is published; there is no release branch and no approval step.
Runnerubuntu-latest, GitHub-hosted. Two jobs: build produces the artifact, deploy consumes it via needs: build.
PrerequisitesPages source set to GitHub Actions in repository settings; a Go toolchain in the runner for module resolution; DNS CNAME for the custom domain.
Rollbackgit revert and push. Recovery time is one pipeline run, which is the argument for keeping the pipeline short.
Failure modeA failed build leaves the previously deployed site untouched — Pages only swaps once deploy-pages succeeds.
Blast radiusThe whole site, since it is one artifact. Acceptable because the content is static and the undo path is a commit.