Skip to content
This repository was archived by the owner on Jan 28, 2025. It is now read-only.

Commit 396a13c

Browse files
authored
chore(e2e-tests): cleanup lambdas in initialize workflow, update run-e2e-ci script with additional logging (#1080)
1 parent cb305ee commit 396a13c

File tree

5 files changed

+169
-0
lines changed

5 files changed

+169
-0
lines changed

.github/workflows/e2e-tests.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,16 @@ jobs:
8787
path: build.tar.gz
8888
retention-days: 1
8989

90+
- name: Cleanup any old Lambda versions in AWS account
91+
env:
92+
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_AT }}
93+
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_ST }}
94+
AWS_DEFAULT_REGION: us-east-1
95+
run: |
96+
cd packages/e2e-tests/test-utils
97+
yarn --frozen-lockfile
98+
yarn cleanup-lambda
99+
90100
run-e2e-tests:
91101
needs: [initialize]
92102
runs-on: [ubuntu-latest]

packages/e2e-tests/test-utils/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
"name": "e2e-test-utils",
33
"version": "1.0.0",
44
"description": "Test utils for running serverless-next.js end-to-end tests",
5+
"scripts": {
6+
"cleanup-lambda": "ts-node --project tsconfig.scripts.json scripts/cleanup-lambda.ts"
7+
},
58
"repository": {
69
"type": "git",
710
"url": "git+https://github.com/serverless-next.js/serverless-next.js"
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
#!/usr/bin/env node
2+
3+
// Cleanup Lambda code adapted from https://github.com/davidmenger/cleanup-lambda-versions/blob/master/src/cleanupVersions.js
4+
import * as AWS from "aws-sdk";
5+
import {
6+
ListFunctionsResponse,
7+
ListVersionsByFunctionResponse
8+
} from "aws-sdk/clients/lambda";
9+
10+
function listLambdaFunctions(
11+
lambda: AWS.Lambda,
12+
nextMarker: string | undefined = undefined
13+
): Promise<ListFunctionsResponse> {
14+
return new Promise((resolve, reject) => {
15+
const opts = {
16+
MaxItems: 999
17+
};
18+
19+
if (nextMarker) {
20+
Object.assign(opts, { Marker: nextMarker });
21+
}
22+
23+
lambda.listFunctions(opts, (err, res) => {
24+
if (err) {
25+
reject(err);
26+
} else {
27+
resolve(res);
28+
}
29+
});
30+
});
31+
}
32+
33+
function listLambdaVersions(
34+
lambda: AWS.Lambda,
35+
fnName: string
36+
): Promise<ListVersionsByFunctionResponse> {
37+
return new Promise((resolve, reject) => {
38+
lambda.listVersionsByFunction(
39+
{
40+
FunctionName: fnName,
41+
MaxItems: 50
42+
},
43+
(err, res) => {
44+
if (err) {
45+
reject(err);
46+
} else {
47+
resolve(res);
48+
}
49+
}
50+
);
51+
});
52+
}
53+
54+
function removeLambdaVersion(
55+
lambda: AWS.Lambda,
56+
fnName: string,
57+
version: string
58+
): Promise<{}> {
59+
return new Promise((resolve, reject) => {
60+
lambda.deleteFunction(
61+
{ FunctionName: fnName, Qualifier: version },
62+
(err, res) => {
63+
if (err) {
64+
reject(err);
65+
} else {
66+
resolve(res);
67+
}
68+
}
69+
);
70+
});
71+
}
72+
73+
async function cleanupVersions(
74+
region: string,
75+
removeIt: boolean = false,
76+
nextMarker: string | undefined = undefined
77+
) {
78+
const lambda: AWS.Lambda = new AWS.Lambda({ region });
79+
const lambdas = await listLambdaFunctions(lambda, nextMarker);
80+
81+
let i = 0;
82+
83+
for (const fn of lambdas.Functions ?? []) {
84+
if (fn.FunctionName) {
85+
const versions = await listLambdaVersions(lambda, fn.FunctionName);
86+
87+
for (const version of versions.Versions ?? []) {
88+
if (version.Version && version.Version !== fn.Version) {
89+
if (removeIt) {
90+
try {
91+
console.log(
92+
`Removing function: ${fn.FunctionName} - ${version.Version}`
93+
);
94+
await removeLambdaVersion(
95+
lambda,
96+
fn.FunctionName,
97+
version.Version
98+
);
99+
i++;
100+
} catch (e) {
101+
console.log(
102+
`Remove failed (${fn.FunctionName} - ${version.Version}): ${e.message}`
103+
);
104+
}
105+
} else {
106+
console.log(
107+
`Listing function only: ${fn.FunctionName} - ${version.Version}`
108+
);
109+
i++;
110+
}
111+
}
112+
}
113+
}
114+
}
115+
116+
if (lambdas.NextMarker) {
117+
i += await cleanupVersions(region, removeIt, lambdas.NextMarker);
118+
}
119+
120+
return i;
121+
}
122+
123+
console.info("Cleaning up old Lambda versions");
124+
cleanupVersions("us-east-1", true) // All Lambda@Edge is created in us-east-1 only
125+
.then((success) => {
126+
if (success) {
127+
console.info("Cleaning up old Lambda versions successful.");
128+
process.exit(0);
129+
} else {
130+
console.error("Cleaning up old Lambda versions failed.");
131+
process.exit(1);
132+
}
133+
})
134+
.catch((error) => {
135+
console.error(`Unhandled error: ${error}`);
136+
process.exit(1);
137+
});

packages/e2e-tests/test-utils/scripts/run-e2e-ci.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ function cleanup(): void {
256256
);
257257

258258
// Optimistically clean up app's S3 bucket
259+
console.info("Optimistically cleaning up app's S3 bucket");
259260
execSync(
260261
`aws s3 rm s3://${getAppBucketName(appName)} --recursive || true`,
261262
{
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"compilerOptions": {
3+
"baseUrl": "scripts",
4+
"noImplicitReturns": true,
5+
"noImplicitThis": true,
6+
"noUnusedLocals": false,
7+
"preserveConstEnums": true,
8+
"removeComments": true,
9+
"sourceMap": true,
10+
"strictNullChecks": true,
11+
"strict": true,
12+
"esModuleInterop": true,
13+
"target": "es2015",
14+
"module": "commonjs",
15+
"rootDir": "./"
16+
},
17+
"include": ["**/*.ts"]
18+
}

0 commit comments

Comments
 (0)