Skip to content

Commit cbea64b

Browse files
WC-2965 Prevent selecting in-progress deployments when tailing (#9685)
If not provided with a deployment to tail, Wrangler will try to pull the list of deployments and select the most recently created one. However, we do not check whether this deployment has finished. This is causing intermittent errors for users. Co-authored-by: Mathias Lafeldt <[email protected]>
1 parent 4dd026b commit cbea64b

File tree

3 files changed

+54
-10
lines changed

3 files changed

+54
-10
lines changed

.changeset/bumpy-otters-kiss.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"wrangler": patch
3+
---
4+
5+
Select only successfully deployed deployments when tailing.

packages/wrangler/src/__tests__/pages/pages-deployment-tail.test.ts

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,16 +62,13 @@ describe("pages deployment tail", () => {
6262
mockApiToken();
6363
const std = mockConsoleMethods();
6464

65-
beforeEach(() => {
66-
// Force the CLI to be "non-interactive" in test env
67-
vi.stubEnv("CF_PAGES", "1");
68-
});
69-
7065
/**
7166
* Interaction with the tailing API, including tail creation,
7267
* deletion, and connection.
7368
*/
7469
describe("API interaction", () => {
70+
const { setIsTTY } = useMockIsTTY();
71+
7572
it("should throw an error if deployment isn't provided", async () => {
7673
api = mockTailAPIs();
7774
await expect(
@@ -83,6 +80,22 @@ describe("pages deployment tail", () => {
8380
await api.closeHelper();
8481
});
8582

83+
it("only uses deployments with status=success and name=deploy", async () => {
84+
setIsTTY(true);
85+
api = mockTailAPIs("mock-deployment-id");
86+
expect(api.requests.creation.length).toStrictEqual(0);
87+
88+
await runWrangler("pages deployment tail --project-name mock-project");
89+
90+
await expect(api.ws.connected).resolves.toBeTruthy();
91+
expect(api.requests.creation.length).toStrictEqual(1);
92+
expect(api.requests.deletion.count).toStrictEqual(0);
93+
94+
await api.closeHelper();
95+
expect(api.requests.deletion.count).toStrictEqual(1);
96+
await api.closeHelper();
97+
});
98+
8699
it("creates and then delete tails by deployment ID", async () => {
87100
api = mockTailAPIs();
88101
expect(api.requests.creation.length).toStrictEqual(0);
@@ -867,6 +880,24 @@ function mockListDeployments(): RequestLogger {
867880
errors: [],
868881
messages: [],
869882
result: [
883+
{
884+
id: "mock-deployment-id-skipped",
885+
url: "https://abc123.mock.pages.dev",
886+
environment: "production",
887+
created_on: "2020-01-17T14:52:26.133835Z",
888+
latest_stage: {
889+
ended_on: "2020-01-17T14:52:26.133835Z",
890+
status: "skipped",
891+
name: "deploy",
892+
},
893+
deployment_trigger: {
894+
metadata: {
895+
branch: "main",
896+
commit_hash: "11122334c4cb32ad4f65b530b9424e8be5bec9d6",
897+
},
898+
},
899+
project_name: "mock-project",
900+
},
870901
{
871902
id: "mock-deployment-id",
872903
url: "https://87bbc8fe.mock.pages.dev",
@@ -875,6 +906,7 @@ function mockListDeployments(): RequestLogger {
875906
latest_stage: {
876907
ended_on: "2021-11-17T14:52:26.133835Z",
877908
status: "success",
909+
name: "deploy",
878910
},
879911
deployment_trigger: {
880912
metadata: {
@@ -901,11 +933,13 @@ function mockListDeployments(): RequestLogger {
901933
*
902934
* @returns a `RequestCounter` for counting how many times the API is hit
903935
*/
904-
function mockCreateTailRequest(): RequestInit[] {
936+
function mockCreateTailRequest(
937+
deploymentId: string = ":deploymentId"
938+
): RequestInit[] {
905939
const requests: RequestInit[] = [];
906940
msw.use(
907941
http.post(
908-
`*/accounts/:accountId/pages/projects/:projectName/deployments/:deploymentId/tails`,
942+
`*/accounts/:accountId/pages/projects/:projectName/deployments/${deploymentId}/tails`,
909943
async ({ request }) => {
910944
requests.push((await request.json()) as RequestInit);
911945
return HttpResponse.json(
@@ -1002,7 +1036,9 @@ const websocketURL = "ws://localhost:1234";
10021036
* @param websocketURL a fake websocket URL for wrangler to connect to
10031037
* @returns a mocked-out version of the API
10041038
*/
1005-
function mockTailAPIs(): MockAPI {
1039+
function mockTailAPIs(
1040+
expectedCreateDeploymentId: string = ":deploymentId"
1041+
): MockAPI {
10061042
const api: MockAPI = {
10071043
requests: {
10081044
deletion: { count: 0 },
@@ -1034,7 +1070,7 @@ function mockTailAPIs(): MockAPI {
10341070
api.ws = new MockWebSocketServer(websocketURL);
10351071
mockWebSockets.push(api.ws);
10361072

1037-
api.requests.creation = mockCreateTailRequest();
1073+
api.requests.creation = mockCreateTailRequest(expectedCreateDeploymentId);
10381074
api.requests.deletion = mockDeleteTailRequest();
10391075
api.requests.deployments = mockListDeployments();
10401076

packages/wrangler/src/pages/deployment-tails.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,10 @@ export async function Handler({
169169
);
170170

171171
const envDeployments = deployments.filter(
172-
(d) => d.environment === environment
172+
(d) =>
173+
d.environment === environment &&
174+
d.latest_stage.name === "deploy" &&
175+
d.latest_stage.status === "success"
173176
);
174177

175178
// Deployment is URL

0 commit comments

Comments
 (0)