Skip to content

Commit 2e3aaae

Browse files
authored
Merge pull request #3787 from github/mbg/bundle/metadata
Generate and analyse esbuild bundle metadata
2 parents c618c9b + f98bf5e commit 2e3aaae

File tree

7 files changed

+78
-17
lines changed

7 files changed

+78
-17
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,5 @@ build/
1111
eslint.sarif
1212
# for local incremental compilation
1313
tsconfig.tsbuildinfo
14+
# esbuild metadata file
15+
meta.json

build.mjs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { copyFile, rm } from "node:fs/promises";
1+
import { copyFile, rm, writeFile } from "node:fs/promises";
22
import { dirname, join } from "node:path";
33
import { fileURLToPath } from "node:url";
44

@@ -64,7 +64,11 @@ const onEndPlugin = {
6464

6565
const context = await esbuild.context({
6666
// Include upload-lib.ts as an entry point for use in testing environments.
67-
entryPoints: globSync([`${SRC_DIR}/*-action.ts`, `${SRC_DIR}/*-action-post.ts`, "src/upload-lib.ts"]),
67+
entryPoints: globSync([
68+
`${SRC_DIR}/*-action.ts`,
69+
`${SRC_DIR}/*-action-post.ts`,
70+
"src/upload-lib.ts",
71+
]),
6872
bundle: true,
6973
format: "cjs",
7074
outdir: OUT_DIR,
@@ -74,7 +78,10 @@ const context = await esbuild.context({
7478
define: {
7579
__CODEQL_ACTION_VERSION__: JSON.stringify(pkg.version),
7680
},
81+
metafile: true,
7782
});
7883

79-
await context.rebuild();
84+
const result = await context.rebuild();
85+
await writeFile(join(__dirname, "meta.json"), JSON.stringify(result.metafile));
86+
8087
await context.dispose();

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"description": "CodeQL action",
66
"scripts": {
77
"_build_comment": "echo 'Run the full build so we typecheck the project and can reuse the transpiled files in npm test'",
8-
"build": "./scripts/check-node-modules.sh && npm run transpile && node build.mjs",
8+
"build": "./scripts/check-node-modules.sh && npm run transpile && node build.mjs && npx tsx ./pr-checks/bundle-metadata.ts",
99
"lint": "eslint --report-unused-disable-directives --max-warnings=0 .",
1010
"lint-ci": "SARIF_ESLINT_IGNORE_SUPPRESSED=true eslint --report-unused-disable-directives --max-warnings=0 . --format @microsoft/eslint-formatter-sarif --output-file=eslint.sarif",
1111
"lint-fix": "eslint --report-unused-disable-directives --max-warnings=0 . --fix",

pr-checks/api-client.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import * as githubUtils from "@actions/github/lib/utils";
2+
import { type Octokit } from "@octokit/core";
3+
import { type PaginateInterface } from "@octokit/plugin-paginate-rest";
4+
import { type Api } from "@octokit/plugin-rest-endpoint-methods";
5+
6+
/** The type of the Octokit client. */
7+
export type ApiClient = Octokit & Api & { paginate: PaginateInterface };
8+
9+
/** Constructs an `ApiClient` using `token` for authentication. */
10+
export function getApiClient(token: string): ApiClient {
11+
const opts = githubUtils.getOctokitOptions(token);
12+
return new githubUtils.GitHub(opts);
13+
}

pr-checks/bundle-metadata.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#!/usr/bin/env npx tsx
2+
3+
import * as fs from "node:fs/promises";
4+
5+
import { BUNDLE_METADATA_FILE } from "./config";
6+
7+
interface InputInfo {
8+
bytesInOutput: number;
9+
}
10+
11+
type Inputs = Record<string, InputInfo>;
12+
13+
interface Output {
14+
bytes: number;
15+
inputs: Inputs;
16+
}
17+
18+
interface Metadata {
19+
outputs: Record<string, Output>;
20+
}
21+
22+
function toMB(bytes: number): string {
23+
return `${(bytes / (1024 * 1024)).toFixed(2)}MB`;
24+
}
25+
26+
async function main() {
27+
const fileContents = await fs.readFile(BUNDLE_METADATA_FILE);
28+
const metadata = JSON.parse(String(fileContents)) as Metadata;
29+
30+
for (const [outputFile, outputData] of Object.entries(
31+
metadata.outputs,
32+
).reverse()) {
33+
console.info(`${outputFile}: ${toMB(outputData.bytes)}`);
34+
35+
for (const [inputName, inputData] of Object.entries(outputData.inputs)) {
36+
// Ignore any inputs that make up less than 5% of the output.
37+
const percentage = (inputData.bytesInOutput / outputData.bytes) * 100.0;
38+
if (percentage < 5.0) continue;
39+
40+
console.info(` ${inputName}: ${toMB(inputData.bytesInOutput)}`);
41+
}
42+
}
43+
}
44+
45+
// Only call `main` if this script was run directly.
46+
if (require.main === module) {
47+
void main();
48+
}

pr-checks/config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,6 @@ export const PR_CHECKS_DIR = __dirname;
88

99
/** The path of the file configuring which checks shouldn't be required. */
1010
export const PR_CHECK_EXCLUDED_FILE = path.join(PR_CHECKS_DIR, "excluded.yml");
11+
12+
/** The path to the esbuild metadata file. */
13+
export const BUNDLE_METADATA_FILE = path.join(PR_CHECKS_DIR, "..", "meta.json");

pr-checks/sync-checks.ts

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,9 @@
55
import * as fs from "fs";
66
import { parseArgs } from "node:util";
77

8-
import * as githubUtils from "@actions/github/lib/utils";
9-
import { type Octokit } from "@octokit/core";
10-
import { type PaginateInterface } from "@octokit/plugin-paginate-rest";
11-
import { type Api } from "@octokit/plugin-rest-endpoint-methods";
128
import * as yaml from "yaml";
139

10+
import { type ApiClient, getApiClient } from "./api-client";
1411
import {
1512
OLDEST_SUPPORTED_MAJOR_VERSION,
1613
PR_CHECK_EXCLUDED_FILE,
@@ -49,15 +46,6 @@ function loadExclusions(): Exclusions {
4946
) as Exclusions;
5047
}
5148

52-
/** The type of the Octokit client. */
53-
type ApiClient = Octokit & Api & { paginate: PaginateInterface };
54-
55-
/** Constructs an `ApiClient` using `token` for authentication. */
56-
function getApiClient(token: string): ApiClient {
57-
const opts = githubUtils.getOctokitOptions(token);
58-
return new githubUtils.GitHub(opts);
59-
}
60-
6149
/**
6250
* Represents information about a check run. We track the `app_id` that generated the check,
6351
* because the API will require it in addition to the name in the future.

0 commit comments

Comments
 (0)