docs: keep notices fresh at commit time instead of a new CI gate

Regenerate THIRD_PARTY_NOTICES.md from a pre-commit job whenever a
manifest, lock file, vendor manifest, or pyproject is staged, and assert
the committed bytes inside the generator spec the test lane already runs.
Drops the separate doc-sync gate: no extra CI process, and a dependency
edit no longer bounces back from CI to rerun a generator.
This commit is contained in:
ZiyaZhang
2026-07-30 07:56:13 -07:00
parent 19606bc331
commit 04c73df2f6
7 files changed
+40 -14

No files matched your search

+11 -1
View File
@@ -1,10 +1,20 @@
import { readFileSync } from 'node:fs'
import { resolve } from 'node:path'
import { describe, expect, it } from 'vitest'
import { type Manifest, parseVendoredRows, tierExternalDeps } from './gen-third-party-notices.ts'
import { type Manifest, parseVendoredRows, render, tierExternalDeps } from './gen-third-party-notices.ts'
const root = resolve(import.meta.dirname, '..')
describe('THIRD_PARTY_NOTICES.md', () => {
// Freshness lives here rather than in its own doc-sync gate: this spec file
// already runs in the test lane, so the check costs no extra CI process.
// Pre-commit regenerates the file whenever a manifest is staged, so reaching
// this assertion means the notices were committed without that hook.
it('matches what the generator produces from the current manifests', () => {
expect(readFileSync(resolve(root, 'THIRD_PARTY_NOTICES.md'), 'utf8'), 'stale notices — run `pnpm run gen-third-party-notices`').toBe(render())
})
})
/** Build the (manifests, names) pair `tierExternalDeps` consumes. */
function workspace(entries: Record<string, Manifest>): { manifests: Map<string, Manifest>; names: Set<string> } {
const manifests = new Map(Object.entries(entries))
+5 -2
View File
@@ -283,8 +283,11 @@ function renderNpmTable(deps: ExternalDep[]): string {
return lines.join('\n')
}
/** Render the complete notices document. */
function render(): string {
/**
* Render the complete notices document.
* @returns the exact bytes `THIRD_PARTY_NOTICES.md` must hold.
*/
export function render(): string {
verifyBuildTimePins()
const npm = collectNpmDeps()
const runtimeDeps = npm.filter(dep => dep.runtime)
-1
View File
@@ -472,7 +472,6 @@ function docSyncLeafGates(options: {
pnpmScript('tool-catalog', 'verify-tool-catalog', { label: 'tool catalog' }),
pnpmScript('config-catalog', 'verify-config-catalog', { label: 'config catalog' }),
pnpmScript('persistence-catalog', 'verify-persistence-catalog', { label: 'persistence catalog' }),
pnpmScript('third-party-notices', 'verify-third-party-notices', { label: 'third-party notices' }),
pnpmScript('doc-graphs', 'verify-doc-graphs', { label: 'doc graphs' }),
pnpmScript('scoped-events', 'verify-scoped-events', { label: 'scoped events' }),
pnpmScript('markdown-wrap', 'verify-md-wrap', { label: 'markdown wrap' }),