Skip to content

feat(docs): Docusaurus scaffold with two build profiles (B01) - #60

Open
profd2004 wants to merge 9 commits into
masterfrom
feat/b01-docusaurus-scaffold
Open

profd2004 wants to merge 9 commits into
masterfrom
feat/b01-docusaurus-scaffold

Conversation

@profd2004

@profd2004 profd2004 commented Sep 14, 2026 •

Copy link
Copy Markdown

Summary

The big idea is to put a Docusaurus skeleton in docs/ that builds two sites from one codebase: the fork's dev site under /cardano-db-sync/ against Cardano preview, and production at / for dbsync.cardano.intersect.org against mainnet. Everything in Phases 0 to 3 gets built inside this skeleton, so it goes in first.

The environment lives in exactly one file, docs/config/profiles.ts. DOCS_PROFILE=dev|prod picks a profile and resolveProfile() throws if it is missing or unknown, so a build cannot quietly choose one for you. The config, the CNAME plugin and the pages all read from the profile, and npm run check:baseurl walks the tree and fails on any environment literal that escaped it.

No design system here. The token pipeline is B42 and the drawn UI is B47, and KICKOFF §3 says not to invent a colour or a spacing value, so custom.css is empty and the landing page is plain HTML with a link.

Refs

Refs #2 (checklist item B01).

Traceability

ID Requirement Tests Commits
R1 ENV-1 - baseUrl is a variable at every use site, no hardcoded value outside the profile module test/unit/profiles.test.ts, test/unit/config.test.ts, test/unit/check-baseurl.test.ts, test/build/profiles.test.ts d68c4853, 2b9187a9, a18e6517
R2 ENV-6 - the Pages CNAME is emitted for production only; dev output carries none test/unit/cname.test.ts, test/build/profiles.test.ts d68c4853, 26c74192
R3 CON-9 - markdown.format stays at the mdx default, asserted and marked do-not-change test/unit/config.test.ts d68c4853
R4 Both profiles build clean from one working tree test/build/profiles.test.ts 26c74192
R5 A deliberately broken Markdown file fails the build test/build/markdown-gate.test.ts 26c74192
R6 Formatted, lint clean, tsc --noEmit clean, unit tested with coverage npm run verify 81014c09, 8d4f807c, 4d95b714
R7 ENV-5 - the site builds green with no secrets configured test/build/profiles.test.ts 26c74192

Decisions

  • repoUrl, organizationName and projectName are part of the profile. The edit-this-page link and the navbar GitHub link point at the fork on dev and at upstream on production. Same reasoning as baseUrl: the repository is environment-dependent, so it belongs in the profile, not in the config.
  • resolveProfile() throws instead of defaulting. A default is how a dev build ends up publishing to production's host. The npm scripts set the variable through cross-env, so nobody meets the error in normal use.
  • The ENV-1 gate exempts GitHub repository URLs. github.com/<org>/cardano-db-sync/... contains the repo name and none of those is a baseUrl. Content will link to the repository constantly, so the gate strips that URL from a line before the rules see it, and there is a test proving a real baseUrl on the same line is still caught.
  • A minimal CI workflow ships with this PR. B02 owns the full pipeline - link check, asset budget, the FLOOR-4 and PERF grep gates. This one is the subset B01's own DoD needs to be verified by CI rather than by me saying so, and B02 extends it rather than replacing it.
  • A placeholder landing page at /. With blog: false and docs under /docs, the root had no route and the broken-link check failed the build - correctly. The page is a React page under src/pages/ per CON-11, with no invented visual values.

Assumptions

  • Target is docs-rebuild-spec on this fork, not master. master still carries the Astro site and has no SPECIFICATION.md, so it is not a base this can sit on.
  • Content migration is out of scope. doc/ is untouched (D3) and docs/docs/ holds one seed page to prove the pipeline.

Blockers

None.

Verification

Run from docs/:

npm ci
npm run verify   # format:check, lint, typecheck, check:baseurl, test, test:build

Locally, on Node 24:

  • npm run format:check - clean
  • npm run lint - clean
  • npm run typecheck - clean
  • npm run check:baseurl - clean
  • npm test - 52 tests, coverage 99.31% lines / 100% functions
  • npm run test:build - 10 tests, both profiles built back to back from one tree

Two things the build tests check that a property dump would not: build/dev/ has no CNAME and build/prod/CNAME reads dbsync.cardano.intersect.org, and the dev HTML resolves assets through /cardano-db-sync/assets/ while production resolves them through /assets/.

Three findings from the review pass that are worth naming, because all three would have shipped as silent passes:

  • The broken-Markdown fixture was called __broken-markdown-fixture.md. Docusaurus treats a _-prefixed file as a partial and excludes it, so the build never read the file and the test proved nothing. Renamed, and the test now also asserts the fixture name appears in the failure output.
  • tsc --noEmit passed locally and failed in CI on the same commit. The gate's reporter parameter was inferred from its console default and the two environments resolved a different Console type. It is an explicit @typedef now.
  • The gate guarded the production host but not the developer one, so a hardcoded https://lidonation.github.io would have passed it.

Manual pipeline jobs a human still needs to trigger: none. The repo's existing Haskell CI runs on every push with no path filter, so it is also running on this docs-only branch; it is unrelated to this change.

Progress

  • Toolchain and project config
  • Profile-driven url, baseUrl and CNAME
  • ENV-1 gate
  • Build-level profile and Markdown-gate tests
  • CI workflow
  • Review findings closed

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Sep 14, 2026 •

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
❌ Deployment failed
View logs
cardano-db-sync-docs a18e651 Sep 14 2026, 08:51 AM

@profd2004
profd2004 marked this pull request as ready for review September 14, 2026 11:52
Replaces the removed Astro project with a Docusaurus 3 workspace under docs/: npm scripts for
the two build profiles, TypeScript in strict mode, eslint, prettier and vitest with coverage
thresholds.

Refs B01.
config/profiles.ts is the single origin for every environment-dependent value. The developer
profile publishes the fork to /cardano-db-sync/ against preview; production publishes at / against
mainnet. resolveProfile() throws rather than defaulting, so a build cannot silently pick the wrong
one (ENV-1).

The CNAME plugin writes the Pages CNAME from the profile in postBuild, and removes a stray one on
the developer profile, so the fork's site can never be sent to production's host (ENV-6).

markdown.format is deliberately left unset, which keeps Docusaurus at its mdx default; a unit test
fails if a format key appears in the config (CON-9).

Refs B01.
npm run check:baseurl walks the source, config and authored content and fails on a developer
baseUrl, a production host, or baseUrl assigned a string literal outside config/profiles.ts. A
GitHub repository URL legitimately contains the repository name, so it is exempted before the
rules run; eslint carries the same rule for TypeScript sources.

Refs B01, ENV-1.
Builds both profiles back to back from one working tree, asserts the developer output carries no
CNAME and production's holds the host, checks baseUrl reaches the emitted HTML under both, and
confirms a build succeeds with only DOCS_PROFILE in the environment (ENV-5).

The Markdown gate test writes a file MDX cannot compile and requires the build to fail. Its
filename must not start with an underscore: Docusaurus treats _*.md as a partial and excludes it,
which made the first version of this test pass against a build that had never read the file.

Refs B01.
Two jobs on changes under docs/: format, lint, types, the ENV-1 gate and unit tests; then both
build profiles with the CNAME and Markdown-gate assertions.

Refs B01.
…nsole

tsc --noEmit passed here and failed in CI on the same commit: inference took the parameter type
from the `console` default, and the two environments resolved a different `Console`. An explicit
@typedef removes the dependence on inference, so the contract is the two methods the gate actually
calls.

Refs B01.
The gate guarded the production host but not the developer one, so a hardcoded
https://lidonation.github.io would have passed. Same class of value, now the same rule.

organizationName and projectName were pinned to upstream. They are environment-dependent for the
same reason repoUrl is, so they come from the profile.

engines said node >=20.0, but the gate script uses import.meta.dirname, which landed in 20.11.

Refs B01, ENV-1.
@profd2004
profd2004 force-pushed the feat/b01-docusaurus-scaffold branch from a18e651 to 747627a Compare September 17, 2026 16:10
@profd2004
profd2004 changed the base branch from docs-rebuild-spec to master September 17, 2026 16:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant