Repository navigation
Docs builds, tests, publishes and deploys from iterate/docs - #1
Conversation
The tree main holds, Docs' two packages as iterate/private had them, made to stand alone: - A pnpm workspace of packages/docs and packages/docs-app, with iterate/private's catalog versions, pnpm settings and zod patch. `iterate` comes from npm (a main build). - The app's UI from the shadcn registry: shadcn's components, and iterate's (the app shell, PostHog, the stream link) as iterate's packages/ui has them. The few packages/ui/src/apps and packages/shared files it used are copied to src/app, each naming where it came from. - envs.ts and the app's vite.config.ts and scripts/app.ts: the same Worker config iterate deploys (preview on the dev account, prd at docs.iterate.workers.dev), cut down from iterate's start-app.ts the way iterate/kit's was. - CI on Depot (typecheck, lint, format, tests, the app's build) and main's deploy (preview, then prd, paging #error-pulse when red); pkg.pr.new and npm publishing on GitHub Actions, as iterate/private does. - @iterate-com/docs points agents at its guide on iterate/docs, and the Docs app installs this repo's pkg.pr.new builds for a per-commit deployment. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
commit: |
PR SummaryMedium Risk Overview CI, publishing and deploy automation Docs app de-monolithing and UI copies Behavioral tweaks tied to the split Reviewed by Cursor Bugbot for commit 2cf1c08. Bugbot is set up for automated code reviews on this repo. Configure here. |
… has Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…on preview before prd (#2) Docs' browser specs move here from iterate/private (whose half, iterate/private#215, deletes them), and gate what ships: every pull request gets its own Docs Worker and the specs against it, and main runs them against `preview` before it deploys prd. Stacked on #1. ```sh # by hand, against any Docs Worker on main on dev's platform doppler run --project os --config preview -- env WORKER_BASE_URL=https://os.iterate-dev-preview.workers.dev \ DOCS_BASE_URL=https://docs-pr2.iterate-dev-preview.workers.dev pnpm spec ``` ## Change / Purpose | Change | Purpose | | --- | --- | | `test/playwright/docs/*.spec.ts` | iterate/private's seven Docs specs, byte for byte, at the same paths. | | `test/playwright/docs/support.ts`, `test/helpers/proxied-app-route.ts` | The specs' setup: the project's `docs` route to the Worker under test, and @iterate-com/docs installed at this repo's pkg.pr.new build of the commit (it was iterate/private's). `proxiedAppRoute` is copied from iterate's preview tooling, the one thing support.ts used from it. | | `test/helpers/{test,forged-session,operator,screenshot,auth-config,worker-base-url,fake-ai,fixture-slug,slugify}.ts` | The part of iterate/private's spec harness the specs use, each naming where it came from; the only edits are imports and `appOrigin`'s app list. | | `test/playwright/global-setup.ts` | Replaces iterate's, which read any of its platforms from its envs.ts and core/os's config parser. This one knows two: a local platform (iterate's `pnpm dev`) and main on dev, whose admin bearer, password and secrets key come from Doppler `os/preview`. | | `test/playwright.config.ts`, `test/package.json`, `test/tsconfig.json`, root `spec` script, `pnpm-workspace.yaml` | iterate's config cut down to the `docs` and `docs-phone` projects, with its e2e policy's timeouts and one CI retry written out; `test` is a workspace package. | | `envs.ts` `pullRequestEnv`, `packages/docs-app/vite.config.ts` | `pr<N>` is a deployment: `docs-pr<N>` on the dev account, linked as `preview`. Its `pkgPrNewRef` is the PR head (`PUBLISHED_PACKAGE_COMMIT`), so "Install Docs" there installs the PR's own processors. | | `packages/docs-app/scripts/app.ts` `delete-pull-request` | Deletes `docs-pr<N>`, and only that: a 404 is fine. `force=true`, as Cloudflare refuses to delete a Worker that defines a Durable Object (`BrowserSession`) without it. | | `.depot/workflows/specs.yml` | On every PR: deploy `docs-pr<N>`, then the specs against it (6 browsers on a 4-vCPU runner), the report uploaded on failure. | | `.depot/workflows/pull-request-closed.yml` | Deletes the PR's Worker on close, after its specs run settles (shared concurrency group), with main's code: a head whose install broke still cleans up, and no PR code runs with the Doppler token. Depot registers the `closed` trigger once the file is on main. | | `.depot/workflows/deploy.yml` | Main: `preview`, then the specs against it, then `prd`. A red spec run stops prd and pages. | | `README.md`, `AGENTS.md`, `packages/docs-app/README.md`, `.gitignore` | How to run them, and `test-results/` ignored. | ## Risk map - **Main on dev is shared**: the specs make fixture projects on os.iterate-dev-preview.workers.dev, which iterate/private's main redeploys on every push and resets nightly. A red iterate/private main can redden Docs' specs here. That is the coupling Docs already had, in the other direction; the report says which. - **Main's specs wait for pkg.pr.new**: `support.ts` polls up to two minutes for the commit's build. pkg-pr-new.yml runs beside Deploy and takes about a minute. - **The closed trigger** only works from main, so this PR's own `docs-pr2` stays until it closes after merging (or `pnpm --dir packages/docs-app delete-pull-request --pr 2`). - Review order: `specs.yml`, `deploy.yml`, `test/playwright/global-setup.ts`, `envs.ts`, `vite.config.ts`, `scripts/app.ts`; the copied helpers and specs last. ## Evidence - From this branch, against #1's build on a throwaway Worker on the dev account, installing #1's pkg.pr.new build: `10 passed (50.2s)`, all eight specs and the two phone runs. - This PR's own **Specs** run on Depot: `docs-pr2` deployed (installing this head's build), then `10 passed (1.1m)` against it. CI, pkg.pr.new and Continuous Releases green; npm / check red as on #1. Claude Code session: `local_cdd673f8-107f-4d2f-8087-ac4278554ee1` ("iterate/docs repo") 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Docs builds, tests, publishes and deploys from iterate/docs, with nothing from iterate's monorepo but published packages. Main already holds Docs' history (56 commits, see "History" below). This PR is the one commit that makes that tree stand alone, as iterate/kit#1 did for Kit.
Its other half removes Docs from iterate/private (linked once open). The cutover order is at the end.
What changes for people
Nothing, once both halves land: the same Workers (
docsat docs.iterate.workers.dev, which the iterate project'sdocsslug and docs.iterate.com route to, anddocsat docs.iterate-dev-preview.workers.dev), the sameITERATE_APP, the same package name. What moves:Change / Purpose
package.json,pnpm-workspace.yaml,pnpm-lock.yaml,patches/zod@4.6.5.patch,tsconfig.{base,app}.json,.nvmrccatalog:in the packages' manifests stays as it was.iterateis npm's0.4.1-main.20261105T063432Z-a81a857(iterate/private's main today), let past the one-day release age like the Cloudflare toolchain. zod's patch (a ZodError's message across Durable Object RPC) comes along, as Kit's did.packages/docs-app/src/components/**,src/hooks/use-mobile.ts,src/lib/plain-left-click.ts,src/styles/{globals,iterate,tokens}.css,components.json@iterate-com/uiin the workspace. Its npm build bundles React for no-build pages, so a Start app can't use it; the app takes the components from the shadcn registry instead, like Kit: shadcn'sbase-novaones and iterate/packages'project-app-shell,stream-link,posthog,first-project-redirect,environment-head-content,route-defaultsand their dependencies, each file byte-identical to iterate's packages/ui.packages/docs-app/src/app/*packages/ui/src/appsfiles (base path, document, head, providers, router, server) and twopackages/sharedones (ITERATE_APP's schema, the PostHog proxy) the app imported, copied with a header naming where from.packages/docs-app/src/**imports@iterate-com/ui/…and@iterate-com/shared/…become#/components/…and#/app/…. No other change to what the app does.envs.ts,packages/docs-app/vite.config.ts,packages/docs-app/scripts/app.tsstartAppWorkerConfigwrote for Docs, cut down the way Kit's was: same name, account, bindings, compatibility date, observability,run_worker_firstandITERATE_APP(every link,denyZonescopied from iterate'sownZones()).deploy --env <name>builds,wrangler deploys with_shared's Cloudflare token, and smokes/healthz;generate-route-treeas before.packages/docs-app/src/routes/_auth/projects.$slug.$repo.$.tsxpkg.pr.new/iterate/docs/…@<commit>;iterate/package-buildsbuildVersionnames iterate/private's builds. Production still installs npm'smain.packages/docs/src/install.ts(+ test)docsAgentGuidenames iterate/docs. iterate/private's half keeps the old URL answering with a pointer here.packages/docs/src/processor.test.tsiterate/stream/processoranditerate/stream/test-support. iterate's npm build declares those classes twice (core/lib/tsdown.config.tsbuilds test-support in its node build), so TypeScript sees two#privatefields. One class at runtime; a fix in core/lib would drop the casts.packages/docs/src/processor.ts, the$.tsxrouteoxlint-disablecomments for iterate's own lint plugin, which isn't here, become plain comments..depot/workflows/ci.yml,.depot/actions/setup,scripts/ci/toolchain.sh(+ test).depot/workflows/deploy.yml,scripts/ci/page.tspreview, thenprd; a red run pages #error-pulse (Kit's pager, with_shared/prd's bot token)..github/workflows/pkg-pr-new.yml@iterate-com/docson pkg.pr.new for every main commit and every PR head (iterate/private published a PR only when a package's inputs changed; here nearly every PR touches the package or the app that installs it)..github/workflows/npm-publish.yml,scripts/ci/npm-publish.ts(+ test)README.md,AGENTS.md,doppler.yaml,LICENSE,.oxlintrc.json,.oxfmtrc.json,.gitignore, package READMEsHistory
Main starts with Docs' own commits, the tip's tree byte-identical to iterate/private@a541c9d's
packages/docsandpackages/docs-app:packages/docs, andapps/docswritten aspackages/docs-app. Each title's(#N)reads(iterate/iterate#N), and each ends inOriginal-Commit: iterate/iterate@<sha>.Original-Commit: iterate/packages@<sha>beside copybara'sGitOrigin-RevId.Done outside the diff
Still to do
@iterate-com/docs's trusted publisher names iterate/private'snpm-publish.yml. Until a maintainer adds iterate/docs (npx npm@latest trust github @iterate-com/docs --repo iterate/docs --file npm-publish.yml --allow-publish, then tick "Allow npm dist-tag" at https://www.npmjs.com/package/@iterate-com/docs/access), npm / check stays red here and main's npm run fails. Its job summary prints the commands.test/playwright/docsmove here in a follow-up PR, run against the dev platform.Risk map
src/app/*,src/components/**), not the workspace's packages/ui. They are byte-identical to iterate/private@a541c9d, so the risk is drift later, not a difference now.deploy-docs.ymlandpreview-parents.yml, a main push there redeploys the same Workers from its copy. The code is the same today, so stale, not broken; the cutover order below avoids it.@iterate-com/docsuntil its half lands.packages/docs-app/vite.config.tsandenvs.ts(what deploys where),.depot/workflows/deploy.yml, the two.github/workflows,packages/docs-app/src/routes/_auth/projects.$slug.$repo.$.tsx,packages/docs/src/install.ts; the copied files (src/app,src/components) only for their headers.Cutover
deploy-docs.yml, Docs' per-PR previews andpreview-parents.yml's Docs redeploy go with it, and the Workers keep their last deploy.previewandprd.Evidence
@iterate-com/docsfor its head (pkg.pr.new/iterate/docs/@iterate-com/docs@2cf1c08…answers 200).CLOUDFLARE_ENV=preview, deployed to a throwaway Worker on the dev account (docs-standalone-check), and iterate/private's own--project docsspecs run from its main against it, served through fixture projects on main on dev:8 passed (53.8s). Then the same specs from Docs' browser specs run here: on each pull request's own Worker, and on preview before prd #2, installing this PR's pkg.pr.new build:10 passed (50.2s)with the phone runs.CLOUDFLARE_ENV=preview vite buildwrites the Worker config iterate/private'sstartAppWorkerConfigwrites for Docs: name, account, compatibility date and flags, bindings, observability,run_worker_firstandITERATE_APP(every link and deny zone) equal.deploy.yml(main only),scripts/ci/page.ts(a red main run only), npm'spublishjob (main only, and needs the trusted publisher).Claude Code session:
local_cdd673f8-107f-4d2f-8087-ac4278554ee1("iterate/docs repo")🤖 Generated with Claude Code