Skip to content

Commit 1b80dec

Browse files
authored
fix: wrangler pages deployment (list|tail) env filtering (#7263)
Adds the --environment flag to `wrangler pages deployment list`, which should allow users to list deployments of a specific type. When the flag it's not provided it will list the latest 25 deployments regardless of type. Additionally, makes sure we're listing the correct type of deployments when attempting to tail.
1 parent 97acf07 commit 1b80dec

File tree

5 files changed

+214
-21
lines changed

5 files changed

+214
-21
lines changed

.changeset/curly-rice-travel.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"wrangler": minor
3+
---
4+
5+
Fix wrangler pages deployment (list|tail) environment filtering.

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

+112-4
Original file line numberDiff line numberDiff line change
@@ -47,20 +47,128 @@ describe("pages deployment list", () => {
4747

4848
expect(requests.count).toBe(1);
4949
});
50+
51+
it("should pass no environment", async () => {
52+
const deployments: Deployment[] = [
53+
{
54+
id: "87bbc8fe-16be-45cd-81e0-63d722e82cdf",
55+
url: "https://87bbc8fe.images.pages.dev",
56+
environment: "preview",
57+
created_on: "2021-11-17T14:52:26.133835Z",
58+
latest_stage: {
59+
ended_on: "2021-11-17T14:52:26.133835Z",
60+
status: "success",
61+
},
62+
deployment_trigger: {
63+
metadata: {
64+
branch: "main",
65+
commit_hash: "c7649364c4cb32ad4f65b530b9424e8be5bec9d6",
66+
},
67+
},
68+
project_name: "images",
69+
},
70+
];
71+
72+
const requests = mockDeploymentListRequest(deployments);
73+
await runWrangler("pages deployment list --project-name=images");
74+
expect(requests.count).toBe(1);
75+
expect(
76+
requests.queryParams[0].find(([key, _]) => {
77+
return key === "env";
78+
})
79+
).toBeUndefined();
80+
});
81+
82+
it("should pass production environment with flag", async () => {
83+
const deployments: Deployment[] = [
84+
{
85+
id: "87bbc8fe-16be-45cd-81e0-63d722e82cdf",
86+
url: "https://87bbc8fe.images.pages.dev",
87+
environment: "preview",
88+
created_on: "2021-11-17T14:52:26.133835Z",
89+
latest_stage: {
90+
ended_on: "2021-11-17T14:52:26.133835Z",
91+
status: "success",
92+
},
93+
deployment_trigger: {
94+
metadata: {
95+
branch: "main",
96+
commit_hash: "c7649364c4cb32ad4f65b530b9424e8be5bec9d6",
97+
},
98+
},
99+
project_name: "images",
100+
},
101+
];
102+
103+
const requests = mockDeploymentListRequest(deployments);
104+
await runWrangler(
105+
"pages deployment list --project-name=images --environment=production"
106+
);
107+
expect(requests.count).toBe(1);
108+
expect(
109+
requests.queryParams[0].find(([key, _]) => {
110+
return key === "env";
111+
})
112+
).toStrictEqual(["env", "production"]);
113+
});
114+
115+
it("should pass preview environment with flag", async () => {
116+
const deployments: Deployment[] = [
117+
{
118+
id: "87bbc8fe-16be-45cd-81e0-63d722e82cdf",
119+
url: "https://87bbc8fe.images.pages.dev",
120+
environment: "preview",
121+
created_on: "2021-11-17T14:52:26.133835Z",
122+
latest_stage: {
123+
ended_on: "2021-11-17T14:52:26.133835Z",
124+
status: "success",
125+
},
126+
deployment_trigger: {
127+
metadata: {
128+
branch: "main",
129+
commit_hash: "c7649364c4cb32ad4f65b530b9424e8be5bec9d6",
130+
},
131+
},
132+
project_name: "images",
133+
},
134+
];
135+
136+
const requests = mockDeploymentListRequest(deployments);
137+
await runWrangler(
138+
"pages deployment list --project-name=images --environment=preview"
139+
);
140+
expect(requests.count).toBe(1);
141+
expect(
142+
requests.queryParams[0].find(([key, _]) => {
143+
return key === "env";
144+
})
145+
).toStrictEqual(["env", "preview"]);
146+
});
50147
});
51148

52149
/* -------------------------------------------------- */
53150
/* Helper Functions */
54151
/* -------------------------------------------------- */
55152

56-
function mockDeploymentListRequest(deployments: unknown[]) {
57-
const requests = { count: 0 };
153+
/**
154+
* A logger used to check how many times a mock API has been hit.
155+
* Useful as a helper in our testing to check if wrangler is making
156+
* the correct API calls without actually sending any web traffic.
157+
*/
158+
type RequestLogger = {
159+
count: number;
160+
queryParams: [string, string][][];
161+
};
162+
163+
function mockDeploymentListRequest(deployments: unknown[]): RequestLogger {
164+
const requests: RequestLogger = { count: 0, queryParams: [] };
58165
msw.use(
59166
http.get(
60167
"*/accounts/:accountId/pages/projects/:project/deployments",
61-
({ params }) => {
168+
({ request, params }) => {
62169
requests.count++;
63-
170+
const url = new URL(request.url);
171+
requests.queryParams.push(Array.from(url.searchParams.entries()));
64172
expect(params.project).toEqual("images");
65173
expect(params.accountId).toEqual("some-account-id");
66174

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

+83-14
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,63 @@ describe("pages deployment tail", () => {
166166
);
167167
await api.closeHelper();
168168
});
169+
170+
it("passes default environment to deployments list", async () => {
171+
api = mockTailAPIs();
172+
expect(api.requests.creation.length).toStrictEqual(0);
173+
174+
await runWrangler(
175+
"pages deployment tail --project-name mock-project mock-deployment-id"
176+
);
177+
178+
await expect(api.ws.connected).resolves.toBeTruthy();
179+
console.log(api.requests.deployments.queryParams[0]);
180+
expect(api.requests.deployments.count).toStrictEqual(1);
181+
expect(
182+
api.requests.deployments.queryParams[0].find(([key, _]) => {
183+
return key === "env";
184+
})
185+
).toStrictEqual(["env", "production"]);
186+
await api.closeHelper();
187+
});
188+
189+
it("passes production environment to deployments list", async () => {
190+
api = mockTailAPIs();
191+
expect(api.requests.creation.length).toStrictEqual(0);
192+
193+
await runWrangler(
194+
"pages deployment tail --project-name mock-project mock-deployment-id --environment production"
195+
);
196+
197+
await expect(api.ws.connected).resolves.toBeTruthy();
198+
console.log(api.requests.deployments.queryParams[0]);
199+
expect(api.requests.deployments.count).toStrictEqual(1);
200+
expect(
201+
api.requests.deployments.queryParams[0].find(([key, _]) => {
202+
return key === "env";
203+
})
204+
).toStrictEqual(["env", "production"]);
205+
await api.closeHelper();
206+
});
207+
208+
it("passes preview environment to deployments list", async () => {
209+
api = mockTailAPIs();
210+
expect(api.requests.creation.length).toStrictEqual(0);
211+
212+
await runWrangler(
213+
"pages deployment tail --project-name mock-project mock-deployment-id --environment preview"
214+
);
215+
216+
await expect(api.ws.connected).resolves.toBeTruthy();
217+
console.log(api.requests.deployments.queryParams[0]);
218+
expect(api.requests.deployments.count).toStrictEqual(1);
219+
expect(
220+
api.requests.deployments.queryParams[0].find(([key, _]) => {
221+
return key === "env";
222+
})
223+
).toStrictEqual(["env", "preview"]);
224+
await api.closeHelper();
225+
});
169226
});
170227

171228
describe("filtering", () => {
@@ -783,7 +840,7 @@ function deserializeToJson(message: WebSocket.RawData): string {
783840
*/
784841
type MockAPI = {
785842
requests: {
786-
deployments: RequestCounter;
843+
deployments: RequestLogger;
787844
creation: RequestInit[];
788845
deletion: RequestCounter;
789846
};
@@ -792,17 +849,29 @@ type MockAPI = {
792849
closeHelper: () => Promise<void>;
793850
};
794851

852+
/**
853+
* A logger used to check how many times a mock API has been hit.
854+
* Useful as a helper in our testing to check if wrangler is making
855+
* the correct API calls without actually sending any web traffic.
856+
*/
857+
type RequestLogger = {
858+
count: number;
859+
queryParams: [string, string][][];
860+
};
861+
795862
/**
796863
* Mock out the API hit during Tail creation
797864
*
798865
* @returns a `RequestCounter` for counting how many times the API is hit
799866
*/
800-
function mockListDeployments(): RequestCounter {
801-
const requests: RequestCounter = { count: 0 };
867+
function mockListDeployments(): RequestLogger {
868+
const requests: RequestLogger = { count: 0, queryParams: [] };
802869
msw.use(
803870
http.get(
804871
`*/accounts/:accountId/pages/projects/:projectName/deployments`,
805-
() => {
872+
({ request }) => {
873+
const url = new URL(request.url);
874+
requests.queryParams.push(Array.from(url.searchParams.entries()));
806875
requests.count++;
807876
return HttpResponse.json(
808877
{
@@ -839,15 +908,6 @@ function mockListDeployments(): RequestCounter {
839908
return requests;
840909
}
841910

842-
/**
843-
* A counter used to check how many times a mock API has been hit.
844-
* Useful as a helper in our testing to check if wrangler is making
845-
* the correct API calls without actually sending any web traffic
846-
*/
847-
type RequestCounter = {
848-
count: number;
849-
};
850-
851911
/**
852912
* Mock out the API hit during Tail creation
853913
*
@@ -911,6 +971,15 @@ const mockEmailEventTo = "[email protected]";
911971
*/
912972
const mockEmailEventSize = 45416;
913973

974+
/**
975+
* A counter used to check how many times a mock API has been hit.
976+
* Useful as a helper in our testing to check if wrangler is making
977+
* the correct API calls without actually sending any web traffic
978+
*/
979+
type RequestCounter = {
980+
count: number;
981+
};
982+
914983
/**
915984
* Mock out the API hit during Tail deletion
916985
*
@@ -950,7 +1019,7 @@ function mockTailAPIs(): MockAPI {
9501019
requests: {
9511020
deletion: { count: 0 },
9521021
creation: [],
953-
deployments: { count: 0 },
1022+
deployments: { count: 0, queryParams: [] },
9541023
},
9551024
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
9561025
ws: null!, // will be set in the `beforeEach()`.

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

+3-1
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,9 @@ export async function Handler({
163163
}
164164

165165
const deployments: Array<Deployment> = await fetchResult(
166-
`/accounts/${accountId}/pages/projects/${projectName}/deployments`
166+
`/accounts/${accountId}/pages/projects/${projectName}/deployments`,
167+
{},
168+
new URLSearchParams({ env: environment })
167169
);
168170

169171
const envDeployments = deployments.filter(

packages/wrangler/src/pages/deployments.ts

+11-2
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,15 @@ export function ListOptions(yargs: CommonYargsArgv) {
2323
description:
2424
"The name of the project you would like to list deployments for",
2525
},
26+
environment: {
27+
type: "string",
28+
choices: ["production", "preview"],
29+
description: "Environment type to list deployments for",
30+
},
2631
});
2732
}
2833

29-
export async function ListHandler({ projectName }: ListArgs) {
34+
export async function ListHandler({ projectName, environment }: ListArgs) {
3035
const config = getConfigCache<PagesConfigCache>(PAGES_CONFIG_CACHE_FILENAME);
3136
const accountId = await requireAuth(config);
3237

@@ -42,7 +47,11 @@ export async function ListHandler({ projectName }: ListArgs) {
4247
}
4348

4449
const deployments: Array<Deployment> = await fetchResult(
45-
`/accounts/${accountId}/pages/projects/${projectName}/deployments`
50+
`/accounts/${accountId}/pages/projects/${projectName}/deployments`,
51+
{},
52+
environment
53+
? new URLSearchParams({ env: environment })
54+
: new URLSearchParams({})
4655
);
4756

4857
const titleCase = (word: string) =>

0 commit comments

Comments
 (0)