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

chore: post handler size comparisons for non-fork PRs #1320

Merged
merged 17 commits into from
Jun 29, 2021
Merged
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
16 changes: 13 additions & 3 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@ jobs:

- run: yarn --frozen-lockfile

- name: Calculate and post handler sizes
# TODO: handle commenting for fork/dependabot PRs somehow, either through a locked-down web API, periodic workflow, or pull_request_target event.
if: (matrix.node-version == '14.x' && startsWith(github.head_ref, 'dependabot/') == false && github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository)
env:
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
GITHUB_NEW_SHA: ${{ github.event.pull_request.head.sha }}
GITHUB_BASE_SHA: ${{ github.event.pull_request.base.sha }}
PULL_REQUEST_ID: ${{ github.event.number }}
run: yarn handlers:comment-handler-sizes

- run: yarn test

- run: yarn integration
Expand All @@ -45,11 +55,11 @@ jobs:
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_ST }}
AWS_DEFAULT_REGION: us-east-1
GITHUB_SHA: ${{ github.sha }}
run: yarn upload-handler-sizes
run: yarn handlers:upload-handler-sizes

start-e2e-tests:
# Note: we only run e2e tests automatically if this PR is not from a fork, as forks won't have access to secrets
if: ${{ github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) }}
# Note: we only run e2e tests automatically if this PR is not from a fork or dependabot, as forks won't have access to secrets
if: ${{ startsWith(github.head_ref, 'dependabot/') == false && github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) }}
runs-on: ubuntu-latest

steps:
Expand Down
12 changes: 9 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
"integration": "jest --runInBand --config jest.integration.config.json --setupTestFrameworkScriptFile=./jest.integration.setup.js",
"postinstall": "yarn packages-install && opencollective-postinstall",
"docs": "cd documentation && yarn && yarn build",
"upload-handler-sizes": "ts-node scripts/upload-handler-sizes.ts"
"handlers:upload-handler-sizes": "ts-node scripts/upload-handler-sizes.ts",
"handlers:comment-handler-sizes": "ts-node scripts/comment-handler-sizes.ts"
},
"repository": {
"type": "git",
Expand All @@ -47,6 +48,9 @@
"@sls-next/next-aws-cloudfront": "link:./packages/compat-layers/lambda-at-edge-compat",
"@types/fs-extra": "^9.0.1",
"@types/jest": "^26.0.23",
"@types/lodash": "^4.14.170",
"@types/node": "^15.12.5",
"@types/node-fetch": "^2.5.10",
"@types/react": "^17.0.9",
"@types/react-dom": "^17.0.6",
"@types/webpack": "^5.28.0",
Expand Down Expand Up @@ -117,7 +121,9 @@
]
},
"dependencies": {
"opencollective-postinstall": "^2.0.3"
"opencollective-postinstall": "^2.0.3",
"lodash": "^4.17.21",
"node-fetch": "^2.6.1"
},
"collective": {
"type": "opencollective",
Expand All @@ -133,6 +139,6 @@
},
"resolutions": {
"which": "^2.0.1",
"lodash": "^4.17.19"
"lodash": "^4.17.21"
}
}
123 changes: 123 additions & 0 deletions scripts/comment-handler-sizes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
#!/usr/bin/env node

import fetch from "node-fetch";
import { calculateHandlerSizes } from "./handler-size-utils";
import { Octokit } from "@octokit/rest";
import * as _ from "lodash";

/**
* Get sizes that were calculated from existing commit SHA
* @param commitSha
*/
const getCommitSizes = async (
commitSha: string
): Promise<Record<string, any>> => {
const SIZES_URL =
process.env.SIZES_URL ?? "https://d3m7nebxuhlnm8.cloudfront.net";

const url = `${SIZES_URL}/sizes-github-sha-${commitSha}.json`;

console.info("Retrieving url at: " + url);

const response = await fetch(url);

if (response.ok) {
return JSON.parse(await response.text());
} else {
console.warn(
"Unable to get commit sizes due to response status: " + response.status
);
return {};
}
};

const postCommentToPullRequest = async (
prNumber: number,
comment: string
): Promise<void> => {
const octokit = new Octokit({
auth: `token ${process.env.GITHUB_TOKEN}`
});

// Try to find existing report comment
const comments = await octokit.issues.listComments({
owner: "serverless-nextjs",
repo: "serverless-next.js",
issue_number: prNumber
});

let existingCommentId;

for (const comment of comments.data) {
if (
comment.body?.includes("# Handler Size Report") &&
comment.user?.login === "slsnextbot"
) {
existingCommentId = comment.id;
break;
}
}

if (existingCommentId) {
await octokit.issues.updateComment({
comment_id: existingCommentId,
owner: "serverless-nextjs",
repo: "serverless-next.js",
issue_number: prNumber,
body: comment
});
} else {
await octokit.issues.createComment({
owner: "serverless-nextjs",
repo: "serverless-next.js",
issue_number: prNumber,
body: comment
});
}
};

const main = async (): Promise<void> => {
const PULL_REQUEST_ID = parseInt(process.env.PULL_REQUEST_ID ?? "0");
const GITHUB_BASE_SHA = process.env.GITHUB_BASE_SHA ?? "";
const GITHUB_NEW_SHA = process.env.GITHUB_NEW_SHA ?? "";

console.info("Get base commit's sizes");

// Get sizes from base branch commit
const baseSizes = await getCommitSizes(GITHUB_BASE_SHA);

console.info("Calculate all uncompressed handler sizes");

// Get sizes from PR branch latest commit
const newSizes: Record<string, any> = calculateHandlerSizes();

let output = "# Handler Size Report\n";

if (_.isEqual(baseSizes, newSizes)) {
output += "> No changes to handler sizes.\n";
} else {
output += "> There are changes to handler sizes. Please review.";
}

output += `### Base Handler Sizes (kB) (commit ${GITHUB_BASE_SHA})\n`;
output += "```ts\n";
output += JSON.stringify(baseSizes, null, 4) + "\n";
output += "```\n";
output += `### New Handler Sizes (kB) (commit ${GITHUB_NEW_SHA})\n`;
output += "```ts\n";
output += JSON.stringify(newSizes, null, 4) + "\n";
output += "```\n";

// Post comment to pull request
await postCommentToPullRequest(PULL_REQUEST_ID, output);
};

main()
.then(() => {
console.info("Commented handler sizes successfully.");
process.exit(0);
})
.catch((error) => {
console.error(`Unhandled error: ${error}`);
process.exit(1);
});
67 changes: 67 additions & 0 deletions scripts/handler-size-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import * as path from "path";
import * as fs from "fs";

type HandlerConfiguration = {
path: string;
handlers: Record<string, Record<string, string>>;
};

export const PLATFORM_CONFIGS: Record<string, HandlerConfiguration> = {
"Lambda@Edge": {
path: "packages/libs/lambda-at-edge",
handlers: {
"Default Lambda": {
Standard: "dist/default-handler/standard",
Minified: "dist/default-handler/minified"
},
"API Lambda": {
Standard: "dist/api-handler/standard",
Minified: "dist/api-handler/minified"
},
"Image Lambda": {
Standard: "dist/image-handler/standard",
Minified: "dist/image-handler/minified"
},
"Regeneration Lambda": {
Standard: "dist/regeneration-handler/standard",
Minified: "dist/regeneration-handler/minified"
}
}
}
};

export const getDirectorySizeInKilobytes = (
directoryPath: string
): number | undefined => {
let size = 0;

if (fs.existsSync(directoryPath)) {
fs.readdirSync(directoryPath).forEach((file) => {
size += fs.statSync(path.join(directoryPath, file)).size;
});
return Math.round(size / 1024);
} else {
return undefined;
}
};

export const calculateHandlerSizes = (): Record<string, any> => {
const sizes: Record<string, any> = {};

for (const [platform, platformConfig] of Object.entries(PLATFORM_CONFIGS)) {
sizes[platform] = {};
const packagePath = platformConfig.path;
for (const [handler, handlerConfig] of Object.entries(
platformConfig.handlers
)) {
sizes[platform][handler] = {};
for (const [handlerType, handlerPath] of Object.entries(handlerConfig)) {
const relativePath = path.join(packagePath, handlerPath);
sizes[platform][handler][handlerType] =
getDirectorySizeInKilobytes(relativePath);
}
}
}

return sizes;
};
64 changes: 2 additions & 62 deletions scripts/upload-handler-sizes.ts
Original file line number Diff line number Diff line change
@@ -1,52 +1,7 @@
#!/usr/bin/env node

import * as path from "path";
import * as fs from "fs";
import * as AWS from "aws-sdk";

type HandlerConfiguration = {
path: string;
handlers: Record<string, Record<string, string>>;
};

const PLATFORM_CONFIGS: Record<string, HandlerConfiguration> = {
"Lambda@Edge": {
path: "packages/libs/lambda-at-edge",
handlers: {
"Default Lambda": {
Standard: "dist/default-handler/standard",
Minified: "dist/default-handler/minified"
},
"API Lambda": {
Standard: "dist/api-handler/standard",
Minified: "dist/api-handler/minified"
},
"Image Lambda": {
Standard: "dist/image-handler/standard",
Minified: "dist/image-handler/minified"
},
"Regeneration Lambda": {
Standard: "dist/regeneration-handler/standard",
Minified: "dist/regeneration-handler/minified"
}
}
}
};

const getDirectorySizeInKilobytes = (
directoryPath: string
): number | undefined => {
let size = 0;

if (fs.existsSync(directoryPath)) {
fs.readdirSync(directoryPath).forEach((file) => {
size += fs.statSync(path.join(directoryPath, file)).size;
});
return Math.round(size / 1024);
} else {
return undefined;
}
};
import { handlerSizeUtils } from "./handler-size-utils";

const uploadHandlerSizesToS3 = async (
sizes: Record<string, any>
Expand All @@ -65,22 +20,7 @@ const uploadHandlerSizesToS3 = async (

console.info("Calculate all uncompressed handler sizes");

const sizes: Record<string, any> = {};

for (const [platform, platformConfig] of Object.entries(PLATFORM_CONFIGS)) {
sizes[platform] = {};
const packagePath = platformConfig.path;
for (const [handler, handlerConfig] of Object.entries(
platformConfig.handlers
)) {
sizes[platform][handler] = {};
for (const [handlerType, handlerPath] of Object.entries(handlerConfig)) {
const relativePath = path.join(packagePath, handlerPath);
sizes[platform][handler][handlerType] =
getDirectorySizeInKilobytes(relativePath);
}
}
}
const sizes: Record<string, any> = handlerSizeUtils();

console.log("Calculated sizes: " + JSON.stringify(sizes, null, 2));

Expand Down
15 changes: 14 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3489,7 +3489,7 @@
dependencies:
"@types/node" "*"

"@types/lodash@^4.14.123":
"@types/lodash@^4.14.123", "@types/lodash@^4.14.170":
version "4.14.170"
resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.170.tgz#0d67711d4bf7f4ca5147e9091b847479b87925d6"
integrity sha512-bpcvu/MKHHeYX+qeEN8GE7DIravODWdACVA1ctevD8CN24RhPZIKMn9ntfAsrvLfSX3cR5RrBKAbYm9bGs0A+Q==
Expand All @@ -3509,6 +3509,14 @@
resolved "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.1.tgz#283f669ff76d7b8260df8ab7a4262cc83d988256"
integrity sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==

"@types/node-fetch@^2.5.10":
version "2.5.10"
resolved "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.10.tgz#9b4d4a0425562f9fcea70b12cb3fcdd946ca8132"
integrity sha512-IpkX0AasN44hgEad0gEF/V6EgR5n69VEqPEgnmoM8GsIGro3PowbWs4tR6IhxUTyPLpOn+fiGG6nrQhcmoCuIQ==
dependencies:
"@types/node" "*"
form-data "^3.0.0"

"@types/node@*":
version "15.3.1"
resolved "https://registry.npmjs.org/@types/node/-/node-15.3.1.tgz#23a06b87eedb524016616e886b116b8fdcb180af"
Expand All @@ -3519,6 +3527,11 @@
resolved "https://registry.npmjs.org/@types/node/-/node-15.12.2.tgz#1f2b42c4be7156ff4a6f914b2fb03d05fa84e38d"
integrity sha512-zjQ69G564OCIWIOHSXyQEEDpdpGl+G348RAKY0XXy9Z5kU9Vzv1GMNnkar/ZJ8dzXB3COzD9Mo9NtRZ4xfgUww==

"@types/node@^15.12.5":
version "15.12.5"
resolved "https://registry.npmjs.org/@types/node/-/node-15.12.5.tgz#9a78318a45d75c9523d2396131bd3cca54b2d185"
integrity sha512-se3yX7UHv5Bscf8f1ERKvQOD6sTyycH3hdaoozvaLxgUiY5lIGEeH37AD0G0Qi9kPqihPn0HOfd2yaIEN9VwEg==

"@types/normalize-package-data@^2.4.0":
version "2.4.0"
resolved "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e"
Expand Down