From 10ffb81aefded66b2654ffbf98af74e68f93d1f9 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Tue, 18 Aug 2026 22:20:28 -0400 Subject: [PATCH 1/7] npm scripts: inline lifecycle pre/post hooks into their parents --- docsy.dev/package.json | 15 +++++---------- package.json | 6 ++---- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/docsy.dev/package.json b/docsy.dev/package.json index 8e014eaba3..e483ddac53 100644 --- a/docsy.dev/package.json +++ b/docsy.dev/package.json @@ -16,23 +16,18 @@ "_serve": "npm run _hugo-dev -- serve --disableFastRender --renderToMemory", "_test:base": "npm run check:format && npm run _check:links", "_update:goldens": "npm run update:md-goldens && npm run update:favicon-goldens", - "build:preview": "cross-env npm run _hugo-dev -- --minify --baseURL \"${DEPLOY_PRIME_URL:-http://localhost}\"", - "build:production": "npm run _hugo -- --minify", + "build:preview": "cross-env npm run _hugo-dev -- --minify --baseURL \"${DEPLOY_PRIME_URL:-http://localhost}\" && npm run _postbuild", + "build:production": "npm run _hugo -- --minify && npm run _postbuild", "build": "cross-env npm run _build -- --baseURL \"${BASE_URL:-http://localhost}\"", "check:format": "npm run _check:format || (echo '[help] Run: npm run fix:format'; exit 1)", - "check:links:internal": "npm run _check:links -- --offline", - "check:links": "npm run _check:links --", + "check:links:internal": "npm run build && npm run _check:links -- --offline", + "check:links": "npm run build && npm run _check:links --", "clean": "rm -Rf public", "ccr": "cross-env HUGO_PARAMS_TD_CHROME=shared npm run", "fix:format": "npm run _check:format -- --write", "fix:refcache": "npm run check:links", "fix": "npm run fix:format", "make:public": "git init -b main public", - "postbuild:preview": "npm run _postbuild", - "postbuild:production": "npm run _postbuild", - "precheck:links:internal": "npm run build", - "precheck:links": "npm run build", - "preupdate:goldens": "npm run build", "refcache": "refcache", "seq": "bash -c 'for cmd in \"$@\"; do npm run $cmd || exit 1; done' - ", "serve": "npm run _serve -- --minify", @@ -45,7 +40,7 @@ "test": "npm run seq -- test:base test:extra", "update:dep": "npm run -s update:hugo", "update:favicon-goldens": "node tests/favicons/update-goldens.mjs", - "update:goldens": "npm run _update:goldens", + "update:goldens": "npm run build && npm run _update:goldens", "update:hugo": "npm install --save-exact -D hugo-extended@latest", "update:md-goldens": "node tests/md-output/update-goldens.mjs", "update:packages": "npm-check-updates -u" diff --git a/package.json b/package.json index 44c66bd454..f8907d3370 100644 --- a/package.json +++ b/package.json @@ -62,8 +62,6 @@ "install:browser": "node node_modules/puppeteer/install.mjs", "is:clean": "bash -c 'o=$(git status --porcelain -uall); echo \"$o\"; [ -z \"$o\" ]'", "post-update": "echo; echo 'IMPORTANT! Run the following in case the ScrollSpy patch needs to be updated:\n npm run _prepare'; echo", - "postupdate:dep": "npm run -s post-update", - "postupdate:packages": "npm run -s post-update", "refcache": "npm run -C docsy.dev refcache --", "seq": "bash -c 'for cmd in \"$@\"; do npm run $cmd || exit 1; done' - ", "serve": "npm run -C docsy.dev serve --", @@ -78,12 +76,12 @@ "test:visual": "node --test 'tests/visual/*.test.mjs'", "test:website": "npm run -C docsy.dev test", "test": "npm run fix-and-test", - "update:dep": "npm install --save-exact @fortawesome/fontawesome-free@latest bootstrap@latest", + "update:dep": "npm install --save-exact @fortawesome/fontawesome-free@latest bootstrap@latest && npm run -s post-update", "update:goldens": "npm run -C docsy.dev update:goldens && npm run update:markup-goldens", "update:markup-goldens": "node tests/fixture-site/update-markup-goldens.mjs", "update:packages:all": "npm run update:packages --workspaces --include-workspace-root", "update:packages:not-hugo": "npm run update:packages -- -x hugo-extended", - "update:packages": "npm-check-updates -u", + "update:packages": "npm-check-updates -u && npm run -s post-update", "update:visual-goldens": "UPDATE_VISUAL_GOLDENS=1 npm run test:visual", "update:visual-goldens:linux": "node tests/visual/update-goldens-linux.mjs", "wt": "HUGO_THEME=$(basename \"$PWD\")/theme npm run", From 99de2e263f1f714ec2cbf97108595cddacf33dd7 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Wed, 19 Aug 2026 07:05:18 -0400 Subject: [PATCH 2/7] Address review: extra-args routing, hook-sibling guard, changelog - Routes npm extra args past the inlined post-update step (otel.io bash -c form), fixing update:packages:not-hugo - Widens the hook-sibling test to every script in all three manifests - Adds the changelog "For maintainers" entry --- .../content/en/project/about/changelog.md | 4 ++ package.json | 2 +- tests/test-wiring.test.mjs | 52 ++++++++++--------- 3 files changed, 33 insertions(+), 25 deletions(-) diff --git a/docsy.dev/content/en/project/about/changelog.md b/docsy.dev/content/en/project/about/changelog.md index 7b57dc5ef2..7774ec937d 100644 --- a/docsy.dev/content/en/project/about/changelog.md +++ b/docsy.dev/content/en/project/about/changelog.md @@ -187,6 +187,9 @@ For the full list of changes, see the [0.16.1][] or [0.17.0][] release page. - Renamed the full test-suite entry point: `ci:test` → `test:full`, with `_test:full:pre`/`_test:full:common` phases; the freed `ci:*` names retire. A repo clone now installs via `npm run install:safe` ([#2712][]). +- Inlined npm `pre*`/`post*` run-hooks into their parent scripts, so + `check:links` still builds the site under user-level `ignore-scripts` + ([#2726][]). - Moved the default Mermaid version to `theme/hugo.yaml` `params.mermaid.version`, guarded by the repo test suite (`test:repo`). See [Default Mermaid version][mermaid-version-notes]. @@ -198,6 +201,7 @@ For the full list of changes, see the [0.16.1][] or [0.17.0][] release page. [#2712]: https://github.com/google/docsy/pull/2712 [#2714]: https://github.com/google/docsy/pull/2714 [#2724]: https://github.com/google/docsy/pull/2724 +[#2726]: https://github.com/google/docsy/pull/2726 [0.16.1]: https://github.com/google/docsy/releases/latest?FIXME=v0.16.1 [0.17.0]: https://github.com/google/docsy/releases/latest?FIXME=v0.17.0 [footer copyright docs]: /docs/content/lookandfeel/#footer-copyright diff --git a/package.json b/package.json index f8907d3370..0185587beb 100644 --- a/package.json +++ b/package.json @@ -81,7 +81,7 @@ "update:markup-goldens": "node tests/fixture-site/update-markup-goldens.mjs", "update:packages:all": "npm run update:packages --workspaces --include-workspace-root", "update:packages:not-hugo": "npm run update:packages -- -x hugo-extended", - "update:packages": "npm-check-updates -u && npm run -s post-update", + "update:packages": "bash -c 'npm-check-updates -u \"$@\" && npm run -s post-update' -", "update:visual-goldens": "UPDATE_VISUAL_GOLDENS=1 npm run test:visual", "update:visual-goldens:linux": "node tests/visual/update-goldens-linux.mjs", "wt": "HUGO_THEME=$(basename \"$PWD\")/theme npm run", diff --git a/tests/test-wiring.test.mjs b/tests/test-wiring.test.mjs index 5b85470117..6881c48ae9 100644 --- a/tests/test-wiring.test.mjs +++ b/tests/test-wiring.test.mjs @@ -156,30 +156,34 @@ test('manifests: own-suite scripts resolve their test files', () => { } }); -// npm wraps every script in implicit pre/post hooks: a hook -// sibling on a check-lane script runs unreviewed code inside the pinned CI -// chain — e.g. rewriting goldens in its own env before test:visual -// compares. Install-path hooks are the supply-chain audit's subject; these -// are check-execution. -test('manifests: check-lane scripts carry no lifecycle hook siblings', () => { - const { scripts } = JSON.parse( - fs.readFileSync(path.join(repoRoot, 'package.json'), 'utf8'), - ); - for (const name of [ - 'test:visual', - 'test:repo', - 'test:lychee', - 'is:clean', - 'update:visual-goldens', - 'update:visual-goldens:linux', - 'update:markup-goldens', - ]) { - for (const hook of [`pre${name}`, `post${name}`]) { - assert.equal( - scripts[hook], - undefined, - `${hook} stays absent, so ${name} runs exactly as pinned`, - ); +// npm wraps every `npm run S` in implicit preS/postS hooks: a double +// hazard. On a check-lane script, a hook sibling runs unreviewed code +// inside the pinned CI chain — e.g. rewriting goldens in its own env +// before test:visual compares. And under user-level ignore-scripts +// (which suppresses run-hooks but not the script itself), a hook step +// silently drops — precheck:links once skipped the site build, false- +// greening the link check. Steps are inlined into their parents instead +// (#2726); this scan keeps hook siblings out of every workspace +// manifest. (Install-path hooks are the supply-chain audit's subject.) +test('manifests: no script has a lifecycle hook sibling', () => { + const manifests = [ + 'package.json', + 'docsy.dev/package.json', + 'theme/package.json', + ]; + for (const manifest of manifests) { + const { scripts } = JSON.parse( + fs.readFileSync(path.join(repoRoot, manifest), 'utf8'), + ); + const names = Object.keys(scripts); + assert.ok(names.length > 0, `${manifest} declares scripts`); + for (const name of names) { + for (const hook of [`pre${name}`, `post${name}`]) { + assert.ok( + !names.includes(hook), + `${manifest}: ${hook} stays absent, so ${name} runs exactly as pinned`, + ); + } } } }); From cf2f84856b5ae274919a795143e164fb5ab413fc Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Wed, 19 Aug 2026 07:11:41 -0400 Subject: [PATCH 3/7] Add refcache entry for the new changelog link --- docsy.dev/.lycheecache | 1 + 1 file changed, 1 insertion(+) diff --git a/docsy.dev/.lycheecache b/docsy.dev/.lycheecache index 8f9e452dee..d5c5bdae4e 100644 --- a/docsy.dev/.lycheecache +++ b/docsy.dev/.lycheecache @@ -523,6 +523,7 @@ https://github.com/google/docsy/pull/2700,200,1786106543 https://github.com/google/docsy/pull/2712,200,1786305687 https://github.com/google/docsy/pull/2714,200,1786628621 https://github.com/google/docsy/pull/2724,200,1787076569 +https://github.com/google/docsy/pull/2726,200,1787137876 https://github.com/google/docsy/pull/941,200,1782498225 https://github.com/google/docsy/pulls,200,1782563369 https://github.com/google/docsy/releases,200,1782563368 From 7e2d39a3f2094bbd01281fce793d7fe0a33ab4d6 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Wed, 19 Aug 2026 07:22:49 -0400 Subject: [PATCH 4/7] Simplify update:packages arg routing; trim guard-test comment - Replaces the bash -c arg-passthrough with the repo's underscore-payload idiom: :not-hugo puts its flag on _update:packages directly --- package.json | 5 +++-- tests/test-wiring.test.mjs | 11 ++--------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index 0185587beb..1b125bde01 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "_test:fix-clean": "npm run fix-for-test && npm run -s is:clean", "_test:full:common": "npm run _test:fix-clean && npm run test:repo", "_test:full:pre": "npm run _prepare && npm run -s is:clean", + "_update:packages": "npm-check-updates -u", "build": "npm run -C docsy.dev build --", "check:afdocs:dev": "npm run -s _check:afdocs -- http://localhost:1313 | tee docsy.dev/content/en/docs/content/agent-support/afdocs-scorecard.txt", "check:format": "npm list prettier && npm run _check:format || (echo '[help] Run: npm run fix:format'; exit 1)", @@ -80,8 +81,8 @@ "update:goldens": "npm run -C docsy.dev update:goldens && npm run update:markup-goldens", "update:markup-goldens": "node tests/fixture-site/update-markup-goldens.mjs", "update:packages:all": "npm run update:packages --workspaces --include-workspace-root", - "update:packages:not-hugo": "npm run update:packages -- -x hugo-extended", - "update:packages": "bash -c 'npm-check-updates -u \"$@\" && npm run -s post-update' -", + "update:packages:not-hugo": "npm run _update:packages -- -x hugo-extended && npm run -s post-update", + "update:packages": "npm run _update:packages && npm run -s post-update", "update:visual-goldens": "UPDATE_VISUAL_GOLDENS=1 npm run test:visual", "update:visual-goldens:linux": "node tests/visual/update-goldens-linux.mjs", "wt": "HUGO_THEME=$(basename \"$PWD\")/theme npm run", diff --git a/tests/test-wiring.test.mjs b/tests/test-wiring.test.mjs index 6881c48ae9..083ed58c82 100644 --- a/tests/test-wiring.test.mjs +++ b/tests/test-wiring.test.mjs @@ -156,15 +156,8 @@ test('manifests: own-suite scripts resolve their test files', () => { } }); -// npm wraps every `npm run S` in implicit preS/postS hooks: a double -// hazard. On a check-lane script, a hook sibling runs unreviewed code -// inside the pinned CI chain — e.g. rewriting goldens in its own env -// before test:visual compares. And under user-level ignore-scripts -// (which suppresses run-hooks but not the script itself), a hook step -// silently drops — precheck:links once skipped the site build, false- -// greening the link check. Steps are inlined into their parents instead -// (#2726); this scan keeps hook siblings out of every workspace -// manifest. (Install-path hooks are the supply-chain audit's subject.) +// Hook siblings silently drop under ignore-scripts and splice unreviewed +// steps into check chains; parents inline their steps instead (#2726). test('manifests: no script has a lifecycle hook sibling', () => { const manifests = [ 'package.json', From 8a257110c4bed259cad9a3a2311641e72217b35a Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Wed, 19 Aug 2026 07:26:28 -0400 Subject: [PATCH 5/7] Restore update:packages argument wrapper --- package.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 1b125bde01..0185587beb 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,6 @@ "_test:fix-clean": "npm run fix-for-test && npm run -s is:clean", "_test:full:common": "npm run _test:fix-clean && npm run test:repo", "_test:full:pre": "npm run _prepare && npm run -s is:clean", - "_update:packages": "npm-check-updates -u", "build": "npm run -C docsy.dev build --", "check:afdocs:dev": "npm run -s _check:afdocs -- http://localhost:1313 | tee docsy.dev/content/en/docs/content/agent-support/afdocs-scorecard.txt", "check:format": "npm list prettier && npm run _check:format || (echo '[help] Run: npm run fix:format'; exit 1)", @@ -81,8 +80,8 @@ "update:goldens": "npm run -C docsy.dev update:goldens && npm run update:markup-goldens", "update:markup-goldens": "node tests/fixture-site/update-markup-goldens.mjs", "update:packages:all": "npm run update:packages --workspaces --include-workspace-root", - "update:packages:not-hugo": "npm run _update:packages -- -x hugo-extended && npm run -s post-update", - "update:packages": "npm run _update:packages && npm run -s post-update", + "update:packages:not-hugo": "npm run update:packages -- -x hugo-extended", + "update:packages": "bash -c 'npm-check-updates -u \"$@\" && npm run -s post-update' -", "update:visual-goldens": "UPDATE_VISUAL_GOLDENS=1 npm run test:visual", "update:visual-goldens:linux": "node tests/visual/update-goldens-linux.mjs", "wt": "HUGO_THEME=$(basename \"$PWD\")/theme npm run", From 4aa46b54de4461690bc117869f6796fe7d1e6273 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Wed, 19 Aug 2026 07:31:47 -0400 Subject: [PATCH 6/7] Drop redundant lifecycle-hook guard comment --- tests/test-wiring.test.mjs | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/test-wiring.test.mjs b/tests/test-wiring.test.mjs index 083ed58c82..08cbd43228 100644 --- a/tests/test-wiring.test.mjs +++ b/tests/test-wiring.test.mjs @@ -156,8 +156,6 @@ test('manifests: own-suite scripts resolve their test files', () => { } }); -// Hook siblings silently drop under ignore-scripts and splice unreviewed -// steps into check chains; parents inline their steps instead (#2726). test('manifests: no script has a lifecycle hook sibling', () => { const manifests = [ 'package.json', From cb0e90e9bb454e791f1742707917906386ef7bc2 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Wed, 19 Aug 2026 07:37:43 -0400 Subject: [PATCH 7/7] Rename update post-step for explicit chaining --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 0185587beb..775545f7ba 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,6 @@ "install:theme-deps": "npm ci --prefix theme --ignore-scripts --omit=dev --omit=peer --no-audit --no-fund", "install:browser": "node node_modules/puppeteer/install.mjs", "is:clean": "bash -c 'o=$(git status --porcelain -uall); echo \"$o\"; [ -z \"$o\" ]'", - "post-update": "echo; echo 'IMPORTANT! Run the following in case the ScrollSpy patch needs to be updated:\n npm run _prepare'; echo", "refcache": "npm run -C docsy.dev refcache --", "seq": "bash -c 'for cmd in \"$@\"; do npm run $cmd || exit 1; done' - ", "serve": "npm run -C docsy.dev serve --", @@ -76,12 +75,13 @@ "test:visual": "node --test 'tests/visual/*.test.mjs'", "test:website": "npm run -C docsy.dev test", "test": "npm run fix-and-test", - "update:dep": "npm install --save-exact @fortawesome/fontawesome-free@latest bootstrap@latest && npm run -s post-update", + "update::post": "echo; echo 'IMPORTANT! Run the following in case the ScrollSpy patch needs to be updated:\n npm run _prepare'; echo", + "update:dep": "npm install --save-exact @fortawesome/fontawesome-free@latest bootstrap@latest && npm run -s update::post", "update:goldens": "npm run -C docsy.dev update:goldens && npm run update:markup-goldens", "update:markup-goldens": "node tests/fixture-site/update-markup-goldens.mjs", "update:packages:all": "npm run update:packages --workspaces --include-workspace-root", "update:packages:not-hugo": "npm run update:packages -- -x hugo-extended", - "update:packages": "bash -c 'npm-check-updates -u \"$@\" && npm run -s post-update' -", + "update:packages": "bash -c 'npm-check-updates -u \"$@\" && npm run -s update::post' -", "update:visual-goldens": "UPDATE_VISUAL_GOLDENS=1 npm run test:visual", "update:visual-goldens:linux": "node tests/visual/update-goldens-linux.mjs", "wt": "HUGO_THEME=$(basename \"$PWD\")/theme npm run",