Skip to content
Draft
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
7 changes: 7 additions & 0 deletions .changeset/quiet-pandas-preview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"wrangler": patch
---

`[private beta]`: Explain how to enable Preview URLs when a Preview deployment has none

Wrangler now names the `preview_urls` and `previews_enabled` configuration fields and tells users to deploy those settings before creating the Preview again.
6 changes: 5 additions & 1 deletion packages/deploy-helpers/src/preview/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,11 @@ async function prepareContainersForPreview(
}

export const NO_ACTIVE_PREVIEW_URLS_MESSAGE =
"Note: This Preview deployment has no active URLs. To get one, enable Preview Deployments on workers.dev or a custom domain. See https://developers.cloudflare.com/workers/previews/custom-domains/ for more information";
"Note: This Preview deployment has no active URLs. " +
"For Workers.dev previews, set the top-level `preview_urls` setting to `true`. " +
"For custom-domain previews, set `previews_enabled` to `true` on a custom-domain route. " +
"After changing either setting, run `wrangler deploy`, then `wrangler preview` again. " +
"See https://developers.cloudflare.com/workers/previews/custom-domains/ for more information.";

function getPreviewMigrationsToUpload(
workerName: string,
Expand Down
9 changes: 8 additions & 1 deletion packages/wrangler/src/__tests__/preview.secret.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@ const BRANCH_ENV_VARS = [
"CI_COMMIT_REF_NAME",
] as const;
const NO_ACTIVE_PREVIEW_URLS_MESSAGE =
"Note: This Preview deployment has no active URLs. To get one, enable Preview Deployments on workers.dev or a custom domain. See https://developers.cloudflare.com/workers/previews/custom-domains/ for more information";
"Note: This Preview deployment has no active URLs. " +
"For Workers.dev previews, set the top-level `preview_urls` setting to `true`. " +
"For custom-domain previews, set `previews_enabled` to `true` on a custom-domain route. " +
"After changing either setting, run `wrangler deploy`, then `wrangler preview` again. " +
"See https://developers.cloudflare.com/workers/previews/custom-domains/ for more information.";

async function withoutBranchEnvVars<T>(callback: () => Promise<T>): Promise<T> {
const originalBranchEnv = Object.fromEntries(
Expand Down Expand Up @@ -188,6 +192,7 @@ describe("wrangler preview", () => {
expect(std.out).toContain(
"is now live at https://test-preview.example.workers.dev"
);
expect(std.out).not.toContain(NO_ACTIVE_PREVIEW_URLS_MESSAGE);
expect(std.out).not.toContain("preview-secret");
});

Expand Down Expand Up @@ -394,6 +399,7 @@ describe("wrangler preview", () => {
expect(std.out).toContain(
"is now live at https://test-preview.example.workers.dev"
);
expect(std.out).not.toContain(NO_ACTIVE_PREVIEW_URLS_MESSAGE);
});

test("notes when the new Preview deployment has no active URLs", async ({
Expand Down Expand Up @@ -631,6 +637,7 @@ describe("wrangler preview", () => {
expect(std.out).toContain(
"is now live at https://test-preview.example.workers.dev"
);
expect(std.out).not.toContain(NO_ACTIVE_PREVIEW_URLS_MESSAGE);
expect(std.out).not.toContain("one");
expect(std.out).not.toContain("two");
});
Expand Down
167 changes: 102 additions & 65 deletions packages/wrangler/src/__tests__/preview.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ import {
import type { OutputEntry } from "../output";
import type { Config, PreviewsConfig } from "@cloudflare/workers-utils";

const NO_ACTIVE_PREVIEW_URLS_MESSAGE =
"Note: This Preview deployment has no active URLs. " +
"For Workers.dev previews, set the top-level `preview_urls` setting to `true`. " +
"For custom-domain previews, set `previews_enabled` to `true` on a custom-domain route. " +
"After changing either setting, run `wrangler deploy`, then `wrangler preview` again. " +
"See https://developers.cloudflare.com/workers/previews/custom-domains/ for more information.";

vi.mock("node:child_process", async () => {
const actual =
await vi.importActual<typeof childProcess>("node:child_process");
Expand Down Expand Up @@ -1893,77 +1900,107 @@ describe("wrangler preview", () => {
expect(std.out).toContain("Deployment URLs:");
expect(std.out).toContain(" https://dep-one.test-worker.cloudflare.app");
expect(std.out).toContain(" https://dep-two.test-worker.cloudflare.app");
expect(std.out).not.toContain("no active URLs");
expect(std.out).not.toContain(NO_ACTIVE_PREVIEW_URLS_MESSAGE);
});

test("should note when URL arrays are empty", async ({ expect }) => {
msw.use(
http.get(
`*/accounts/:accountId/workers/workers/:workerId/previews/:previewId`,
() =>
HttpResponse.json(
{
success: false,
result: null,
errors: [{ code: 10025, message: "Preview not found" }],
},
{ status: 404 }
)
),
http.post(
`*/accounts/:accountId/workers/workers/:workerId/previews`,
() =>
HttpResponse.json(
{
success: true,
result: {
id: "preview-id-empty-urls",
name: "empty-urls-preview",
slug: "empty-urls-preview",
urls: [],
worker_name: "test-worker",
created_on: new Date().toISOString(),
test.for([
{
name: "both URL arrays are empty",
previewUrls: [] as string[],
deploymentUrls: [] as string[],
shouldShowGuidance: true,
},
{
name: "the Preview URL array is active",
previewUrls: ["https://empty-urls-preview.test-worker.workers.dev"],
deploymentUrls: [] as string[],
shouldShowGuidance: false,
},
{
name: "the deployment URL array is active",
previewUrls: [] as string[],
deploymentUrls: [
"https://deployment-id-empty-urls.test-worker.workers.dev",
],
shouldShowGuidance: false,
},
])(
"handles URL guidance when $name",
async (
{ previewUrls, deploymentUrls, shouldShowGuidance },
{ expect }
) => {
msw.use(
http.get(
`*/accounts/:accountId/workers/workers/:workerId/previews/:previewId`,
() =>
HttpResponse.json(
{
success: false,
result: null,
errors: [{ code: 10025, message: "Preview not found" }],
},
},
{ status: 201 }
)
),
http.post(
`*/accounts/:accountId/workers/workers/:workerId/previews/:previewId/deployments`,
() =>
HttpResponse.json(
{
success: true,
result: {
id: "deployment-id-empty-urls",
preview_id: "preview-id-empty-urls",
preview_name: "empty-urls-preview",
urls: [],
compatibility_date: "2025-01-01",
env: {},
created_on: new Date().toISOString(),
{ status: 404 }
)
),
http.post(
`*/accounts/:accountId/workers/workers/:workerId/previews`,
() =>
HttpResponse.json(
{
success: true,
result: {
id: "preview-id-empty-urls",
name: "empty-urls-preview",
slug: "empty-urls-preview",
urls: previewUrls,
worker_name: "test-worker",
created_on: new Date().toISOString(),
},
},
},
{ status: 201 }
)
)
);
{ status: 201 }
)
),
http.post(
`*/accounts/:accountId/workers/workers/:workerId/previews/:previewId/deployments`,
() =>
HttpResponse.json(
{
success: true,
result: {
id: "deployment-id-empty-urls",
preview_id: "preview-id-empty-urls",
preview_name: "empty-urls-preview",
urls: deploymentUrls,
compatibility_date: "2025-01-01",
env: {},
created_on: new Date().toISOString(),
},
},
{ status: 201 }
)
)
);

await runWrangler("preview --name empty-urls-preview");
await runWrangler("preview --name empty-urls-preview");

const summaryLines = stripVTControlCharacters(std.out)
.split("\n")
.filter(
(line) => line.startsWith("Preview") || line.startsWith("Deployment")
);
expect(summaryLines).toEqual([
"Preview: empty-urls-preview (new)",
"Deployment ID: deployment-id-empty-urls",
]);
expect(std.out).toContain(
"Note: This Preview deployment has no active URLs. To get one, enable Preview Deployments on workers.dev or a custom domain. See https://developers.cloudflare.com/workers/previews/custom-domains/ for more information"
);
});
if (shouldShowGuidance) {
const summaryLines = stripVTControlCharacters(std.out)
.split("\n")
.filter(
(line) =>
line.startsWith("Preview") || line.startsWith("Deployment")
);
expect(summaryLines).toEqual([
"Preview: empty-urls-preview (new)",
"Deployment ID: deployment-id-empty-urls",
]);
expect(std.out).toContain(NO_ACTIVE_PREVIEW_URLS_MESSAGE);
} else {
expect(std.out).not.toContain(NO_ACTIVE_PREVIEW_URLS_MESSAGE);
}
}
);

test("should use the URL-encoded preview name as the Preview identifier in path params", async ({
expect,
Expand Down
Loading