Skip to content

Add Cloudflare deployment migration executors - #2439

Merged
ascorbic merged 4 commits into
codex/issue-2276-migrations-clifrom
codex/issue-2276-migrations-cloudflare
Aug 18, 2026
Merged

Add Cloudflare deployment migration executors#2439
ascorbic merged 4 commits into
codex/issue-2276-migrations-clifrom
codex/issue-2276-migrations-cloudflare

Conversation

@ascorbic

@ascorbic ascorbic commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

What does this PR do?

Adds deployment migration executors for Cloudflare D1 and Hyperdrive, including the D1 REST dialect and migration target, package entrypoints, build configuration, and credential-gated live coverage.

Part of #2276

Type of change

  • Bug fix
  • Feature (requires maintainer-approved Discussion)
  • Refactor (no behavior change)
  • Translation
  • Documentation
  • Performance improvement
  • Tests
  • Chore (dependencies, CI, tooling)

Checklist

  • I have read CONTRIBUTING.md
  • pnpm typecheck passes
  • pnpm lint passes
  • pnpm test passes (or targeted tests for my change)
  • pnpm format has been run
  • I have added/updated tests for my changes (if applicable)
  • User-visible strings in the admin UI are wrapped for translation (if applicable). Do not include messages.po changes except in translation PRs — a workflow extracts catalogs on merge to main.
  • I have added a changeset (if this PR changes a published package)
  • New features link to an approved Discussion: RFC: Deployment-managed core migrations #2418

Approved design discussion: #2418. Package typechecking, quick lint, and targeted formatting pass.

AI-generated code disclosure

  • This PR includes AI-generated code — model/tool: GPT-5 Codex

Screenshots / test output

Non-visual change. Cloudflare build and typecheck pass; 346 tests pass and two live credential-gated tests are skipped because D1/PostgreSQL credentials are unavailable. Built executor entrypoints contain no test credentials.

@changeset-bot

changeset-bot Bot commented Aug 12, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: b724193

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 17 packages
Name Type
@emdash-cms/cloudflare Minor
@emdash-cms/fixture-perf-site Patch
@emdash-cms/perf-demo-site Patch
@emdash-cms/cache-demo-site Patch
@emdash-cms/do-demo-site Patch
@emdash-cms/do-solo-demo-site Patch
emdash Minor
@emdash-cms/admin Minor
@emdash-cms/auth Minor
@emdash-cms/blocks Minor
@emdash-cms/gutenberg-to-portable-text Minor
@emdash-cms/x402 Minor
create-emdash Minor
@emdash-cms/sandbox-workerd Patch
@emdash-cms/plugin-mcp-smoke Major
@emdash-cms/auth-atproto Patch
@emdash-cms/plugin-embeds Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 12, 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 successful!
View logs
emdash-playground 017e863 Aug 13 2026, 08:53 AM

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 12, 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 successful!
View logs
emdash-demo-cache b724193 Aug 18 2026, 02:26 PM

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 12, 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 successful!
View logs
docs b724193 Aug 18 2026, 02:31 PM

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 12, 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 successful!
View logs
emdash-demo-do b724193 Aug 18 2026, 02:30 PM

@github-actions

Copy link
Copy Markdown
Contributor

Scope check

This PR changes 1,758 lines across 18 files. Large PRs are harder to review and more likely to be closed without review.

If this scope is intentional, no action needed. A maintainer will review it. If not, please consider splitting this into smaller PRs.

See CONTRIBUTING.md for contribution guidelines.

@ascorbic
ascorbic marked this pull request as ready for review August 12, 2026 16:32
Copilot AI lite review requested due to automatic review settings August 12, 2026 16:32
@github-actions github-actions Bot added the review/needs-review No maintainer or bot review yet label Aug 12, 2026

Copilot AI 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.

Pull request overview

Adds Cloudflare-focused deployment migration executors to support running EmDash migrations during deployment (rather than during Worker runtime init), including a D1 REST-based Kysely dialect/target resolution and a Hyperdrive direct-origin executor.

Changes:

  • Exposes new Cloudflare package entrypoints for D1 and Hyperdrive migration executors (and wires them into build config).
  • Implements D1 deployment migration support via Cloudflare’s authenticated REST API (dialect + target resolution helpers).
  • Adds unit/live tests and changesets for the new Cloudflare migration functionality.

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/cloudflare/tsdown.config.ts Adds tsdown build entries for new migration executor entrypoints.
packages/cloudflare/package.json Exports new ./db/*-migrations entrypoints.
packages/cloudflare/src/index.ts Extends D1/Hyperdrive descriptors with migrations manifest config and adds Hyperdrive env-var option/validation.
packages/cloudflare/src/db/hyperdrive.ts Updates docs/comments to clarify “runtime migrations” binding behavior.
packages/cloudflare/src/db/hyperdrive-migrations.ts Adds Hyperdrive migration executor factory that delegates to core Postgres migrations.
packages/cloudflare/src/db/d1-rest-dialect.ts Introduces a REST-backed Kysely dialect for administrative D1 queries.
packages/cloudflare/src/db/d1-migrations.ts Implements D1 migration executor factory using the REST dialect + resolved migration target.
packages/cloudflare/src/db/d1-migration-target.ts Resolves/validates D1 migration targets (wrangler config + control-plane metadata), and fingerprints targets.
packages/cloudflare/tests/hyperdrive-config.test.ts Adds tests for Hyperdrive migration manifest config behavior and credential isolation.
packages/cloudflare/tests/do-config.test.ts Updates D1 descriptor test expectations to include migrations entrypoint/config.
packages/cloudflare/tests/fixtures/d1-wrangler.jsonc Adds wrangler config fixture for D1 target resolution tests.
packages/cloudflare/tests/db/hyperdrive-migrations.test.ts Adds tests for Hyperdrive migration executor target identity and env overrides.
packages/cloudflare/tests/db/d1-rest-dialect.test.ts Adds comprehensive unit tests for the D1 REST dialect behavior and error handling.
packages/cloudflare/tests/db/d1-migrations.test.ts Adds unit tests ensuring D1 executor construction and token-gating behavior.
packages/cloudflare/tests/db/d1-migrations.live.test.ts Adds credential-gated live D1 contract tests for apply/idempotency and query semantics.
packages/cloudflare/tests/db/d1-migration-target.test.ts Adds tests for D1 target resolution rules, pagination, and wrangler env selection.
.changeset/add-hyperdrive-direct-migrations.md Changeset for Hyperdrive direct-origin deployment migrations.
.changeset/add-cloudflare-d1-migrations.md Changeset for deployment-managed D1 migrations via REST.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/cloudflare/src/db/d1-rest-dialect.ts
Comment thread packages/cloudflare/src/db/hyperdrive-migrations.ts

@emdashbot emdashbot 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.

The PR adds a sensible slice of the deployment-migration story: a D1 REST dialect, resolver for D1 target metadata, package entrypoints, and a Hyperdrive wrapper around the existing PostgreSQL migration executor. The changes are additive, carry changesets, keep migration credentials out of the Worker runtime config, and include targeted tests. I checked the diff, migration runner, direct executor, and the existing SQLite/PostgreSQL migration providers.

The big gap is that the new D1 REST dialect rejects beginTransaction/commitTransaction/rollbackTransaction. EmDash's migration runner uses Kysely's Migrator.migrateToLatest(), which wraps each migration in a transaction by default. The other migration providers (SQLite, libSQL, PostgreSQL) all use transaction-capable Kysely dialects, so an action: "apply" against the new D1 REST executor will throw at the first pending migration. The credential-gated live apply test is skipped in CI, so this path is not currently exercised and the bug is hidden. That needs to be fixed before the feature can be considered working.

Aside from that, the Hyperdrive side looks correct, tests are behavior-oriented rather than tautological, and the exports/build config line up.

Comment thread packages/cloudflare/src/db/d1-rest-dialect.ts
@github-actions github-actions Bot added review/awaiting-author Reviewed; waiting on the author to respond and removed review/needs-review No maintainer or bot review yet labels Aug 12, 2026
@ascorbic
ascorbic force-pushed the codex/issue-2276-migrations-cloudflare branch from ad5242b to beb551b Compare August 13, 2026 08:20
@github-actions github-actions Bot added review/needs-rereview Author pushed changes since the last review and removed review/awaiting-author Reviewed; waiting on the author to respond labels Aug 13, 2026
@pkg-pr-new

pkg-pr-new Bot commented Aug 13, 2026

Copy link
Copy Markdown

Open in StackBlitz

@emdash-cms/admin

npm i https://pkg.pr.new/@emdash-cms/admin@2439

@emdash-cms/auth

npm i https://pkg.pr.new/@emdash-cms/auth@2439

@emdash-cms/auth-atproto

npm i https://pkg.pr.new/@emdash-cms/auth-atproto@2439

@emdash-cms/blocks

npm i https://pkg.pr.new/@emdash-cms/blocks@2439

@emdash-cms/cloudflare

npm i https://pkg.pr.new/@emdash-cms/cloudflare@2439

@emdash-cms/contentful-to-portable-text

npm i https://pkg.pr.new/@emdash-cms/contentful-to-portable-text@2439

emdash

npm i https://pkg.pr.new/emdash@2439

create-emdash

npm i https://pkg.pr.new/create-emdash@2439

@emdash-cms/gutenberg-to-portable-text

npm i https://pkg.pr.new/@emdash-cms/gutenberg-to-portable-text@2439

@emdash-cms/plugin-cli

npm i https://pkg.pr.new/@emdash-cms/plugin-cli@2439

@emdash-cms/plugin-types

npm i https://pkg.pr.new/@emdash-cms/plugin-types@2439

@emdash-cms/registry-client

npm i https://pkg.pr.new/@emdash-cms/registry-client@2439

@emdash-cms/registry-lexicons

npm i https://pkg.pr.new/@emdash-cms/registry-lexicons@2439

@emdash-cms/registry-verification

npm i https://pkg.pr.new/@emdash-cms/registry-verification@2439

@emdash-cms/sandbox-workerd

npm i https://pkg.pr.new/@emdash-cms/sandbox-workerd@2439

@emdash-cms/x402

npm i https://pkg.pr.new/@emdash-cms/x402@2439

@emdash-cms/plugin-ai-moderation

npm i https://pkg.pr.new/@emdash-cms/plugin-ai-moderation@2439

@emdash-cms/plugin-atproto

npm i https://pkg.pr.new/@emdash-cms/plugin-atproto@2439

@emdash-cms/plugin-audit-log

npm i https://pkg.pr.new/@emdash-cms/plugin-audit-log@2439

@emdash-cms/plugin-color

npm i https://pkg.pr.new/@emdash-cms/plugin-color@2439

@emdash-cms/plugin-embeds

npm i https://pkg.pr.new/@emdash-cms/plugin-embeds@2439

@emdash-cms/plugin-field-kit

npm i https://pkg.pr.new/@emdash-cms/plugin-field-kit@2439

@emdash-cms/plugin-forms

npm i https://pkg.pr.new/@emdash-cms/plugin-forms@2439

@emdash-cms/plugin-webhook-notifier

npm i https://pkg.pr.new/@emdash-cms/plugin-webhook-notifier@2439

commit: b724193

@ascorbic
ascorbic force-pushed the codex/issue-2276-migrations-cloudflare branch from beb551b to 017e863 Compare August 13, 2026 08:46
@ascorbic ascorbic added the bot:review Trigger an emdashbot code review on this PR label Aug 13, 2026

@emdashbot emdashbot 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.

This is a coherent, additive slice of the deployment-migration story: a D1 REST dialect, a Wrangler-aware target resolver, package entrypoints/build config, and a Hyperdrive wrapper that keeps migration credentials out of the Worker runtime config. The Hyperdrive side is correct and the tests are behavior-oriented where they run.

However, the re-review confirms the hard blocker from my previous review is still open: D1RestDriver throws on beginTransaction, commitTransaction, and rollbackTransaction. EmDash's migration runner uses Kysely.Migrator.migrateToLatest(), which wraps each migration in a transaction by default. The other migration providers (SQLite, PostgreSQL) all use transaction-capable dialects, so an action: "apply" against the new D1 REST executor will throw "Transactions are not supported yet" at the first pending migration. The credential-gated live apply test is skipped in CI, and the unit tests only exercise action: "check", so the bug remains hidden.

That needs to be fixed before this feature can be considered working — either by implementing D1 REST batch transactions in the driver (the correct fix, since /query accepts a statement array) or by another transaction strategy that interoperates with Kysely's migrator. Once the dialect can survive migrateToLatest(), the live test should run when credentials are present, and a unit-level test for the apply path would prevent regression in CI.

Comment thread packages/cloudflare/src/db/d1-rest-dialect.ts
Comment thread packages/cloudflare/tests/db/d1-migrations.test.ts
@emdashbot emdashbot Bot removed the bot:review Trigger an emdashbot code review on this PR label Aug 13, 2026
@github-actions github-actions Bot added review/awaiting-author Reviewed; waiting on the author to respond and removed review/needs-rereview Author pushed changes since the last review labels Aug 13, 2026
@ascorbic
ascorbic force-pushed the codex/issue-2276-migrations-cloudflare branch from 017e863 to 64c4489 Compare August 13, 2026 08:58
@emdashbot emdashbot Bot removed the bot:review Trigger an emdashbot code review on this PR label Aug 13, 2026
@github-actions github-actions Bot added review/awaiting-author Reviewed; waiting on the author to respond and removed review/needs-rereview Author pushed changes since the last review labels Aug 13, 2026
@ascorbic
ascorbic force-pushed the codex/issue-2276-migrations-cloudflare branch from 1f8fa12 to edd028d Compare August 13, 2026 09:17
@ascorbic ascorbic added the bot:review Trigger an emdashbot code review on this PR label Aug 13, 2026

@emdashbot emdashbot 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.

Re-review: the branch is unchanged since the last pass, and the unresolved D1 transaction blocker is still present.

The change remains a coherent additive slice: Wrangler-aware D1 target resolution, a D1 REST dialect, a Hyperdrive direct-origin migration entrypoint, package exports/build config, and credential-gated live coverage. The Hyperdrive path keeps migration credentials out of the runtime Worker config, the D1 REST request/response validation and error redaction are well-tested, and the AGENTS.md conventions I checked (changesets, SQL safety through parameterized queries, secret-free manifest config, no new logged-out-route queries, no offending reviewer-facing comments) are otherwise satisfied.

The one issue that makes the D1 executor non-functional is that D1RestDriver throws from beginTransaction, commitTransaction, and rollbackTransaction, while D1RestDialect.createAdapter() returns a plain D1Adapter that inherits supportsTransactionalDdl() === true from Kysely's SqliteAdapter. createDirectMigrationExecutor constructs a Kysely Migrator without allowMigrationStatementRollback, so migrateToLatest() will attempt to wrap each migration in a transaction before any migration SQL reaches Cloudflare. That means action: "apply" fails against every D1 REST target, including a fresh database. A unit-level regression test for the apply path is also missing: packages/cloudflare/tests/db/d1-migrations.test.ts only tests "check", and the live "apply" test is skipped in CI.

No new blockers or convention violations were found in this pass.

Comment thread packages/cloudflare/src/db/d1-rest-dialect.ts
@emdashbot emdashbot Bot removed the bot:review Trigger an emdashbot code review on this PR label Aug 13, 2026
@ascorbic
ascorbic force-pushed the codex/issue-2276-migrations-cloudflare branch from edd028d to 44a6a74 Compare August 13, 2026 11:23
@github-actions github-actions Bot added review/needs-rereview Author pushed changes since the last review and removed review/awaiting-author Reviewed; waiting on the author to respond labels Aug 13, 2026
@ascorbic ascorbic added the bot:review Trigger an emdashbot code review on this PR label Aug 13, 2026

@emdashbot emdashbot 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.

This is a coherent additive slice that wires Cloudflare D1 and Hyperdrive into the new deployment migration framework: a Wrangler-aware D1 target resolver, a D1 REST dialect for running migrations over the Cloudflare API, a Hyperdrive direct-origin migration entrypoint, package exports/build config, and credential-gated live tests. The Hyperdrive path keeps migration credentials out of runtime Worker config, the D1 REST request/response validation and error redaction are well-tested, and the AGENTS.md conventions I checked (changesets, SQL safety through parameterized queries, secret-free manifest config, no new logged-out-route queries, no reviewer-facing comments) are otherwise satisfied.

However, the branch is unchanged since the last review and the D1 transaction blocker is still present: D1RestDialect.createAdapter() returns a plain D1Adapter that inherits supportsTransactionalDdl() === true from Kysely's SqliteAdapter, while D1RestDriver throws from beginTransaction, commitTransaction, and rollbackTransaction. The shared createDirectMigrationExecutor constructs a Kysely Migrator without disabling transactional DDL wrapping, so migrateToLatest() will attempt to start a transaction before any migration SQL reaches Cloudflare. That makes the D1 apply action fail against every D1 REST target, including a fresh database.

A unit-level regression test for the apply path is also missing: packages/cloudflare/tests/db/d1-migrations.test.ts only exercises "check", and the one live "apply" test in d1-migrations.live.test.ts is skipped in CI when credentials are unavailable. I would expect the fix plus a mocked apply test before this merges.

No new blockers or convention violations were found in this pass.

Comment thread packages/cloudflare/src/db/d1-rest-dialect.ts
Comment thread packages/cloudflare/tests/db/d1-migrations.test.ts
@emdashbot emdashbot Bot removed the bot:review Trigger an emdashbot code review on this PR label Aug 13, 2026
@github-actions github-actions Bot added review/awaiting-author Reviewed; waiting on the author to respond and removed review/needs-rereview Author pushed changes since the last review labels Aug 13, 2026
@ascorbic
ascorbic force-pushed the codex/issue-2276-migrations-cloudflare branch from 44a6a74 to 27359a8 Compare August 18, 2026 13:08
@github-actions github-actions Bot added review/needs-rereview Author pushed changes since the last review and removed review/awaiting-author Reviewed; waiting on the author to respond labels Aug 18, 2026
@ascorbic
ascorbic force-pushed the codex/issue-2276-migrations-cloudflare branch from 27359a8 to b724193 Compare August 18, 2026 14:20
@ascorbic
ascorbic merged commit 340743b into main Aug 18, 2026
66 of 94 checks passed
@ascorbic
ascorbic deleted the codex/issue-2276-migrations-cloudflare branch August 18, 2026 15:16
@emdashbot emdashbot Bot mentioned this pull request Aug 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants