Context

The site is built with a Hugo generator and a PaperMod theme. Untracked upgrades of either can change output silently: the theme’s templates, the generator’s rendering rules, or both can alter the HTML bytes between two “identical” rebuilds. When a release is proven by a byte manifest, reproducibility is not a nice-to-have; two builds of the same source must produce the same tree.

Decision

Vendor the theme into the repository and record the exact generator version and theme version in a pin file, data/upstream-pins.toml. The build pipeline reads that file and fails if the installed generator does not match the pinned version.

Hugo 0.165.0
PaperMod v8.0
data/upstream-pins.toml   (pinned)

Themes that are vendored stay under themes/ in the tree so they are part of the commit and therefore part of the byte identity of a release.

Consequences

  • Reproducible output: the same source plus the pinned generator yields the same tree, so the manifest means something.
  • Visible upgrades: bumping the theme or generator is an explicit, reviewable change to the pin file, not an accidental drift.
  • Auditable provenance: a reader of any release can see which generator and theme produced the bytes.
  • Trade-off accepted: the repository carries the vendored theme and the pin bookkeeping; the cost is small against silent output drift.

Why this wins

A build whose inputs are not pinned can produce the right answer today and a different tree tomorrow, and neither the diff nor the manifest can tell you why. Pinning turns “the build changed” into “the pin changed”, which is a question a changelog can actually answer.

Sources