From e970a5896e18eb2638c0464507f572ea41d099d7 Mon Sep 17 00:00:00 2001 From: Nikhil Kumar Rajak Date: Tue, 9 Jun 2026 17:59:30 +0000 Subject: [PATCH 1/4] feat: add governance docs fetcher under pages/contribute/governance --- .gitignore | 1 + package.json | 1 + pages/site.mjs | 2 + scripts/markdown/governance.mjs | 95 +++++++++++++++++++++++++++++++++ 4 files changed, 99 insertions(+) create mode 100644 scripts/markdown/governance.mjs diff --git a/.gitignore b/.gitignore index 77b103b6..e3e2c528 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ out /pages/loaders /pages/plugins /generated +/pages/contribute/governance diff --git a/package.json b/package.json index 2661be5f..7acf6292 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "build:md": "npm-run-all build:md:*", "build:md:api": "node scripts/markdown/api.mjs", "build:md:readmes": "node scripts/markdown/readmes.mjs", + "build:md:governance": "node scripts/markdown/governance.mjs", "build:html": "node scripts/html/index.mjs", "build": "npm-run-all build:*", "lint": "npm-run-all \"lint:!(fix)\"", diff --git a/pages/site.mjs b/pages/site.mjs index 0c6114c0..dce6ced2 100644 --- a/pages/site.mjs +++ b/pages/site.mjs @@ -1,6 +1,7 @@ import { sidebar as _sidebar } from './site.json' with { type: 'json' }; import loaders from './loaders/site.json' with { type: 'json' }; import plugins from './plugins/site.json' with { type: 'json' }; +import contribute from './contribute/governance/site.json' with { type: 'json' }; export * from './site.json' with { type: 'json' }; @@ -10,4 +11,5 @@ export const sidebar = [ groupName: 'Loaders & Plugins', items: [...loaders.sidebar, ...plugins.sidebar], }, + ...contribute.sidebar, ]; diff --git a/scripts/markdown/governance.mjs b/scripts/markdown/governance.mjs new file mode 100644 index 00000000..b558a0b1 --- /dev/null +++ b/scripts/markdown/governance.mjs @@ -0,0 +1,95 @@ +import { mkdir, writeFile } from 'node:fs/promises'; +import { join } from 'node:path'; + +const { GH_TOKEN } = process.env; + +const BASE_HEADERS = { + ...(GH_TOKEN && { Authorization: `Bearer ${GH_TOKEN}` }), +}; + +// Maps source filenames in webpack/governance repo to their output slug and sidebar label. +// Insertion order determines sidebar order, this could be changed as per need. +const FILE_MAP = { + 'README.md': { output: 'governance-overview', label: 'Governance Overview' }, + 'CHARTER.md': { output: 'charter', label: 'Charter' }, + 'MEMBER_EXPECTATIONS.md': { + output: 'member-expectations', + label: 'Member Expectations', + }, + 'MODERATION_POLICY.md': { + output: 'moderation-policy', + label: 'Moderation Policy', + }, + 'WORKING_GROUPS.md': { output: 'working-groups', label: 'Working Groups' }, + 'AI_POLICY.md': { output: 'ai-policy', label: 'AI Policy' }, +}; + +// Derived from FILE_MAP - stays in sync automatically if entries are added/removed. +const LINK_REWRITE_MAP = Object.fromEntries( + Object.entries(FILE_MAP).map(([source, { output }]) => [ + source, + `/contribute/governance/${output}`, + ]) +); + +// Rewrites relative cross-references between governance docs. +// Covers both inline [text](./FILE.md) and reference-style [label]: ./FILE.md. +// Negative lookaheads prevent rewriting absolute URLs that happen to end in a known filename. +const rewriteLinks = content => + content.replace( + /(\]\(|\]:\s*)(?!https?:\/\/)(?!\/)(\.\/)?([A-Z_]+\.md)/g, + (match, prefix, _dot, filename) => + LINK_REWRITE_MAP[filename] + ? `${prefix}${LINK_REWRITE_MAP[filename]}` + : match + ); + +const outputDir = join( + import.meta.dirname, + '..', + '..', + 'pages', + 'contribute', + 'governance' +); +await mkdir(outputDir, { recursive: true }); + +const results = await Promise.all( + Object.entries(FILE_MAP).map(async ([source, { output, label }]) => { + const url = `https://raw.githubusercontent.com/webpack/governance/HEAD/${source}`; + const res = await fetch(url, { headers: BASE_HEADERS }); + + if (!res.ok) { + console.error(`Failed: ${source} -> ${res.status} ${res.statusText}`); + return null; + } + + const content = `---\nsource: ${url}\n---\n\n${rewriteLinks(await res.text())}`; + await writeFile(join(outputDir, `${output}.md`), content, 'utf8'); + console.log(`Fetched: ${source} -> ${output}.md`); + return { output, label }; + }) +); + +const fetched = results.filter(Boolean); + +const siteJson = { + sidebar: [ + { + groupName: 'Governance', + items: fetched.map(({ output, label }) => ({ + link: `/contribute/governance/${output}`, + label, + })), + }, + ], +}; + +await writeFile( + join(outputDir, 'site.json'), + JSON.stringify(siteJson, null, 2) + '\n', + 'utf8' +); +console.log( + `Written: pages/contribute/governance/site.json (${fetched.length} pages)` +); From 14b2d9bef77e3fe33ce1d982e8cb2c62c85e00e3 Mon Sep 17 00:00:00 2001 From: Nikhil Kumar Rajak <145889151+ryzrr@users.noreply.github.com> Date: Wed, 10 Jun 2026 02:18:27 +0530 Subject: [PATCH 2/4] Update scripts/markdown/governance.mjs Co-authored-by: Aviv Keller --- scripts/markdown/governance.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/markdown/governance.mjs b/scripts/markdown/governance.mjs index b558a0b1..c2ef1220 100644 --- a/scripts/markdown/governance.mjs +++ b/scripts/markdown/governance.mjs @@ -10,7 +10,7 @@ const BASE_HEADERS = { // Maps source filenames in webpack/governance repo to their output slug and sidebar label. // Insertion order determines sidebar order, this could be changed as per need. const FILE_MAP = { - 'README.md': { output: 'governance-overview', label: 'Governance Overview' }, + 'README.md': { output: 'index', label: 'Governance Overview' }, 'CHARTER.md': { output: 'charter', label: 'Charter' }, 'MEMBER_EXPECTATIONS.md': { output: 'member-expectations', From d7e25dc2af2c88b97a01fd901918fecc7887ba9a Mon Sep 17 00:00:00 2001 From: Nikhil Kumar Rajak Date: Thu, 11 Jun 2026 14:22:38 +0000 Subject: [PATCH 3/4] move governance output to pages/about/governance --- .gitignore | 2 +- pages/site.mjs | 7 +++++-- scripts/markdown/governance.mjs | 8 ++++---- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index e3e2c528..3674bb9f 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,4 @@ out /pages/loaders /pages/plugins /generated -/pages/contribute/governance +/pages/about/governance diff --git a/pages/site.mjs b/pages/site.mjs index dce6ced2..5da7d15a 100644 --- a/pages/site.mjs +++ b/pages/site.mjs @@ -1,7 +1,7 @@ import { sidebar as _sidebar } from './site.json' with { type: 'json' }; import loaders from './loaders/site.json' with { type: 'json' }; import plugins from './plugins/site.json' with { type: 'json' }; -import contribute from './contribute/governance/site.json' with { type: 'json' }; +import contribute from './about/governance/site.json' with { type: 'json' }; export * from './site.json' with { type: 'json' }; @@ -11,5 +11,8 @@ export const sidebar = [ groupName: 'Loaders & Plugins', items: [...loaders.sidebar, ...plugins.sidebar], }, - ...contribute.sidebar, + { + groupName: 'About', + items: contribute.sidebar, + }, ]; diff --git a/scripts/markdown/governance.mjs b/scripts/markdown/governance.mjs index c2ef1220..38a48bcc 100644 --- a/scripts/markdown/governance.mjs +++ b/scripts/markdown/governance.mjs @@ -28,7 +28,7 @@ const FILE_MAP = { const LINK_REWRITE_MAP = Object.fromEntries( Object.entries(FILE_MAP).map(([source, { output }]) => [ source, - `/contribute/governance/${output}`, + `/about/governance/${output}`, ]) ); @@ -49,7 +49,7 @@ const outputDir = join( '..', '..', 'pages', - 'contribute', + 'about', 'governance' ); await mkdir(outputDir, { recursive: true }); @@ -78,7 +78,7 @@ const siteJson = { { groupName: 'Governance', items: fetched.map(({ output, label }) => ({ - link: `/contribute/governance/${output}`, + link: `/about/governance/${output}`, label, })), }, @@ -91,5 +91,5 @@ await writeFile( 'utf8' ); console.log( - `Written: pages/contribute/governance/site.json (${fetched.length} pages)` + `Written: pages/about/governance/site.json (${fetched.length} pages)` ); From d8924595125cad479b402bc85daf4d14d74fba2d Mon Sep 17 00:00:00 2001 From: Nikhil Kumar Rajak Date: Thu, 11 Jun 2026 15:16:49 +0000 Subject: [PATCH 4/4] use label instead of groupName for nested sidebar --- scripts/markdown/governance.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/markdown/governance.mjs b/scripts/markdown/governance.mjs index 38a48bcc..76644419 100644 --- a/scripts/markdown/governance.mjs +++ b/scripts/markdown/governance.mjs @@ -76,7 +76,7 @@ const fetched = results.filter(Boolean); const siteJson = { sidebar: [ { - groupName: 'Governance', + label: 'Governance', items: fetched.map(({ output, label }) => ({ link: `/about/governance/${output}`, label,