diff --git a/.changeset/late-kings-peel.md b/.changeset/late-kings-peel.md new file mode 100644 index 000000000000..296aa0951ae0 --- /dev/null +++ b/.changeset/late-kings-peel.md @@ -0,0 +1,5 @@ +--- +"wrangler": minor +--- + +feat: Add deployment http targets to wrangler deploy logs, and add url to pages deploy logs diff --git a/packages/wrangler/src/__tests__/deploy.test.ts b/packages/wrangler/src/__tests__/deploy.test.ts index f9e4bb9b4bb5..cbc821712e5f 100644 --- a/packages/wrangler/src/__tests__/deploy.test.ts +++ b/packages/wrangler/src/__tests__/deploy.test.ts @@ -89,6 +89,63 @@ describe("deploy", () => { clearDialogs(); }); + it("should output log file with deployment details", async () => { + vi.stubEnv("WRANGLER_OUTPUT_FILE_DIRECTORY", "output"); + vi.stubEnv("WRANGLER_OUTPUT_FILE_PATH", ""); + writeWorkerSource(); + writeWranglerToml({ + routes: ["example.com/some-route/*"], + workers_dev: true, + }); + mockSubDomainRequest(); + mockUploadWorkerRequest(); + mockUpdateWorkerRequest({ enabled: false }); + mockPublishRoutesRequest({ routes: ["example.com/some-route/*"] }); + + await runWrangler("deploy ./index.js"); + expect(std.out).toMatchInlineSnapshot(` + "Total Upload: xx KiB / gzip: xx KiB + Worker Startup Time: 100 ms + Uploaded test-name (TIMINGS) + Published test-name (TIMINGS) + https://test-name.test-sub-domain.workers.dev + example.com/some-route/* + Current Deployment ID: Galaxy-Class + Current Version ID: Galaxy-Class + + + Note: Deployment ID has been renamed to Version ID. Deployment ID is present to maintain compatibility with the previous behavior of this command. This output will change in a future version of Wrangler. To learn more visit: https://developers.cloudflare.com/workers/configuration/versions-and-deployments" + `); + expect(std.err).toMatchInlineSnapshot(`""`); + + const outputFilePaths = fs.readdirSync("output"); + + expect(outputFilePaths.length).toEqual(1); + expect(outputFilePaths[0]).toMatch(/wrangler-output-.+\.json/); + const outputFile = fs.readFileSync( + path.join("output", outputFilePaths[0]), + "utf8" + ); + const entries = outputFile + .split("\n") + .filter(Boolean) + .map((e) => JSON.parse(e)); + + expect(entries.find((e) => e.type === "deploy")).toMatchObject({ + targets: [ + "https://test-name.test-sub-domain.workers.dev", + "example.com/some-route/*", + ], + // Omitting timestamp for matching + // timestamp: ... + type: "deploy", + version: 1, + version_id: "Galaxy-Class", + worker_name: "test-name", + worker_tag: "tag:test-name", + }); + }); + it("should resolve wrangler.toml relative to the entrypoint", async () => { fs.mkdirSync("./some-path/worker", { recursive: true }); fs.writeFileSync( diff --git a/packages/wrangler/src/__tests__/output.test.ts b/packages/wrangler/src/__tests__/output.test.ts index caf24211c77b..8a548130b757 100644 --- a/packages/wrangler/src/__tests__/output.test.ts +++ b/packages/wrangler/src/__tests__/output.test.ts @@ -85,6 +85,7 @@ describe("writeOutput()", () => { worker_name: "Worker", worker_tag: "ABCDE12345", version_id: "1234", + targets: undefined, }); const outputFile = readFileSync(WRANGLER_OUTPUT_FILE_PATH, "utf8"); @@ -102,6 +103,7 @@ describe("writeOutput()", () => { worker_name: "Worker", worker_tag: "ABCDE12345", version_id: "1234", + targets: undefined, }, ]); }); @@ -148,6 +150,7 @@ describe("writeOutput()", () => { worker_name: "Worker", worker_tag: "ABCDE12345", version_id: "1234", + targets: undefined, }); const outputFilePaths = readdirSync("output"); @@ -168,6 +171,7 @@ describe("writeOutput()", () => { worker_name: "Worker", worker_tag: "ABCDE12345", version_id: "1234", + targets: undefined, }, ]); }); diff --git a/packages/wrangler/src/deploy/deploy.ts b/packages/wrangler/src/deploy/deploy.ts index 84bfaf9d067e..006b94258cf8 100644 --- a/packages/wrangler/src/deploy/deploy.ts +++ b/packages/wrangler/src/deploy/deploy.ts @@ -312,6 +312,7 @@ export default async function deploy(props: Props): Promise<{ sourceMapSize?: number; deploymentId: string | null; workerTag: string | null; + targets?: string[]; }> { // TODO: warn if git/hg has uncommitted changes const { config, accountId, name } = props; @@ -866,14 +867,19 @@ See https://developers.cloudflare.com/workers/platform/compatibility-dates for m } // deploy triggers - await triggersDeploy(props); + const targets = await triggersDeploy(props); logger.log("Current Deployment ID:", deploymentId); logger.log("Current Version ID:", deploymentId); logVersionIdChange(); - return { sourceMapSize, deploymentId, workerTag }; + return { + sourceMapSize, + deploymentId, + workerTag, + targets: targets ?? [], + }; } function deployWfpUserWorker( diff --git a/packages/wrangler/src/deploy/index.ts b/packages/wrangler/src/deploy/index.ts index 446a73aa396b..6a7d1a6d0322 100644 --- a/packages/wrangler/src/deploy/index.ts +++ b/packages/wrangler/src/deploy/index.ts @@ -326,7 +326,7 @@ export async function deployHandler( const beforeUpload = Date.now(); const name = getScriptName(args, config); - const { sourceMapSize, deploymentId, workerTag } = await deploy({ + const { sourceMapSize, deploymentId, workerTag, targets } = await deploy({ config, accountId, name, @@ -370,6 +370,7 @@ export async function deployHandler( worker_tag: workerTag, // Note that the `deploymentId` returned from a simple deployment is actually the versionId of the uploaded version. version_id: deploymentId, + targets, }); await metrics.sendMetricsEvent( diff --git a/packages/wrangler/src/output.ts b/packages/wrangler/src/output.ts index b53035a8b0eb..814e9665f63e 100644 --- a/packages/wrangler/src/output.ts +++ b/packages/wrangler/src/output.ts @@ -68,6 +68,7 @@ interface OutputEntryBase { export type OutputEntry = | OutputEntrySession | OutputEntryDeployment + | OutputEntryPagesDeployment | OutputEntryVersionUpload | OutputEntryVersionDeployment; @@ -92,6 +93,19 @@ export interface OutputEntryDeployment extends OutputEntryBase<"deploy"> { worker_tag: string | null; /** A GUID that identifies this deployed version of the Worker. This version is associated with an automatically created deployment, with this version set at 100%. */ version_id: string | null; + /** A list of URLs that represent the HTTP triggers associated with this deployment */ + targets: string[] | undefined; +} + +export interface OutputEntryPagesDeployment + extends OutputEntryBase<"pages-deploy"> { + version: 1; + /** The name of the Pages project. */ + pages_project: string | null; + /** A GUID that identifies this Pages deployment. */ + deployment_id: string | null; + /** The URL associated with this deployment */ + url: string | undefined; } export interface OutputEntryVersionUpload diff --git a/packages/wrangler/src/pages/deploy.tsx b/packages/wrangler/src/pages/deploy.tsx index 57c7ec3b0f9b..4506ecde2873 100644 --- a/packages/wrangler/src/pages/deploy.tsx +++ b/packages/wrangler/src/pages/deploy.tsx @@ -9,6 +9,7 @@ import { prompt } from "../dialogs"; import { FatalError } from "../errors"; import { logger } from "../logger"; import * as metrics from "../metrics"; +import { writeOutput } from "../output"; import { requireAuth } from "../user"; import { MAX_DEPLOYMENT_STATUS_ATTEMPTS, @@ -433,6 +434,14 @@ ${failureMessage}`, ); } + writeOutput({ + type: "pages-deploy", + version: 1, + pages_project: deploymentResponse.project_name, + deployment_id: deploymentResponse.id, + url: deploymentResponse.url, + }); + await metrics.sendMetricsEvent("create pages deployment"); }; diff --git a/packages/wrangler/src/triggers/deploy.ts b/packages/wrangler/src/triggers/deploy.ts index d8f96b06a27d..e331f4a681e7 100644 --- a/packages/wrangler/src/triggers/deploy.ts +++ b/packages/wrangler/src/triggers/deploy.ts @@ -30,7 +30,9 @@ type Props = { experimentalVersions: boolean | undefined; }; -export default async function triggersDeploy(props: Props): Promise { +export default async function triggersDeploy( + props: Props +): Promise { const { config, accountId, name: scriptName } = props; const triggers = props.triggers || config.triggers?.crons; @@ -253,13 +255,15 @@ export default async function triggersDeploy(props: Props): Promise { : `Published ${workerName}`; logger.log(msg, formatTime(deployMs)); - for (const target of targets.flat()) { + const flatTargets = targets.flat().map( // Append protocol only on workers.dev domains - logger.log( - " ", - (target.endsWith("workers.dev") ? "https://" : "") + target - ); + (target) => (target.endsWith("workers.dev") ? "https://" : "") + target + ); + + for (const target of flatTargets) { + logger.log(" ", target); } + return flatTargets; } else { logger.log("No deploy targets for", workerName, formatTime(deployMs)); }