diff --git a/AGENTS.md b/AGENTS.md index 6c6ea676e..580711718 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -6,7 +6,8 @@ - **Build**: `npm run build` - **Dev**: `npm run dev` - **Lint**: `npm run lint` -- **Check links**: `npm run check-links -- --check-anchors --check-self-links` (CI comments on PRs that break links; see `dev/check-links.mjs`; `next build` runs it without flags, so only dead page links fail a deploy). When moving a page or renaming a heading, update every link to it; a redirect in `src/data/redirects.ts` does not satisfy the check. Link to this site with relative paths (`/admin/config/site-config`), never `https://sourcegraph.com/docs/…` or `https://docs.sourcegraph.com/…`. To also probe the external links you added: `npm run check-links -- --check-anchors --check-self-links --check-external --diff <(git diff -U0 origin/main)` +- **Checks**: `npm run check` runs every `dev/check-*.mjs` (links, filenames, images); `npm run build` runs them first, so any finding fails a deploy +- **Check links**: `npm run check -- links --check-anchors --check-self-links` (CI comments on PRs that break links; see `dev/check-links.mjs`; the build runs it without flags, so only dead page links fail a deploy). When moving a page or renaming a heading, update every link to it; a redirect in `src/data/redirects.ts` does not satisfy the check. Link to this site with relative paths (`/admin/config/site-config`), never `https://sourcegraph.com/docs/…` or `https://docs.sourcegraph.com/…`. To also probe the external links you added: `npm run check -- links --check-anchors --check-self-links --check-external --diff <(git diff -U0 origin/main)` - **Prove changed links resolve on a deploy**: `node dev/verify-links-live.mjs --site ` prints a Markdown table for the PR description ## AI Chat Integration diff --git a/dev/checks.mjs b/dev/checks.mjs new file mode 100644 index 000000000..c947a9521 --- /dev/null +++ b/dev/checks.mjs @@ -0,0 +1,59 @@ +#!/usr/bin/env node + +/** + * Runs the docs checks in dev/check-*.mjs. `npm run build` runs them all + * before `next build`. + * + * Usage: node dev/checks.mjs [check ...] [flags] + * node dev/checks.mjs every check + * node dev/checks.mjs links filenames only those + * node dev/checks.mjs links --check-anchors flags go to that one check + * + * Every check runs even when an earlier one fails; exits 1 if any failed. + */ + +import {spawnSync} from 'child_process'; +import path from 'path'; +import {fileURLToPath} from 'url'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +const CHECKS = { + links: 'check-links.mjs', + filenames: 'check-filenames.mjs', + images: 'check-images.mjs' +}; + +const args = process.argv.slice(2); +const names = []; +while (args.length > 0 && CHECKS[args[0]]) { + names.push(args.shift()); +} +const flags = args; + +if (flags.length > 0 && !flags[0].startsWith('-')) { + console.error( + `Unknown check "${flags[0]}"; use ${Object.keys(CHECKS).join(', ')}` + ); + process.exit(1); +} +if (flags.length > 0 && names.length !== 1) { + console.error( + `Flags ${flags.join(' ')} need exactly one check to apply to` + ); + process.exit(1); +} + +const failed = []; +for (const name of names.length > 0 ? names : Object.keys(CHECKS)) { + const script = path.join(__dirname, CHECKS[name]); + const {status} = spawnSync(process.execPath, [script, ...flags], { + stdio: 'inherit' + }); + if (status !== 0) failed.push(name); +} + +if (failed.length > 0) { + console.error(`\n❌ Failed checks: ${failed.join(', ')}`); + process.exit(1); +} diff --git a/next.config.js b/next.config.js index 8e71169ab..caaefd0a2 100644 --- a/next.config.js +++ b/next.config.js @@ -1,5 +1,4 @@ const {withContentlayer} = require('next-contentlayer'); -const {execSync} = require('child_process'); /** @type {import('next').NextConfig} */ const nextConfig = { @@ -18,11 +17,4 @@ const nextConfig = { } }; -module.exports = async () => { - // placing this here so its part of nextjs's build process - execSync('node dev/check-links.mjs', {stdio: 'inherit'}); - execSync('node dev/check-filenames.mjs', {stdio: 'inherit'}); - execSync('node dev/check-images.mjs', {stdio: 'inherit'}); - execSync('node dev/generate-mermaid-icons.mjs', {stdio: 'inherit'}); - return withContentlayer(nextConfig); -}; +module.exports = withContentlayer(nextConfig); diff --git a/package.json b/package.json index 0649e4657..44114c96e 100644 --- a/package.json +++ b/package.json @@ -8,13 +8,11 @@ }, "scripts": { "dev": "next dev", - "build": "next build", + "build": "node dev/checks.mjs && node dev/generate-mermaid-icons.mjs && next build", "start": "next start", "lint": "next lint", - "check-links": "node dev/check-links.mjs", - "check-filenames": "node dev/check-filenames.mjs", - "check-images": "node dev/check-images.mjs", - "generate-mermaid-logos": "node dev/generate-aws-icons.mjs", + "check": "node dev/checks.mjs", + "generate-mermaid-logos": "node dev/generate-mermaid-icons.mjs", "format": "prettier --config ./prettier.config.js --cache --cache-strategy metadata --write=true '**/{*.{js?(on),ts?(x),md,mdx,s?css},.*.js?(on)}'" }, "browserslist": "defaults, not ie <= 11",