Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/runtime-cloudflare/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ SSI is extracted only for import requests, so normal browser, mutation, publicat
2. Run `npm run provision:cloudflare-wordpress-runtime-corpus -- --local --persist-to <directory>` to verify and upload all exact content-addressed artifacts into isolated local R2 storage. For an authorized deployment, run the provisioner with `--remote` and require every upload to succeed before deploying the Worker that imports their manifests.
3. Run `npm run test:cloudflare-runtime` for routing, coordinator composition, canonical-state, artifact validation, source contract, and TypeScript coverage.
4. Run `npm run cloudflare:dry-run` and `npm run cloudflare:dry-run:d1` to compile the Durable Object and D1 profiles without creating Cloudflare resources. The placeholder D1 database ID is for local/dry-run verification; an implementation supplies its provisioned binding at deployment.
Use `npm run provision:cloudflare-d1-coordinator -- --output <production-config>` to idempotently create or resolve the named production database and emit a mode-`0600` deployment config from the checked-in template.
Use `npm run provision:cloudflare-d1-coordinator -- --output <production-config>` to idempotently create or resolve the named production database and emit a mode-`0600` deployment config from the checked-in template. Relative entrypoints are resolved from that template so the emitted config remains deployable outside the checkout.
5. Run `npm run cloudflare:local-gate` and `npm run cloudflare:local-gate:d1` for the same isolated workerd workflow through both coordinator implementations. Each gate generates and provisions all artifacts, verifies the selected backend through the state envelope, injects stable test-only admin-password, auth-secret, and operator-token values, uploads and activates a real plugin ZIP, establishes an anonymous homepage and canonical-permalink publication, updates a published post through authenticated REST without immediate rendering, restarts with pending publication work, and proves bounded scheduled draining eventually exposes the updated permalink through coordinator-free R2. The cron gate also proves that a scheduled post becomes readable from the publication path without an operator call. Restart verification requires the immutable R2 publication. A final two-host phase proves isolated mutations, coordinator versions, REST collections, credentials, publications, and caches plus fail-closed unknown-host routing. The remaining coverage includes login, concurrent canonical writes, media, representative frontend/admin/editor assets, PHP diagnostics, session recovery, and a fresh login after restart.

This document describes local candidate verification only. It does not claim remote deployment.
3 changes: 2 additions & 1 deletion scripts/provision-cloudflare-d1-coordinator.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { spawn } from "node:child_process"
import { readFile, writeFile } from "node:fs/promises"
import { resolve } from "node:path"
import { dirname, resolve } from "node:path"

const args = process.argv.slice(2)
const option = (name, fallback) => {
Expand All @@ -26,6 +26,7 @@ const database = matches[0]
if (!database || typeof database.uuid !== "string" || !/^[a-f0-9-]{36}$/.test(database.uuid)) throw new Error(`D1 database ${databaseName} was not resolved after provisioning.`)

const template = parseJsonc(await readFile(templatePath, "utf8"))
if (typeof template.main === "string" && !template.main.startsWith("/")) template.main = resolve(dirname(templatePath), template.main)
const configured = template.d1_databases?.find((candidate) => candidate.binding === binding && candidate.database_name === databaseName)
if (!configured) throw new Error(`D1 template does not declare ${binding} for ${databaseName}.`)
configured.database_id = database.uuid
Expand Down
1 change: 1 addition & 0 deletions tests/cloudflare-d1-provisioner.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ test("D1 provisioner creates once and emits a deployable config deterministicall
assert.deepEqual(second, first)
const config = JSON.parse(await readFile(output, "utf8"))
assert.equal(config.d1_databases[0].database_id, first.databaseId)
assert.equal(config.main, join(directory, "src/worker-d1.ts"))
const invocations = (await readFile(calls, "utf8")).trim().split("\n").map(JSON.parse)
assert.equal(invocations.filter((args) => args[1] === "create").length, 1)
} finally {
Expand Down