diff --git a/AGENTS.md b/AGENTS.md index 33757e1a4..49b324c16 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -3,6 +3,7 @@ ## Frontend - The Vercel app lives in `site/`. +- Vercel is configured by `site/vercel.json`; preview builds skip full docs prerendering, and the ignored build step skips builds unless `site/` or `docs/` changed. - Use Aura Dark from `daltonmenezes/aura-theme` for frontend dark mode and code surfaces. Core palette: background `#15141b`, foreground `#edecee`, muted `#6d6d6d`, purple `#a277ff`, green `#61ffca`, orange `#ffca85`, pink `#f694ff`, blue `#82e2ff`, red `#ff6767`. - Keep docs syntax highlighting aligned with the Aura Dark palette. - Use Node 22 for local site commands: `PATH="$HOME/.nvm/versions/node/v22.19.0/bin:$PATH" npm --prefix site run build`. diff --git a/site/README.md b/site/README.md index 8b18c034a..8813793f1 100644 --- a/site/README.md +++ b/site/README.md @@ -57,12 +57,23 @@ Recommended project settings: ```text Framework Preset: Next.js Root Directory: site -Build Command: default +Build Command: checked in via `site/vercel.json` Output Directory: default Install Command: default +Ignored Build Step: node scripts/ignore-build.mjs Production Branch: the integrator-approved trunk branch ``` +The Vercel build command is checked in via `site/vercel.json`. Preview builds +set `GRAPH_SITTER_PRERENDER_DOCS=0`, so the docs route renders pages on demand +instead of prerendering every MD/MDX page during deployment. Production and +local `npm run build` builds still prerender the full docs tree. + +The ignored build step is also checked in via `site/vercel.json`. It skips +Vercel builds when a commit does not change `site/` or `docs/`, using +`VERCEL_GIT_PREVIOUS_SHA` when Vercel exposes system environment variables and +falling back to `HEAD^` otherwise. + From an authenticated Vercel CLI session: ```bash diff --git a/site/app/docs/[[...slug]]/page.tsx b/site/app/docs/[[...slug]]/page.tsx index aaf74f202..c6a0a2665 100644 --- a/site/app/docs/[[...slug]]/page.tsx +++ b/site/app/docs/[[...slug]]/page.tsx @@ -35,10 +35,10 @@ type DocsPageProps = { }>; }; -export const dynamicParams = false; +const shouldPrerenderDocs = process.env.GRAPH_SITTER_PRERENDER_DOCS !== "0"; export function generateStaticParams() { - return getDocsStaticParams(); + return shouldPrerenderDocs ? getDocsStaticParams() : []; } export async function generateMetadata({ diff --git a/site/next.config.mjs b/site/next.config.mjs index 3ac4834bd..0ec6af4c0 100644 --- a/site/next.config.mjs +++ b/site/next.config.mjs @@ -6,6 +6,9 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url)); /** @type {import('next').NextConfig} */ const nextConfig = { outputFileTracingRoot: path.join(__dirname, ".."), + outputFileTracingIncludes: { + "/docs/\\[\\[\\.\\.\\.slug\\]\\]": ["../docs/**/*"], + }, }; export default nextConfig; diff --git a/site/scripts/ignore-build.mjs b/site/scripts/ignore-build.mjs new file mode 100644 index 000000000..3e5b0d6f3 --- /dev/null +++ b/site/scripts/ignore-build.mjs @@ -0,0 +1,57 @@ +import { spawnSync } from "node:child_process"; + +const watchedPaths = [":/site", ":/docs"]; +const currentRef = process.env.VERCEL_GIT_COMMIT_SHA || "HEAD"; +const previousRef = process.env.VERCEL_GIT_PREVIOUS_SHA; + +if (isTruthy(process.env.VERCEL_FORCE_BUILD)) { + console.log("Vercel build forced by VERCEL_FORCE_BUILD."); + process.exit(1); +} + +const baseRef = pickBaseRef(previousRef); +if (!baseRef) { + console.log("No previous git ref found; running the Vercel build."); + process.exit(1); +} + +const diff = spawnSync( + "git", + ["diff", "--quiet", baseRef, currentRef, "--", ...watchedPaths], + { stdio: "inherit" }, +); + +if (diff.status === 0) { + console.log(`No site/docs changes since ${baseRef}; skipping Vercel build.`); + process.exit(0); +} + +if (diff.status === 1) { + console.log( + `Detected site/docs changes since ${baseRef}; running Vercel build.`, + ); + process.exit(1); +} + +console.log("Could not evaluate site/docs diff; running Vercel build."); +process.exit(1); + +function pickBaseRef(ref) { + if (ref && hasCommit(ref)) { + return ref; + } + + return hasCommit("HEAD^") ? "HEAD^" : undefined; +} + +function hasCommit(ref) { + const result = spawnSync("git", ["cat-file", "-e", `${ref}^{commit}`], { + stdio: "ignore", + }); + + return result.status === 0; +} + +function isTruthy(value) { + return /^(1|true|yes)$/iu.test(value ?? ""); +} diff --git a/site/vercel.json b/site/vercel.json index fa1e26387..d2694a033 100644 --- a/site/vercel.json +++ b/site/vercel.json @@ -1,5 +1,6 @@ { "$schema": "https://openapi.vercel.sh/vercel.json", + "buildCommand": "if [ \"$VERCEL_ENV\" = \"production\" ]; then npm run build; else GRAPH_SITTER_PRERENDER_DOCS=0 npm run build; fi", "framework": "nextjs", - "ignoreCommand": "git diff --quiet HEAD^ HEAD -- :/site :/docs" + "ignoreCommand": "node scripts/ignore-build.mjs" }