Skip to content

[ci] Serve the docs from Cloudflare Workers with per-PR previews - #6287

Merged
mmabrouk merged 1 commit into
mainfrom
docs-cloudflare-preview
Aug 26, 2026
Merged

[ci] Serve the docs from Cloudflare Workers with per-PR previews#6287
mmabrouk merged 1 commit into
mainfrom
docs-cloudflare-preview

Conversation

@mmabrouk

Copy link
Copy Markdown
Member

Context

The docs site is the last thing we host on Vercel. Vercel's GitHub integration builds it, and the whole setup lives in a dashboard, so the only trace of it in this repo is a four-line docs/vercel.json. Nobody can review the deploy, reproduce it, or change it from a pull request.

Docs pull requests also get no preview that a reviewer can open. You approve a wording change by reading the diff and hoping the page still builds.

The marketing site moved to Cloudflare Workers in July and that setup works well. This puts the docs on the same one.

Changes

Two new workers, both plain static-asset workers with no worker code:

Worker Config What it serves
agenta-docs docs/wrangler.production.jsonc production
agenta-docs-preview docs/wrangler.jsonc one version per pull request

Two workflows drive them, cloned from the marketing site's 15/16: 18-docs-preview.yml builds every pull request that touches docs/** and uploads it as a preview version, and 19-docs-production.yml builds and deploys on merge to main.

The one real change to the site itself is where the build lands. Docusaurus writes the site to the root of build/ while every link is prefixed /docs/, which is exactly what the Vercel rewrite existed to paper over:

"rewrites": [{ "source": "/docs/:path*", "destination": "/:path*" }]

pnpm run build:worker writes to dist/docs instead, so the file tree matches the URL tree and Cloudflare serves /docs/anything with no rule at all. scripts/stage-worker-assets.mjs then copies _headers and _redirects up to dist/, where Cloudflare reads them.

The preview comment updates in place on every push and deep-links the pages the branch touched:

### 📘 Docs preview

|  |  |
| --- | --- |
| Status | ✅ Ready |
| Preview | https://pr-1234-agenta-docs-preview.<subdomain>.workers.dev/docs |
| Inspect | Actions run |
| Commit | abc1234 |

**Pages changed in this pull request**
- [Quick start](.../docs/getting-started/quick-start)

The links are not guessed from file paths. Numeric prefixes, slug: frontmatter and versioned docs all break that. scripts/changed-pages.mjs reads the metadata Docusaurus writes during the build, which carries the real source path and permalink, and prints nothing at all rather than a wrong link.

Preview builds set DOCS_NOINDEX=true, which turns on Docusaurus noIndex and writes a disallow-all robots.txt, so a public workers.dev preview can never rank against the real docs.

Nothing routes to the new production worker yet. agenta.ai/docs/* still goes through the existing new-docs-router worker and on to Vercel. Merging this deploys agenta-docs to its workers.dev URL and changes no live traffic. Cutover is a separate step (below).

Tests

Verified against a real preview deploy of this branch, agenta-docs-preview:

  • scripts/check-parity.mjs requested all 950 URLs from the live docs sitemap against the preview. All 950 returned 200. The only two redirects are the two version roots, /docs/ and /docs/1.0/, which now 307 to the no-slash form.
  • Cloudflare's asset router can treat a path segment containing a dot as a file name and skip the index.html lookup, which would have broken /docs/1.0 and /docs/self-host/upgrades/v0.100.3-migration. Both return 200.
  • The custom 404 page renders even though the site sits one level down in dist/docs.
  • Cache headers land as intended and are not comma-joined: max-age=31536000, immutable on /docs/assets/*, one week on images, 60 s with stale-while-revalidate on HTML.
  • Client-side redirect pages still bounce, for example /docs/changelog/main.
  • <meta name="robots" content="noindex, nofollow"> is present on the preview and /robots.txt disallows everything.
  • wrangler versions upload --preview-alias pr-0 produced the alias URL the workflow greps for. The first upload of the full 378 MB build took 35 seconds; the second took 6, because wrangler only sends changed files.
  • Build wall time is 1 minute 33 seconds locally.
  • Rendered both the home page and a deep page in a browser. Layout, images, sidebar and search all fine.

Before merging

POSTHOG_API_KEY currently lives in the Vercel project settings. It needs to exist as a GitHub repo secret of the same name, or docs analytics goes quiet when we cut over. PostHog project keys are ingest-only and public by design, so this is about not losing the value, not about secrecy.

Cutover, after this merges

  1. Run node docs/scripts/check-parity.mjs https://agenta-docs.<subdomain>.workers.dev against the deployed production worker.
  2. In one sitting, remove the agenta.ai/docs* route from new-docs-router and add agenta.ai/docs and agenta.ai/docs/* to agenta-docs. Two workers cannot hold the same route, so this is a single swap. The commented-out routes block in wrangler.production.jsonc has the exact patterns.
  3. Re-run the parity check against https://agenta.ai, and confirm docs.agenta.ai still redirects and /sitemap_index.xml still lists both sitemaps. new-docs-router keeps owning both; only its Vercel proxy rule goes away.
  4. Rolling back takes under two minutes: drop the two routes and restore the old one. The Vercel proxy code is untouched.
  5. After a couple of quiet weeks, delete docs/vercel.json and the Vercel project.

Not in this pull request

Fork pull requests get no preview, because they cannot read the deploy secrets. Two of the last sixty docs pull requests came from forks. The safe pattern (build without secrets, upload an artifact, deploy from a workflow_run job) is a follow-up if we decide we want it.

@vercel

vercel Bot commented Aug 26, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agenta-documentation Ready Ready Preview Aug 26, 2026 6:52pm

Request Review

@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. ci/cd devops documentation Improvements or additions to documentation labels Aug 26, 2026
@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

📘 Docs preview

Status ✅ Ready
Preview https://pr-6287-agenta-docs-preview.mahmoud-637.workers.dev/docs
Inspect Actions run
Commit 251b5baaefde7f2d0bb3106ad33b0761c89ea443

This comment updates in place on every push.

@coderabbitai

coderabbitai Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 3b9f768f-8d27-438f-8249-6dd433e2f29a

📥 Commits

Reviewing files that changed from the base of the PR and between 00ac9be and 6d96f33.

📒 Files selected for processing (13)
  • .github/workflows/18-docs-preview.yml
  • .github/workflows/19-docs-production.yml
  • docs/.gitignore
  • docs/README.md
  • docs/docusaurus.config.ts
  • docs/package.json
  • docs/scripts/changed-pages.mjs
  • docs/scripts/check-parity.mjs
  • docs/scripts/stage-worker-assets.mjs
  • docs/worker-assets/_headers
  • docs/worker-assets/_redirects
  • docs/wrangler.jsonc
  • docs/wrangler.production.jsonc

Included review availability: Your plan provides up to 8 included reviews per hour; 6 remain after this review.


📝 Walkthrough

Summary by CodeRabbit

  • New Features
    • Added automated documentation previews for pull requests, including readiness checks and links to changed pages.
    • Added automated production documentation deployments with endpoint verification.
    • Preview documentation is excluded from search indexing, while production documentation remains discoverable.
    • Improved documentation delivery with redirects, custom error handling, caching, and security headers.
  • Documentation
    • Added guidance for deploying, previewing, and locally serving the documentation site.
  • Quality Improvements
    • Added automated checks to verify documentation page parity across deployments.

Walkthrough

Added production and pull-request preview workflows for Cloudflare Workers documentation deployments. Added asset staging, cache and redirect rules, preview noindex handling, changed-page links, sitemap parity checks, and deployment documentation.

Changes

Documentation deployment

Layer / File(s) Summary
Build and asset staging
docs/docusaurus.config.ts, docs/package.json, docs/scripts/stage-worker-assets.mjs, docs/worker-assets/*, docs/.gitignore
The worker build stages Docusaurus output with headers, redirects, and optional preview robots.txt content.
Production deployment
docs/wrangler.production.jsonc, .github/workflows/19-docs-production.yml
The production workflow builds and deploys agenta-docs, extracts the deployment URL, and verifies /docs with retries.
Pull-request preview deployment
docs/wrangler.jsonc, .github/workflows/18-docs-preview.yml, docs/scripts/changed-pages.mjs
The preview workflow deploys PR-specific aliases, verifies them, and updates sticky pull-request comments with status and changed-page links.
Parity checks and deployment documentation
docs/scripts/check-parity.mjs, docs/README.md
The parity checker validates sitemap URLs against a target origin with redirect and concurrency handling. The README documents deployment and local validation procedures.

Estimated code review effort: 4 (Complex) | ~45 minutes

Merge Risk: 🔵 Low · up to 6d96f

The PR adds Cloudflare-based docs previews and deployment, while the validation script can accept redirected URLs with changed query strings and does not verify cache headers or missing-page responses. This is a bounded merge-readiness risk that is mergeable with explicit owner follow-up.

Sequence Diagram(s)

sequenceDiagram
  participant PullRequest
  participant GitHubActions
  participant CloudflareWorkers
  participant PullRequestComment
  PullRequest->>GitHubActions: trigger preview workflow
  GitHubActions->>GitHubActions: resolve and check out PR head
  GitHubActions->>CloudflareWorkers: deploy PR-specific docs alias
  CloudflareWorkers-->>GitHubActions: return deployment URL
  GitHubActions->>CloudflareWorkers: verify /docs returns HTTP 200
  GitHubActions->>PullRequestComment: publish ready or failure status
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: serving documentation from Cloudflare Workers with per-PR previews.
Description check ✅ Passed The description directly explains the Cloudflare Workers migration, preview and production workflows, validation, and unchanged live routing.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 4…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 4 files. (9 skipped: 9 unsupported.)

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs-cloudflare-preview

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Comment thread docs/scripts/changed-pages.mjs Fixed

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 500780d2-57b2-4c07-8e00-12e0dfc967c5

📥 Commits

Reviewing files that changed from the base of the PR and between a09a0f0 and e4753ff.

📒 Files selected for processing (13)
  • .github/workflows/18-docs-preview.yml
  • .github/workflows/19-docs-production.yml
  • docs/.gitignore
  • docs/README.md
  • docs/docusaurus.config.ts
  • docs/package.json
  • docs/scripts/changed-pages.mjs
  • docs/scripts/check-parity.mjs
  • docs/scripts/stage-worker-assets.mjs
  • docs/worker-assets/_headers
  • docs/worker-assets/_redirects
  • docs/wrangler.jsonc
  • docs/wrangler.production.jsonc

Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review.

Comment thread .github/workflows/18-docs-preview.yml Outdated
Comment thread docs/README.md Outdated
Comment thread docs/scripts/check-parity.mjs Outdated
Comment thread docs/scripts/check-parity.mjs Outdated
Comment thread docs/scripts/check-parity.mjs
Comment thread docs/scripts/check-parity.mjs Outdated
Comment thread docs/worker-assets/_headers

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: f49fee6d-24ce-4dd1-aa4e-78aa8ea41656

📥 Commits

Reviewing files that changed from the base of the PR and between e4753ff and 7d68c48.

📒 Files selected for processing (1)
  • docs/scripts/changed-pages.mjs

Included review availability: Your plan provides up to 8 included reviews per hour; 5 remain after this review.

Comment thread docs/scripts/changed-pages.mjs
@mmabrouk

Copy link
Copy Markdown
Member Author

Addressed every review comment. Pushed as 8719644ed6.

CodeQL, incomplete escaping in changed-pages.mjs. The markdown link title escaped [ and ] but not \. Now escaped in one pass: /([\\[\]])/g. CodeQL passes.

A manual dispatch could publish main under a PR's alias. Correct, and worse than cosmetic. A new Resolve the pull request head step now looks the PR up first, refuses a head that lives in a fork (this job holds deploy secrets, so it must never build outside code), and checkout takes that exact SHA. The comment reports the resolved head, not the dispatch commit. persist-credentials: false added to checkout in both workflows, since neither pushes.

check-parity.mjs could pass without checking anything. Three ways it could, all closed:

  • A non-numeric or missing --concurrency made Math.max(1, NaN) produce NaN workers, so Promise.all resolved immediately and the run reported success. --concurrency, --limit and the new --timeout are now validated as integers with a floor, and a bad value exits 2.
  • A sitemap with no <loc> elements reported parity OK: 0/0. It now exits 2 with a message.
  • No request deadline meant one stalled page could hang the run forever. Both fetches now pass AbortSignal.timeout, default 30 seconds, overridable with --timeout.

check-parity.mjs doubled the /docs prefix. Right, and the same bug bit the comment links earlier. The script now uses only the origin of the target and ignores any path, because sitemap paths already carry /docs. Verified: https://agenta.ai/docs and https://agenta.ai now check the same URLs.

No X-Robots-Tag on the workers.dev host. Good catch, and it matters after cutover, not just before: production is deliberately built without DOCS_NOINDEX because it is the real docs, so agenta-docs.<subdomain>.workers.dev would be a crawlable duplicate of agenta.ai/docs forever. Added the host-scoped rule and confirmed on a live deploy that Workers Static Assets honours it:

$ curl -sID https://hdrtest-agenta-docs-preview.mahmoud-637.workers.dev/docs
cache-control: public, max-age=60, stale-while-revalidate=3600
x-robots-tag: noindex

The rule ends in the literal .workers.dev, so it cannot match agenta.ai. Cache-Control still arrives once, not comma-joined.

Unquoted $files split paths on spaces. The workflow now reads the changed paths into a bash array and passes "${files[@]}".

README implied this was the cutover. Reworded. The table now says agenta-docs serves the production build on its own workers.dev URL, followed by a paragraph stating that agenta.ai/docs still goes through new-docs-router to Vercel, what the cutover is, and how to roll it back.

Re-verified after the changes: 950 of 950 sitemap URLs return 200 on the preview, and the preview now also carries x-robots-tag: noindex.

@coderabbitai review

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 439c7a89-a625-4ce4-b816-b689028c296e

📥 Commits

Reviewing files that changed from the base of the PR and between 7d68c48 and 8719644.

📒 Files selected for processing (5)
  • .github/workflows/18-docs-preview.yml
  • .github/workflows/19-docs-production.yml
  • docs/README.md
  • docs/scripts/check-parity.mjs
  • docs/worker-assets/_headers
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/README.md

Included review availability: Your plan provides up to 8 included reviews per hour; 6 remain after this review.

Comment thread docs/scripts/check-parity.mjs
@coderabbitai

coderabbitai Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '=== PR diff summary ==='
git diff --stat HEAD^ HEAD || true

echo '=== Changed files ==='
git diff --name-only HEAD^ HEAD || true

echo '=== Workflow outlines ==='
ast-grep outline .github/workflows/18-docs-preview.yml --items all 2>/dev/null || true
ast-grep outline .github/workflows/19-docs-production.yml --items all 2>/dev/null || true

echo '=== Relevant files with line numbers ==='
for f in \
  .github/workflows/18-docs-preview.yml \
  .github/workflows/19-docs-production.yml \
  docs/scripts/changed-pages.mjs \
  docs/scripts/check-parity.mjs \
  docs/scripts/stage-worker-assets.mjs \
  docs/worker-assets/_headers \
  docs/worker-assets/_redirects \
  docs/README.md \
  docs/wrangler.jsonc \
  docs/wrangler.production.jsonc \
  docs/docusaurus.config.ts \
  docs/package.json
do
  if [ -f "$f" ]; then
    echo "--- $f ---"
    cat -n "$f"
  fi
done

Length of output: 74126


🤖 web_search executed:

Cloudflare Workers Static Assets _headers host-specific rules named placeholders syntax https://:subdomain.example.com/* workers.dev

Length of output: 14624


@mmabrouk, I verified the reported fixes in commit 8719644ed6.

The workflows now resolve and check out the exact same-repository PR head for manual dispatches. The parity script now validates options, rejects empty sitemaps, uses only the target origin, and applies request deadlines. The changed-page script escapes backslashes and brackets. The changed-file collection preserves filenames with spaces.

The workers.dev header pattern matches the Cloudflare-documented two-placeholder form. It applies X-Robots-Tag: noindex only to Workers deployment hosts and does not match agenta.ai. See the Cloudflare _headers documentation.

I will run a new review.

⚠️ Action not completed

Already reviewed the last commit. Use @coderabbitai full review to rerun a review of the entire changeset.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 0990b122-1bb7-49a3-99d7-96e22497b67c

📥 Commits

Reviewing files that changed from the base of the PR and between 8719644 and 7a957ad.

📒 Files selected for processing (3)
  • .github/workflows/18-docs-preview.yml
  • .github/workflows/19-docs-production.yml
  • docs/scripts/check-parity.mjs

Included review availability: Your plan provides up to 8 included reviews per hour; 5 remain after this review.

Comment thread .github/workflows/19-docs-production.yml Outdated
Comment thread .github/workflows/19-docs-production.yml Outdated
Comment thread docs/scripts/check-parity.mjs
@mmabrouk
mmabrouk force-pushed the docs-cloudflare-preview branch from 7a957ad to 6d96f33 Compare August 26, 2026 16:19
@mmabrouk

Copy link
Copy Markdown
Member Author

Second round addressed. Pushed as 6d96f33aa5.

A same-origin redirect could still swallow every deep link. Right, and the previous fix only closed the cross-origin half. visit now remembers the path it asked for and compares it against the path it landed on, allowing only the trailing-slash normalisation that drop-trailing-slash performs. I tested both branches against a throwaway server:

mode: honest    (/docs/ 307s to /docs, deep pages served)
  parity OK: 2/2 returned 200

mode: swallow   (every deep link 302s to /docs, which returns 200)
  [redirect changed the path to /docs] http://localhost:8799/docs/deep/page
    302 -> /docs
  parity FAILED: 1/2

A production deploy could ship with analytics off. Agreed, and the fallback made it silent. The build step now fails with a clear error when POSTHOG_API_KEY is empty, before the build starts. The secret is set on this repository now.

SC2034 on the retry loops. Changed to for _ in in both workflows.

For the record, the workflow_dispatch fix from the first round is now proven rather than argued. GitHub did not schedule a pull_request run for the last two pushes, so I triggered this workflow by hand, and the comment reports 7a957ad3c4, the pull request head, rather than the ref the dispatch came from.

Also re-ran the full gate after these changes: 950 of 950 sitemap URLs return 200 on the preview, with the only two redirects being the two version roots.

@coderabbitai review

@mmabrouk mmabrouk closed this Aug 26, 2026
@mmabrouk mmabrouk reopened this Aug 26, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: eb7e8920-3f31-47d6-b9ef-34c0d203d96e

📥 Commits

Reviewing files that changed from the base of the PR and between 7a957ad and 6d96f33.

📒 Files selected for processing (3)
  • .github/workflows/18-docs-preview.yml
  • .github/workflows/19-docs-production.yml
  • docs/scripts/check-parity.mjs

Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review.

Comment thread docs/scripts/check-parity.mjs
@coderabbitai

coderabbitai Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '=== Commit metadata and changed files ==='
git show --no-ext-diff --format=fuller --stat 6d96f33aa5
git diff-tree --no-commit-id --name-only -r 6d96f33aa5

echo '=== Commit patch ==='
git show --no-ext-diff --format= --find-renames 6d96f33aa5 -- \
  docs/scripts/check-parity.mjs \
  .github/workflows/18-docs-preview.yml \
  .github/workflows/19-docs-production.yml

echo '=== JavaScript outline ==='
ast-grep outline docs/scripts/check-parity.mjs --items all --view expanded 2>/dev/null || true

echo '=== Current relevant source ==='
for file in \
  docs/scripts/check-parity.mjs \
  .github/workflows/18-docs-preview.yml \
  .github/workflows/19-docs-production.yml
do
  echo "--- ${file} ---"
  cat -n "$file"
done

Length of output: 43624


@mmabrouk, I verified the second-round fixes in 6d96f33aa5.

check-parity.mjs now rejects redirects that change the requested path. It permits only trailing-slash normalization. The production workflow now fails before the build when POSTHOG_API_KEY is empty. Both retry loops now use _.

I will run a full review of the PR changeset.


If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

✅ Action performed

Full review finished.

@mmabrouk
mmabrouk enabled auto-merge August 26, 2026 16:30
The docs site is the last thing we host on Vercel, deployed by Vercel's
GitHub integration and configured in a dashboard we cannot review. Docs pull
requests also get no preview link that anyone can check before merging.

Move it onto the same Cloudflare Workers Static Assets setup the marketing site
already uses: a preview worker that takes one version per pull request, a
production worker deployed on merge, and a sticky pull request comment that
carries the preview URL and deep links to the pages the change touches.

'pnpm run build:worker' writes the site into dist/docs so the file tree matches
the public /docs/ URL prefix, which is what removes the Vercel rewrite. Nothing
routes to the new production worker yet: cutover is a separate, deliberate swap
of the agenta.ai/docs* route.
@mmabrouk
mmabrouk force-pushed the docs-cloudflare-preview branch from 6d96f33 to 251b5ba Compare August 26, 2026 18:49
@mmabrouk

Copy link
Copy Markdown
Member Author

Cache policy and 404 handling are now part of the gate. Pushed as 251b5baaef.

Fair point, and it is the last hole in this check. Every URL returning 200 is necessary but not sufficient: a deployment that answered everything with the home page would also score 950 out of 950, and one that lost _headers would serve the whole site with the wrong cache policy while passing.

After the sitemap sweep the script now probes a path that cannot exist and requires a 404, reads the home page to find a real content-hashed asset, and asserts the two cache policies that worker-assets/_headers is supposed to produce.

Against the Cloudflare preview:

parity OK: 20/20 returned 200

checking deployment shape
  missing page 404s
  html cache policy: public, max-age=60, stale-while-revalidate=3600
  hashed asset cache policy: public, max-age=31536000, immutable

all checks passed

Against the current production docs on Vercel, the same check fails, correctly:

  hashed asset /docs/assets/js/main.4a9e2a1e.js sent
    "cache-control: public, max-age=60, s-maxage=300", expected /immutable/

parity FAILED on deployment shape

That is a real difference, not a false alarm. The router worker in front of Vercel rewrites cache-control on every response, so content-hashed build assets are re-fetched every minute today. On Cloudflare they get the one-year immutable policy they should have had.

@mmabrouk
mmabrouk merged commit e24609c into main Aug 26, 2026
11 of 12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci/cd devops documentation Improvements or additions to documentation size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants