perf: build hygiene (conditional vendoring, CI GOGC, determinism gate, docs)#2034
Merged
Conversation
- prebuild/prestart re-vendored all Hugo modules on every build; mod:vendor now skips when _vendor/modules.txt is newer than go.mod and go.sum - the original unconditional behavior is preserved verbatim as mod:vendor:force and is used whenever the guard misses - CI is unaffected: clean checkouts have no _vendor, so the guard always misses there and vendoring runs exactly as before 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Netlify: GOGC added to [build.environment] in data/netlify.toml (the source read by the header generator) and the auto-generated netlify.toml regenerated via build:headers:prod; a second generator run is a no-op - GitHub Actions: GOGC=400 prepended to the build-command input of the reusable workflow, as a caller-level env block does not propagate into it - measured locally on the exampleSite build, GOGC=800 saved 6-7 CPU-seconds; 400 is the conservative pick as CI runners have less RAM - local defaults are intentionally unchanged 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- scripts/check-build-determinism.sh builds the exampleSite twice from scratch, verifies zero ERROR lines and the expected page counts (98 EN / 26 FR / 24 NL), then compares both trees with diff -rq - the only tolerated diffs are the pre-existing intermittent .Content race in RSS-embedded HTML (en/index.xml, en/docs/blocks/index.xml, en/tags/block/index.xml), accepted by the maintainer on 2026-07-15 - future performance PRs cite a green run of this one command as evidence that they do not change the generated site 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- caching resources/_gen is worth about 4x on cold runners (68.7 s to ~17 s measured on the exampleSite build) - the shared root resources/ directory serves both the theme build and the exampleSite build - the getresource 5-minute TTL adds network noise to isolated runs - document the conditional mod:vendor guard, mod:vendor:force, the CI GOGC setting, and the determinism gate for performance PRs 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
✅ Deploy Preview for gethinode-demo ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Collaborator
Author
|
Program summary: this PR is Chunk C of the build-time optimization program and is intentionally HELD for the maintainer. All gates passed (byte-diff vs stock, determinism harness green incl. an independently re-run pass, lint green, netlify.toml round-trip stable). Live register: https://github.com/gethinode/gethinode.com/blob/program/build-time-optimization/docs/superpowers/specs/2026-07-15-build-time-optimization-register.md (private repo — link for the maintainer). |
Collaborator
Author
|
🎉 This PR is included in version 3.2.6 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of the build-time optimization program (Chunk C). Four independent hygiene items, no change
to the generated site (byte-diff verified, see below).
1. Conditional module vendoring
prebuild/prestartpreviously ranrimraf _vendor && hugo mod vendoron every build andserver start.
mod:vendornow delegates toscripts/mod-vendor.cjs, which skips vendoring when_vendor/modules.txtis newer than bothgo.modandgo.sum, and otherwise runs the originalrimraf _vendor && hugo mod vendor(kept verbatim asmod:vendor:force)._vendor/, so the guard always missesand vendoring runs exactly as before. Same for Netlify (the resources plugin caches
resources/, not_vendor/).mod:updatestill re-vendors (it removes_vendor/first, andhugo mod get -utouchesgo.mod).npm run mod:vendor:forcere-vendors unconditionally.Vendor-skip evidence (second consecutive
npm run build:example):2. GOGC=400 for CI builds
Measured locally on the exampleSite build,
GOGC=800saved 6-7 CPU-seconds; 400 is theconservative pick as CI runners have less RAM. Local defaults are intentionally unchanged.
GOGC = "400"to[build.environment]indata/netlify.toml— the SOURCEthe header generator reads (
build:headers:prodrendersmod-csp'sindex.netlify.toml,which remarshals
site.Data.netlify). The auto-generated rootnetlify.tomlwas regeneratedand committed alongside; running the generator twice produces no further diff.
.github/workflows/lint-build.ymlonly calls the reusable workflowgethinode/.github/.github/workflows/lint-build.yml@v1, and anenv:block at the caller doesnot propagate into it.
GOGC=400is therefore prepended to each command in thebuild-commandinput. The reusable workflow runs the command with
shell: bashon all three OSes, so theenv-prefix syntax is portable.
3. Determinism gate
scripts/check-build-determinism.shbuilds the exampleSite twice from scratch(
hugo --gc --minify -s exampleSite,rm -rf exampleSite/publicbefore each), verifies zeroERROR lines and the expected page counts (98 EN / 26 FR / 24 NL) per build, then
diff -rqs thetwo trees. The only tolerated diffs are the pre-existing intermittent
.Contentrace inRSS-embedded HTML (accepted 2026-07-15):
en/index.xml,en/docs/blocks/index.xml,en/tags/block/index.xml. Anything else exits non-zero. Future perf PRs cite one command.4. CI caching documentation
Recorded in
CLAUDE.md(Build Performance and CI Caching):resources/_gencaching is worth ~4x on cold runners (68.7 s → ~17 s measured);resources/dir serves both the theme and the exampleSite build;getresource5-minute TTL adds network noise to isolated runs.Verification
npm run build:exampleoutput on this branch vs. stock (origin/main) is byte-identicalexcept the intended
GOGC = '400'line in the generatednetlify.tomlartifact (item 2) andthe RSS allowlist files above. Page counts 98/26/24, zero ERROR lines, on both.
scripts/check-build-determinism.shruns green on this branch.pnpm test(full lint suite) passes.pnpm build:headers:prodround-trip is stable: a second run after regeneration produces nofurther diff in
netlify.toml.🤖 Generated with Claude Code