Baseleg Docs
Reference · Decisions / 001 · Runtime and hosting · Baseleg Docs

ADR-001: Runtime and hosting

Date: 2026-04-28 Status: Accepted

Context

Baseleg needs a lightweight hosting model suited to a small team, with a Cloudflare-friendly runtime for the product app and a simple way to publish documentation.

Decision

  • The product app (apps/web) will target the Cloudflare runtime.
  • Documentation (apps/docs) will be published to GitHub Pages as a static site.

Consequences

  • Runtime-specific bindings (e.g. D1) are isolated to infrastructure and app wiring.
  • Docs publishing is decoupled from production deployments.

Alternatives considered

  • Single deployable for both app and docs (tighter coupling)
  • Other hosts/runtimes (would reduce alignment with D1/Workers)

Update (2026-08-21) — how deploys actually work

The original decision to publish apps/docs to GitHub Pages was never carried out. Discovered while building issue #49 (automating D1 migrations): both apps/web and apps/docs deploy via Cloudflare Pages’ own dashboard-configured GitHub integration — visible as the “Deploying base-leg-app/base-leg-docs with Cloudflare Pages” bot comments on every PR. This git integration triggers preview deploys on every branch/PR and a production deploy on every push to main, entirely outside this repo’s tracked GitHub Actions workflows.

This was undocumented and had to be reverse-engineered from evidence: .github/workflows/ deploy-app.yml (now renamed db-migrate-remote.yml) ran “successfully” on every merge to main for months while its only step was a literal echo "TODO: add Wrangler deploy step..." — yet the site demonstrably updated on every merge (that’s what caused the 2026-08-12 outage, PR #48: new code went live referencing a schema that was never migrated). Cloudflare Pages’ git integration is the only mechanism consistent with that evidence.

Consequence for CI: GitHub Actions does not deploy either app, and should not try to — db-migrate-remote.yml exists only to apply pending D1 migrations to production on push to main (the one real gap Pages’ deploy doesn’t cover), using CLOUDFLARE_API_TOKEN/ CLOUDFLARE_ACCOUNT_ID repo secrets scoped to Account > D1 > Edit only — no Pages/Workers deploy permission, since it never deploys anything.

Known residual risk, not solved: Pages’ deploy and db-migrate-remote.yml’s migration-apply are two independent systems reacting to the same push to main, with no ordering guarantee between them. In principle there’s a brief window where new code is live before its migration has applied — a much smaller version of the original incident (which was migrations never applying at all, not a sub-minute race). Closing this fully would mean either disabling Pages’ auto-deploy in favor of an Actions-orchestrated deploy+migrate sequence, or using a Cloudflare Pages Deploy Hook to sequence the two — out of scope for issue #49 (NON_GOALS explicitly excludes a multi-environment/orchestration pipeline); left as a known limitation.