Skip to content

Add per-PR Cloudflare preview deploys - #953

Merged
RhysSullivan merged 1 commit into
mainfrom
claude/practical-heyrovsky-caa52a
Jun 11, 2026
Merged

Add per-PR Cloudflare preview deploys#953
RhysSullivan merged 1 commit into
mainfrom
claude/practical-heyrovsky-caa52a

Conversation

@RhysSullivan

Copy link
Copy Markdown
Collaborator

Every same-repo pull request now gets an isolated preview deployment of the Cloudflare host, torn down when the PR closes.

How it works

  • apps/host-cloudflare/scripts/preview.ts (deploy | destroy | list --pr N) provisions one stack per PR on a dedicated preview Cloudflare account: a Worker (executor-preview-pr-<n>), its own D1 database, a fresh at-rest encryption key, and its own Cloudflare Access application created via API — MCP-OAuth-aware (dynamic client registration enabled), edge-enforced on the workers.dev hostname, with an email allowlist policy. Previews are never publicly open: browsers get the Access login, unauthenticated /mcp gets the standard 401 + resource_metadata OAuth challenge.
  • The preview wrangler config is derived from the committed wrangler.jsonc with asserted substitutions, so previews deploy the same config self-hosters use and config drift fails loudly.
  • Teardown is stateless by naming convention: every resource a preview owns is derived from its PR number, so destroy needs no deploy-time state to survive CI.
  • The shared R2 blob bucket (executor-preview-blobs) is reused across previews — blobs are only reachable via pointers in each preview's private D1, and leaving the bucket keeps teardown trivial.

Workflows

  • preview.yml: deploy on PR open/reopen/sync, sticky comment with console + MCP URLs, teardown on close. Fork PRs are skipped — they never run with the deploy token. Concurrency is per-PR.
  • preview-sweep.yml: nightly sweep that destroys previews whose PR is no longer open (catches force-push and cancelled-run orphans).

Repo configuration (already set): secret CLOUDFLARE_PREVIEW_API_TOKEN plus variables CLOUDFLARE_PREVIEW_ACCOUNT_ID, PREVIEW_ACCESS_TEAM_DOMAIN, PREVIEW_ACCESS_EMAILS.

The deploy/redeploy/destroy cycle was verified end-to-end against the preview account, including the Access gate on both the console and MCP surfaces.

Also extends the relaxed lint override for script files to apps/*/scripts/** and gitignores the generated wrangler.preview.jsonc.

Every same-repo pull request gets an isolated preview of the Cloudflare
host on a dedicated preview account: its own Worker, D1 database,
encryption key, and Cloudflare Access application (MCP-OAuth-aware,
edge-enforced on the workers.dev hostname), deployed on PR open/sync and
destroyed on close. A nightly sweeper removes previews whose PR is no
longer open. Teardown is stateless: every resource a preview owns is
derived from its PR number.
@cloudflare-workers-and-pages

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 successful!
View logs
executor-cloud a17a1e4 Jun 11 2026, 09:29 PM

@cloudflare-workers-and-pages

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 Preview URL Updated (UTC)
✅ Deployment successful!
View logs
executor-marketing a17a1e4 Commit Preview URL

Branch Preview URL
Jun 11 2026, 09:28 PM

@github-actions

github-actions Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Cloudflare preview

Torn down — the PR is closed.

@pkg-pr-new

pkg-pr-new Bot commented Jun 11, 2026

Copy link
Copy Markdown

Open in StackBlitz

@executor-js/cli

npm i https://pkg.pr.new/@executor-js/cli@953

@executor-js/config

npm i https://pkg.pr.new/@executor-js/config@953

@executor-js/execution

npm i https://pkg.pr.new/@executor-js/execution@953

@executor-js/sdk

npm i https://pkg.pr.new/@executor-js/sdk@953

@executor-js/codemode-core

npm i https://pkg.pr.new/@executor-js/codemode-core@953

@executor-js/runtime-quickjs

npm i https://pkg.pr.new/@executor-js/runtime-quickjs@953

@executor-js/plugin-file-secrets

npm i https://pkg.pr.new/@executor-js/plugin-file-secrets@953

@executor-js/plugin-graphql

npm i https://pkg.pr.new/@executor-js/plugin-graphql@953

@executor-js/plugin-keychain

npm i https://pkg.pr.new/@executor-js/plugin-keychain@953

@executor-js/plugin-mcp

npm i https://pkg.pr.new/@executor-js/plugin-mcp@953

@executor-js/plugin-onepassword

npm i https://pkg.pr.new/@executor-js/plugin-onepassword@953

@executor-js/plugin-openapi

npm i https://pkg.pr.new/@executor-js/plugin-openapi@953

executor

npm i https://pkg.pr.new/executor@953

commit: a17a1e4

@RhysSullivan
RhysSullivan merged commit 1dcebe6 into main Jun 11, 2026
14 checks passed
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