diff --git a/.changeset/dark-ads-appear.md b/.changeset/dark-ads-appear.md new file mode 100644 index 000000000000..572ab32ce053 --- /dev/null +++ b/.changeset/dark-ads-appear.md @@ -0,0 +1,5 @@ +--- +"@cloudflare/devprod-status-bot": minor +--- + +Notify when security advisories are submitted to workers-sdk diff --git a/.changeset/fair-tools-happen.md b/.changeset/fair-tools-happen.md new file mode 100644 index 000000000000..a3929f6fb42d --- /dev/null +++ b/.changeset/fair-tools-happen.md @@ -0,0 +1,5 @@ +--- +"wrangler": minor +--- + +Improve telemetry errors being sent to Sentry by `wrangler init` when it delegates to C3 by ensuring that they contain the output of the C3 execution. diff --git a/.changeset/fix-jsonc-config-filename.md b/.changeset/fix-jsonc-config-filename.md new file mode 100644 index 000000000000..c63b397800f6 --- /dev/null +++ b/.changeset/fix-jsonc-config-filename.md @@ -0,0 +1,10 @@ +--- +"wrangler": patch +"@cloudflare/workers-utils": patch +--- + +Fix `configFileName` returning wrong filename for `.jsonc` config files + +Previously, users with a `wrangler.jsonc` config file would see error messages and hints referring to `wrangler.json` instead of `wrangler.jsonc`. This was because the `configFormat` function collapsed both `.json` and `.jsonc` files into a single `"jsonc"` value, losing the distinction between them. + +Now `configFormat` returns `"json"` for `.json` files and `"jsonc"` for `.jsonc` files, allowing `configFileName` to return the correct filename for each format. diff --git a/.changeset/happy-clubs-kiss.md b/.changeset/happy-clubs-kiss.md new file mode 100644 index 000000000000..8aaaed9e2e35 --- /dev/null +++ b/.changeset/happy-clubs-kiss.md @@ -0,0 +1,7 @@ +--- +"create-cloudflare": patch +--- + +Bump the version of `@cloudflare/vitest-pool-workers` in the hello-world templates from `^0.8.19` to `^0.12.4` + +The version of the `@cloudflare/vitest-pool-workers` in the hello-world templates is currently `^0.8.19`, since the package is pre v1, the Caret syntax only installs the latest `0.8.x` version of the package, which is a bit outdated. So the changes here manually keep the package more up to date. diff --git a/.changeset/purple-lemons-sip.md b/.changeset/purple-lemons-sip.md new file mode 100644 index 000000000000..2d878f0dc227 --- /dev/null +++ b/.changeset/purple-lemons-sip.md @@ -0,0 +1,6 @@ +--- +"@cloudflare/vitest-pool-workers": patch +"miniflare": patch +--- + +Bump capnp-es to ^0.0.14 diff --git a/packages/create-cloudflare/templates/hello-world-with-assets/js/package.json b/packages/create-cloudflare/templates/hello-world-with-assets/js/package.json index b6f128442a39..11573a9e35de 100644 --- a/packages/create-cloudflare/templates/hello-world-with-assets/js/package.json +++ b/packages/create-cloudflare/templates/hello-world-with-assets/js/package.json @@ -9,7 +9,7 @@ "test": "vitest" }, "devDependencies": { - "@cloudflare/vitest-pool-workers": "^0.8.19", + "@cloudflare/vitest-pool-workers": "^0.12.4", "wrangler": "^3.101.0", "vitest": "~3.2.0" } diff --git a/packages/create-cloudflare/templates/hello-world-with-assets/ts/package.json b/packages/create-cloudflare/templates/hello-world-with-assets/ts/package.json index c97511cef832..4104fd8ffb4f 100644 --- a/packages/create-cloudflare/templates/hello-world-with-assets/ts/package.json +++ b/packages/create-cloudflare/templates/hello-world-with-assets/ts/package.json @@ -10,7 +10,7 @@ "cf-typegen": "wrangler types" }, "devDependencies": { - "@cloudflare/vitest-pool-workers": "^0.8.19", + "@cloudflare/vitest-pool-workers": "^0.12.4", "typescript": "^5.5.2", "vitest": "~3.2.0", "wrangler": "^3.101.0" diff --git a/packages/create-cloudflare/templates/hello-world/js/package.json b/packages/create-cloudflare/templates/hello-world/js/package.json index b6f128442a39..11573a9e35de 100644 --- a/packages/create-cloudflare/templates/hello-world/js/package.json +++ b/packages/create-cloudflare/templates/hello-world/js/package.json @@ -9,7 +9,7 @@ "test": "vitest" }, "devDependencies": { - "@cloudflare/vitest-pool-workers": "^0.8.19", + "@cloudflare/vitest-pool-workers": "^0.12.4", "wrangler": "^3.101.0", "vitest": "~3.2.0" } diff --git a/packages/create-cloudflare/templates/hello-world/ts/package.json b/packages/create-cloudflare/templates/hello-world/ts/package.json index c97511cef832..4104fd8ffb4f 100644 --- a/packages/create-cloudflare/templates/hello-world/ts/package.json +++ b/packages/create-cloudflare/templates/hello-world/ts/package.json @@ -10,7 +10,7 @@ "cf-typegen": "wrangler types" }, "devDependencies": { - "@cloudflare/vitest-pool-workers": "^0.8.19", + "@cloudflare/vitest-pool-workers": "^0.12.4", "typescript": "^5.5.2", "vitest": "~3.2.0", "wrangler": "^3.101.0" diff --git a/packages/devprod-status-bot/src/index.ts b/packages/devprod-status-bot/src/index.ts index 0b3abdfc87f3..96984a317379 100644 --- a/packages/devprod-status-bot/src/index.ts +++ b/packages/devprod-status-bot/src/index.ts @@ -274,6 +274,30 @@ function isIssueOrPREvent( return null; } +// Repository advisory event type (not yet in @octokit/webhooks-types) +interface RepositoryAdvisoryEvent { + action: "reported" | "published"; + repository_advisory: { + ghsa_id: string; + html_url: string; + summary: string; + description: string; + }; +} + +function isRepositoryAdvisoryEvent( + message: WebhookEvent +): RepositoryAdvisoryEvent | null { + if ( + "repository_advisory" in message && + "action" in message && + message.action === "reported" + ) { + return message as RepositoryAdvisoryEvent; + } + return null; +} + async function sendSecurityAlert( webhookUrl: string, { @@ -347,6 +371,62 @@ async function sendSecurityAlert( ); } +async function sendRepositoryAdvisoryAlert( + webhookUrl: string, + advisoryEvent: RepositoryAdvisoryEvent +) { + const advisory = advisoryEvent.repository_advisory; + + return sendMessage( + webhookUrl, + { + cardsV2: [ + { + cardId: "unique-card-id", + card: { + header: { + title: `🔐 Repository Security Advisory Reported`, + subtitle: advisory.summary, + }, + sections: [ + { + collapsible: true, + widgets: [ + { + textParagraph: { + text: advisory.description, + }, + }, + ], + }, + { + collapsible: false, + widgets: [ + { + buttonList: { + buttons: [ + { + text: "View Advisory", + onClick: { + openLink: { + url: advisory.html_url, + }, + }, + }, + ], + }, + }, + ], + }, + ], + }, + }, + ], + }, + "-repository-advisory-" + advisory.ghsa_id + ); +} + async function sendUpcomingMeetingMessage(webhookUrl: string, ai: Ai) { const message = await getBotMessage( ai, @@ -514,9 +594,18 @@ export default { env.GITHUB_PAT, body ); + // Flags suspicious issues/PRs for review if (maybeSecurityIssue) { await sendSecurityAlert(env.ALERTS_WEBHOOK, maybeSecurityIssue); } + // Notifies when a repository advisory is reported to workers-sdk + const maybeRepositoryAdvisory = isRepositoryAdvisoryEvent(body); + if (maybeRepositoryAdvisory) { + await sendRepositoryAdvisoryAlert( + env.ALERTS_WEBHOOK, + maybeRepositoryAdvisory + ); + } } if (url.pathname.startsWith("/pr-project") && request.method === "POST") { diff --git a/packages/miniflare/package.json b/packages/miniflare/package.json index 1e535f12e2f4..031ca7150a94 100644 --- a/packages/miniflare/package.json +++ b/packages/miniflare/package.json @@ -72,7 +72,7 @@ "@types/ws": "^8.5.7", "acorn": "8.14.0", "acorn-walk": "8.3.2", - "capnp-es": "^0.0.11", + "capnp-es": "catalog:default", "capnweb": "^0.1.0", "chokidar": "^4.0.1", "concurrently": "^8.2.2", diff --git a/packages/miniflare/src/runtime/config/generated/workerd.ts b/packages/miniflare/src/runtime/config/generated/workerd.ts index c96c20649690..36df22d4c0b0 100644 --- a/packages/miniflare/src/runtime/config/generated/workerd.ts +++ b/packages/miniflare/src/runtime/config/generated/workerd.ts @@ -1,7 +1,7 @@ // This file has been automatically generated by capnp-es. import * as $ from "capnp-es"; -export const _capnpFileId = BigInt("0xe6afd26682091c01"); +export const _capnpFileId = 0xe6afd26682091c01n; /** * Top-level configuration for a workerd instance. * diff --git a/packages/vitest-pool-workers/package.json b/packages/vitest-pool-workers/package.json index b128dc42028b..4a5990fd7fd3 100644 --- a/packages/vitest-pool-workers/package.json +++ b/packages/vitest-pool-workers/package.json @@ -70,7 +70,7 @@ "@vitest/runner": "catalog:default", "@vitest/snapshot": "catalog:default", "birpc": "0.2.14", - "capnp-es": "^0.0.11", + "capnp-es": "catalog:default", "devalue": "^5.3.2", "eslint": "catalog:default", "get-port": "^7.1.0", diff --git a/packages/vitest-pool-workers/scripts/rtti/rtti.js b/packages/vitest-pool-workers/scripts/rtti/rtti.js index 417cfec735bc..f31abe48e60e 100644 --- a/packages/vitest-pool-workers/scripts/rtti/rtti.js +++ b/packages/vitest-pool-workers/scripts/rtti/rtti.js @@ -1,6 +1,6 @@ // This file has been automatically generated by capnp-es. import * as $ from "capnp-es"; -export const _capnpFileId = BigInt("0xb042d6da9e1721ad"); +export const _capnpFileId = 0xb042d6da9e1721adn; export const Type_Which = { /** * statically unknown type diff --git a/packages/workers-utils/src/config/index.ts b/packages/workers-utils/src/config/index.ts index d6e2a0987752..8b5f4c92c64d 100644 --- a/packages/workers-utils/src/config/index.ts +++ b/packages/workers-utils/src/config/index.ts @@ -20,23 +20,30 @@ export type { export function configFormat( configPath: string | undefined -): "jsonc" | "toml" | "none" { +): "json" | "jsonc" | "toml" | "none" { if (configPath?.endsWith("toml")) { return "toml"; - } else if (configPath?.endsWith("json") || configPath?.endsWith("jsonc")) { + } + if (configPath?.endsWith("jsonc")) { return "jsonc"; } + if (configPath?.endsWith("json")) { + return "json"; + } return "none"; } export function configFileName(configPath: string | undefined) { const format = configFormat(configPath); - if (format === "toml") { - return "wrangler.toml"; - } else if (format === "jsonc") { - return "wrangler.json"; - } else { - return "Wrangler configuration"; + switch (format) { + case "toml": + return "wrangler.toml"; + case "json": + return "wrangler.json"; + case "jsonc": + return "wrangler.jsonc"; + default: + return "Wrangler configuration"; } } diff --git a/packages/workers-utils/src/constants.ts b/packages/workers-utils/src/constants.ts index 5b25e93b75c8..b326a6cfd627 100644 --- a/packages/workers-utils/src/constants.ts +++ b/packages/workers-utils/src/constants.ts @@ -7,3 +7,8 @@ export const SERVICE_TAG_PREFIX = "cf:service="; export const ENVIRONMENT_TAG_PREFIX = "cf:environment="; export const PATH_TO_DEPLOY_CONFIG = ".wrangler/deploy/config.json"; + +/** + * Config formats that use JSON parsing + */ +export const JSON_CONFIG_FORMATS: readonly string[] = ["json", "jsonc"]; diff --git a/packages/workers-utils/tests/config/config-format.test.ts b/packages/workers-utils/tests/config/config-format.test.ts new file mode 100644 index 000000000000..f8c169fc6424 --- /dev/null +++ b/packages/workers-utils/tests/config/config-format.test.ts @@ -0,0 +1,47 @@ +import { describe, expect, it } from "vitest"; +import { configFileName, configFormat } from "../../src/config"; + +describe("configFormat", () => { + it("returns 'toml' for .toml files", () => { + expect(configFormat("wrangler.toml")).toBe("toml"); + expect(configFormat("/path/to/wrangler.toml")).toBe("toml"); + }); + + it("returns 'json' for .json files", () => { + expect(configFormat("wrangler.json")).toBe("json"); + expect(configFormat("/path/to/wrangler.json")).toBe("json"); + }); + + it("returns 'jsonc' for .jsonc files", () => { + expect(configFormat("wrangler.jsonc")).toBe("jsonc"); + expect(configFormat("/path/to/wrangler.jsonc")).toBe("jsonc"); + }); + + it("returns 'none' for unknown formats", () => { + expect(configFormat("wrangler.yaml")).toBe("none"); + expect(configFormat("wrangler.yml")).toBe("none"); + expect(configFormat(undefined)).toBe("none"); + }); +}); + +describe("configFileName", () => { + it("returns 'wrangler.toml' for .toml config paths", () => { + expect(configFileName("wrangler.toml")).toBe("wrangler.toml"); + expect(configFileName("/path/to/wrangler.toml")).toBe("wrangler.toml"); + }); + + it("returns 'wrangler.json' for .json config paths", () => { + expect(configFileName("wrangler.json")).toBe("wrangler.json"); + expect(configFileName("/path/to/wrangler.json")).toBe("wrangler.json"); + }); + + it("returns 'wrangler.jsonc' for .jsonc config paths", () => { + expect(configFileName("wrangler.jsonc")).toBe("wrangler.jsonc"); + expect(configFileName("/path/to/wrangler.jsonc")).toBe("wrangler.jsonc"); + }); + + it("returns 'Wrangler configuration' for unknown formats", () => { + expect(configFileName("wrangler.yaml")).toBe("Wrangler configuration"); + expect(configFileName(undefined)).toBe("Wrangler configuration"); + }); +}); diff --git a/packages/wrangler/src/__tests__/init.test.ts b/packages/wrangler/src/__tests__/init.test.ts index 72253d80957a..81da3fd6b60e 100644 --- a/packages/wrangler/src/__tests__/init.test.ts +++ b/packages/wrangler/src/__tests__/init.test.ts @@ -76,7 +76,7 @@ describe("init", () => { "mockpm", ["create", "cloudflare@^2.5.0"], { - stdio: "inherit", + stdio: ["inherit", "pipe", "pipe"], } ); }); @@ -87,7 +87,9 @@ describe("init", () => { expect(execa).toHaveBeenCalledWith( "mockpm", ["create", "cloudflare@^2.5.0", "--wrangler-defaults"], - { stdio: "inherit" } + { + stdio: ["inherit", "pipe", "pipe"], + } ); }); @@ -126,7 +128,7 @@ describe("init", () => { "mockpm", ["run", "create-cloudflare"], { - stdio: "inherit", + stdio: ["inherit", "pipe", "pipe"], } ); }); @@ -137,7 +139,9 @@ describe("init", () => { expect(execa).toHaveBeenCalledWith( "mockpm", ["run", "create-cloudflare", "--wrangler-defaults"], - { stdio: "inherit" } + { + stdio: ["inherit", "pipe", "pipe"], + } ); }); }); @@ -158,7 +162,7 @@ describe("init", () => { env: { CREATE_CLOUDFLARE_TELEMETRY_DISABLED: "1", }, - stdio: "inherit", + stdio: ["inherit", "pipe", "pipe"], } ); }); @@ -811,7 +815,9 @@ describe("init", () => { "--existing-script", "existing-memory-crystal", ], - { stdio: "inherit" } + { + stdio: ["inherit", "pipe", "pipe"], + } ); }); it("should download routes + custom domains + workers dev", async () => { diff --git a/packages/wrangler/src/__tests__/type-generation.test.ts b/packages/wrangler/src/__tests__/type-generation.test.ts index 559243490369..ea83db91a66e 100644 --- a/packages/wrangler/src/__tests__/type-generation.test.ts +++ b/packages/wrangler/src/__tests__/type-generation.test.ts @@ -420,7 +420,7 @@ describe("generate types", () => { 📖 Read about runtime types https://developers.cloudflare.com/workers/languages/typescript/#generate-types - 📣 Remember to rerun 'wrangler types' after you change your wrangler.json file. + 📣 Remember to rerun 'wrangler types' after you change your wrangler.jsonc file. ⛅️ wrangler x.x.x @@ -443,7 +443,7 @@ describe("generate types", () => { 📖 Read about runtime types https://developers.cloudflare.com/workers/languages/typescript/#generate-types - 📣 Remember to rerun 'wrangler types' after you change your wrangler.json file. + 📣 Remember to rerun 'wrangler types' after you change your wrangler.jsonc file. ⛅️ wrangler x.x.x @@ -466,7 +466,7 @@ describe("generate types", () => { 📖 Read about runtime types https://developers.cloudflare.com/workers/languages/typescript/#generate-types - 📣 Remember to rerun 'wrangler types' after you change your wrangler.json file. + 📣 Remember to rerun 'wrangler types' after you change your wrangler.jsonc file. " `); }); @@ -571,7 +571,7 @@ describe("generate types", () => { ──────────────────────────────────────────────────────────── ✨ Types written to worker-configuration.d.ts - 📣 Remember to rerun 'wrangler types' after you change your wrangler.json file. + 📣 Remember to rerun 'wrangler types' after you change your wrangler.jsonc file. " `); }); @@ -688,7 +688,7 @@ describe("generate types", () => { ──────────────────────────────────────────────────────────── ✨ Types written to worker-configuration.d.ts - 📣 Remember to rerun 'wrangler types' after you change your wrangler.json file. + 📣 Remember to rerun 'wrangler types' after you change your wrangler.jsonc file. " `); }); @@ -863,7 +863,7 @@ describe("generate types", () => { ──────────────────────────────────────────────────────────── ✨ Types written to a/worker-configuration.d.ts - 📣 Remember to rerun 'wrangler types' after you change your wrangler.json file. + 📣 Remember to rerun 'wrangler types' after you change your wrangler.jsonc file. " `); }); @@ -933,7 +933,7 @@ describe("generate types", () => { No project types to add. ──────────────────────────────────────────────────────────── - 📣 Remember to rerun 'wrangler types' after you change your wrangler.json file. + 📣 Remember to rerun 'wrangler types' after you change your wrangler.jsonc file. " `); }); @@ -978,7 +978,7 @@ describe("generate types", () => { 📖 Read about runtime types https://developers.cloudflare.com/workers/languages/typescript/#generate-types - 📣 Remember to rerun 'wrangler types' after you change your wrangler.json file. + 📣 Remember to rerun 'wrangler types' after you change your wrangler.jsonc file. " `); }); @@ -1015,7 +1015,7 @@ describe("generate types", () => { ──────────────────────────────────────────────────────────── ✨ Types written to worker-configuration.d.ts - 📣 Remember to rerun 'wrangler types' after you change your wrangler.json file. + 📣 Remember to rerun 'wrangler types' after you change your wrangler.jsonc file. " `); }); @@ -1082,7 +1082,7 @@ describe("generate types", () => { ──────────────────────────────────────────────────────────── ✨ Types written to worker-configuration.d.ts - 📣 Remember to rerun 'wrangler types' after you change your wrangler.json file. + 📣 Remember to rerun 'wrangler types' after you change your wrangler.jsonc file. " `); }); @@ -1123,7 +1123,7 @@ describe("generate types", () => { 📖 Read about runtime types https://developers.cloudflare.com/workers/languages/typescript/#generate-types - 📣 Remember to rerun 'wrangler types' after you change your wrangler.json file. + 📣 Remember to rerun 'wrangler types' after you change your wrangler.jsonc file. " `); }); @@ -1159,7 +1159,7 @@ describe("generate types", () => { ──────────────────────────────────────────────────────────── ✨ Types written to worker-configuration.d.ts - 📣 Remember to rerun 'wrangler types' after you change your wrangler.json file. + 📣 Remember to rerun 'wrangler types' after you change your wrangler.jsonc file. " `); }); @@ -1217,7 +1217,7 @@ describe("generate types", () => { ──────────────────────────────────────────────────────────── ✨ Types written to worker-configuration.d.ts - 📣 Remember to rerun 'wrangler types' after you change your wrangler.json file. + 📣 Remember to rerun 'wrangler types' after you change your wrangler.jsonc file. " `); }); @@ -1269,7 +1269,7 @@ describe("generate types", () => { ──────────────────────────────────────────────────────────── ✨ Types written to worker-configuration.d.ts - 📣 Remember to rerun 'wrangler types' after you change your wrangler.json file. + 📣 Remember to rerun 'wrangler types' after you change your wrangler.jsonc file. " `); // Verify that .dev.vars secrets are NOT included @@ -1321,7 +1321,7 @@ describe("generate types", () => { ──────────────────────────────────────────────────────────── ✨ Types written to worker-configuration.d.ts - 📣 Remember to rerun 'wrangler types' after you change your wrangler.json file. + 📣 Remember to rerun 'wrangler types' after you change your wrangler.jsonc file. " `); }); @@ -1361,7 +1361,7 @@ describe("generate types", () => { ──────────────────────────────────────────────────────────── ✨ Types written to worker-configuration.d.ts - 📣 Remember to rerun 'wrangler types' after you change your wrangler.json file. + 📣 Remember to rerun 'wrangler types' after you change your wrangler.jsonc file. " `); }); @@ -1404,7 +1404,7 @@ describe("generate types", () => { ──────────────────────────────────────────────────────────── ✨ Types written to worker-configuration.d.ts - 📣 Remember to rerun 'wrangler types' after you change your wrangler.json file. + 📣 Remember to rerun 'wrangler types' after you change your wrangler.jsonc file. " `); }); @@ -1455,7 +1455,7 @@ describe("generate types", () => { ──────────────────────────────────────────────────────────── ✨ Types written to worker-configuration.d.ts - 📣 Remember to rerun 'wrangler types' after you change your wrangler.json file. + 📣 Remember to rerun 'wrangler types' after you change your wrangler.jsonc file. " `); }); @@ -1513,7 +1513,7 @@ describe("generate types", () => { ──────────────────────────────────────────────────────────── ✨ Types written to worker-configuration.d.ts - 📣 Remember to rerun 'wrangler types' after you change your wrangler.json file. + 📣 Remember to rerun 'wrangler types' after you change your wrangler.jsonc file. " `); }); @@ -1540,7 +1540,7 @@ describe("generate types", () => { ──────────────────────────────────────────────────────────── ✨ Types written to worker-configuration.d.ts - 📣 Remember to rerun 'wrangler types' after you change your wrangler.json file. + 📣 Remember to rerun 'wrangler types' after you change your wrangler.jsonc file. " `); }); @@ -1579,7 +1579,7 @@ describe("generate types", () => { ──────────────────────────────────────────────────────────── ✨ Types written to worker-configuration.d.ts - 📣 Remember to rerun 'wrangler types' after you change your wrangler.json file. + 📣 Remember to rerun 'wrangler types' after you change your wrangler.jsonc file. " `); }); @@ -1790,7 +1790,7 @@ describe("generate types", () => { 📖 Read about runtime types https://developers.cloudflare.com/workers/languages/typescript/#generate-types - 📣 Remember to rerun 'wrangler types' after you change your wrangler.json file. + 📣 Remember to rerun 'wrangler types' after you change your wrangler.jsonc file. " `); }); @@ -1826,7 +1826,7 @@ describe("generate types", () => { 📖 Read about runtime types https://developers.cloudflare.com/workers/languages/typescript/#generate-types - 📣 Remember to rerun 'wrangler types' after you change your wrangler.json file. + 📣 Remember to rerun 'wrangler types' after you change your wrangler.jsonc file. " `); }); diff --git a/packages/wrangler/src/init.ts b/packages/wrangler/src/init.ts index 65afc9462f99..42d0bf37ff79 100644 --- a/packages/wrangler/src/init.ts +++ b/packages/wrangler/src/init.ts @@ -20,6 +20,7 @@ import * as shellquote from "./utils/shell-quote"; import { isWorkerNotFoundError } from "./utils/worker-not-found-error"; import type { PackageManager } from "./package-manager"; import type { ServiceMetadataRes } from "@cloudflare/workers-utils"; +import type { ExecaError } from "execa"; import type { ReadableStream } from "node:stream/web"; export const init = createCommand({ @@ -133,12 +134,28 @@ export const init = createCommand({ // if telemetry is disabled in wrangler, prevent c3 from sending metrics too const metricsConfig = readMetricsConfig(); - await execa(packageManager.type, c3Arguments, { - stdio: "inherit", - ...(metricsConfig.permission?.enabled === false && { - env: { CREATE_CLOUDFLARE_TELEMETRY_DISABLED: "1" }, - }), - }); + try { + const childProcess = execa(packageManager.type, c3Arguments, { + // Note: we need to pipe stdout and stderr otherwise execa won't include + // those in the command's result/error, but we want it to so that we + // can include those in the error Sentry receives + stdio: ["inherit", "pipe", "pipe"], + ...(metricsConfig.permission?.enabled === false && { + env: { CREATE_CLOUDFLARE_TELEMETRY_DISABLED: "1" }, + }), + }); + childProcess.stdout?.pipe(process.stdout); + childProcess.stderr?.pipe(process.stderr); + await childProcess; + } catch (e: unknown) { + const execaError = e as ExecaError; + throw new Error(execaError.shortMessage, { + // We include the execaError as the cause, in this way this + // will be reflected in Sentry allowing us to better monitor + // C3 errors + cause: execaError, + }); + } } }, }); diff --git a/packages/wrangler/src/utils/add-created-resource-config.ts b/packages/wrangler/src/utils/add-created-resource-config.ts index e5aa0f5fe5ab..5d5affd581fb 100644 --- a/packages/wrangler/src/utils/add-created-resource-config.ts +++ b/packages/wrangler/src/utils/add-created-resource-config.ts @@ -3,6 +3,7 @@ import { experimental_patchConfig, formatConfigSnippet, friendlyBindingNames, + JSON_CONFIG_FORMATS, } from "@cloudflare/workers-utils"; import { confirm, prompt } from "../dialogs"; import { logger } from "../logger"; @@ -94,8 +95,9 @@ export async function createdResourceConfig( ) ); - // This is a JSONC config file that we're capable of editing - if (configPath && configFormat(configPath) === "jsonc") { + // This is a JSON config file that we're capable of editing + const format = configFormat(configPath); + if (configPath && JSON_CONFIG_FORMATS.includes(format)) { const writeToConfig = defaults?.binding ?? defaults?.updateConfig ?? diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0c96e1217925..26d1d7f1c3cc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -27,6 +27,9 @@ catalogs: '@vitest/ui': specifier: ~3.2.0 version: 3.2.3 + capnp-es: + specifier: ^0.0.14 + version: 0.0.14 esbuild: specifier: 0.27.0 version: 0.27.0 @@ -1977,8 +1980,8 @@ importers: specifier: 8.3.2 version: 8.3.2 capnp-es: - specifier: ^0.0.11 - version: 0.0.11(typescript@5.8.3) + specifier: catalog:default + version: 0.0.14(typescript@5.8.3) capnweb: specifier: ^0.1.0 version: 0.1.0 @@ -3472,8 +3475,8 @@ importers: specifier: 0.2.14 version: 0.2.14 capnp-es: - specifier: ^0.0.11 - version: 0.0.11(typescript@5.8.3) + specifier: catalog:default + version: 0.0.14(typescript@5.8.3) devalue: specifier: ^5.3.2 version: 5.3.2 @@ -8708,8 +8711,8 @@ packages: caniuse-lite@1.0.30001669: resolution: {integrity: sha512-DlWzFDJqstqtIVx1zeSpIMLjunf5SmwOw0N2Ck/QSQdS8PLS4+9HrLaYei4w8BIAL7IB/UEDu889d8vhCTPA0w==} - capnp-es@0.0.11: - resolution: {integrity: sha512-/M2sGcTIjA2UQC6mnqidCUcfGdVmXGV8DDmNRXMU0ZdiK7TmALjxzJwlLc0UQb/YNy3/xu5OgKktLede69fsnw==} + capnp-es@0.0.14: + resolution: {integrity: sha512-8lWj4GJISiqRSlAJGkWpI4Azib7QY5UDIkqxeHcI7aAnXVk9SFuWxl1Fme+2HhzNANV0WTJqwUZvvXvloc3sBA==} hasBin: true peerDependencies: typescript: ^5.7.3 @@ -19157,7 +19160,7 @@ snapshots: caniuse-lite@1.0.30001669: {} - capnp-es@0.0.11(typescript@5.8.3): + capnp-es@0.0.14(typescript@5.8.3): optionalDependencies: typescript: 5.8.3 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 0bfbaf7997c8..84c175cdef2c 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -42,6 +42,7 @@ catalog: # However, some packages (pages-shared, workers-shared, etc...) need to be tested using vitest-pool-workers but are themselves # ultimately included in vitest-pool-workers (through Wrangler), causing a circular dependency. "@cloudflare/vitest-pool-workers": "^0.10.11" + "capnp-es": "^0.0.14" catalogs: vite-plugin: diff --git a/tools/deployments/validate-changesets.ts b/tools/deployments/validate-changesets.ts index 2aaa5bf21794..943d211f2f7b 100644 --- a/tools/deployments/validate-changesets.ts +++ b/tools/deployments/validate-changesets.ts @@ -31,10 +31,15 @@ export function validateChangesets( } // TEMPORARILY BLOCK PACKAGES THAT WOULD DEPLOY WORKERS + const ALLOWED_PRIVATE_PACKAGES = [ + "@cloudflare/workers-shared", + "@cloudflare/quick-edit", + "@cloudflare/devprod-status-bot", + ]; if ( packages.get(release.name)?.["workers-sdk"]?.deploy && // Exception: deployments for these workers are allowed now - release.name !== "@cloudflare/workers-shared" + !ALLOWED_PRIVATE_PACKAGES.includes(release.name) ) { errors.push( `Currently we are not allowing changes to package "${release.name}" in changeset at "${file}" since it would trigger a Worker/Pages deployment.`