diff --git a/.husky/pre-commit b/.husky/pre-commit index 5ee7abd8..53b48197 100644 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1 +1,2 @@ pnpm exec lint-staged +pnpm run check:secrets diff --git a/docs/agents/build-pipeline.md b/docs/agents/build-pipeline.md index 832b3d1a..65774e47 100644 --- a/docs/agents/build-pipeline.md +++ b/docs/agents/build-pipeline.md @@ -40,7 +40,7 @@ Production `ETHERPAD_DOMAIN` is ``. Only `` actual | Var | Effect | | ------------------------- | ----------------------------------------------------------------------------------------------------------------- | -| `ETHERPAD_DOMAIN` | Host to fetch pads from. Required. `` in prod, `` locally if you want real content. | +| `ETHERPAD_DOMAIN` | Host to fetch pads from. Required. `` in prod, `` locally if you want real content. | | `RENDER` | Set by Render automatically. Triggers in-memory caching paths instead of disk. | | `FILE_SYSTEM_CACHE=false` | Manual override to disable disk caches when developing locally. Useful for snapshot regeneration after pad edits. | diff --git a/docs/agents/debugging-stale-content.md b/docs/agents/debugging-stale-content.md index e70cc8aa..9a04e2ca 100644 --- a/docs/agents/debugging-stale-content.md +++ b/docs/agents/debugging-stale-content.md @@ -16,7 +16,7 @@ There are at least seven places content can be stale. Cheapest checks first. | 4 | Render build cache: `.cache/parsed-markdown/` | inside the build container | keyed on markdown content hash, busts naturally on pad edits — safe | | 5 | `node-fetch-cache` | local disk only | bypassed when `RENDER=true` (see `src/lib/fetchPost.ts`) | | 6 | Astro image cache (`node_modules/.astro/assets/*.json`) | local + Render `node_modules` cache | extended weekly by `scripts/image-cache.mjs`. Only affects images | -| 7 | Etherpad export endpoint | | no cache headers as of last check — fresh per request | +| 7 | Etherpad export endpoint | | no cache headers as of last check — fresh per request | ## Decision tree diff --git a/package.json b/package.json index a164cbfc..25cfb2d7 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "scripts": { "dev": "astro dev", "start": "astro dev", + "prebuild": "[ -z \"$RENDER\" ] || pnpm install --frozen-lockfile", "build": "node ./scripts/image-cache.mjs && astro build", "preview": "astro preview", "astro": "astro", @@ -17,6 +18,7 @@ "test:snapshot:update": "vitest --config ./vitest.snapshot.config.ts --update", "cache:clear": "rm -rf .cache && rm -rf node_modules/.astro", "check": "astro check", + "check:secrets": "tsx ./scripts/check-no-etherpad-domain.ts", "check:ts": "tsc --noEmit", "lint": "eslint .", "format": "prettier --write .", diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index b3b33f8d..1861e842 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -3,3 +3,4 @@ packages: onlyBuiltDependencies: - expost + - pixelteer diff --git a/render.yaml b/render.yaml index b0bcbb56..d6d3121b 100644 --- a/render.yaml +++ b/render.yaml @@ -2,7 +2,7 @@ services: - type: web name: beeblog env: static - buildCommand: pnpm run build + buildCommand: pnpm install --frozen-lockfile && pnpm run build staticPublishPath: ./dist pullRequestPreviewsEnabled: true routes: diff --git a/scripts/check-no-etherpad-domain.ts b/scripts/check-no-etherpad-domain.ts new file mode 100644 index 00000000..f9a45571 --- /dev/null +++ b/scripts/check-no-etherpad-domain.ts @@ -0,0 +1,44 @@ +import "dotenv/config"; +import { spawnSync } from "node:child_process"; + +const domain = process.env.ETHERPAD_DOMAIN; + +if (!domain) { + console.error( + "pre-commit: ETHERPAD_DOMAIN is unset and not found in .env.\n" + + "Set it (e.g. in .env) so this hook can verify no staged file " + + "contains the value.", + ); + process.exit(1); +} + +const result = spawnSync( + "git", + [ + "grep", + "--cached", + "-n", + "-F", + domain, + "--", + ":!.env", + ":!.env.*", + ":!scripts/check-no-etherpad-domain.ts", + ], + { encoding: "utf8" }, +); + +// git grep exits 0 on match, 1 on no match, >1 on error. +if (result.status === 0 && result.stdout) { + console.error("pre-commit: ETHERPAD_DOMAIN value found in staged content:"); + console.error(result.stdout.trimEnd()); + console.error( + "\nRefusing to commit. Remove the literal value before committing.", + ); + process.exit(1); +} + +if (result.status !== null && result.status > 1) { + console.error("pre-commit: git grep failed:", result.stderr.trim()); + process.exit(result.status); +}