mirror of
https://github.com/github/codeql-action.git
synced 2026-06-01 03:14:50 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ab95e32825 | |||
| 3c41d8f998 |
@@ -1,5 +1,5 @@
|
|||||||
import { copyFile, rm, writeFile } from "node:fs/promises";
|
import { copyFile, rm, writeFile } from "node:fs/promises";
|
||||||
import { dirname, join } from "node:path";
|
import { basename, dirname, join } from "node:path";
|
||||||
import { fileURLToPath } from "node:url";
|
import { fileURLToPath } from "node:url";
|
||||||
|
|
||||||
import * as esbuild from "esbuild";
|
import * as esbuild from "esbuild";
|
||||||
@@ -13,6 +13,72 @@ const __dirname = dirname(__filename);
|
|||||||
const SRC_DIR = join(__dirname, "src");
|
const SRC_DIR = join(__dirname, "src");
|
||||||
const OUT_DIR = join(__dirname, "lib");
|
const OUT_DIR = join(__dirname, "lib");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of the shared entrypoint file that imports each Action's code. By introducing a single
|
||||||
|
* entrypoint for all the Actions, we avoid duplicating code across each Action's bundle.
|
||||||
|
*/
|
||||||
|
const SHARED_ENTRYPOINT = "actions-entrypoint";
|
||||||
|
|
||||||
|
/** The names of all the Action entry points (as referenced by `action.yml`s). */
|
||||||
|
function findActionNames() {
|
||||||
|
return globSync([
|
||||||
|
`${SRC_DIR}/*-action.ts`,
|
||||||
|
`${SRC_DIR}/*-action-post.ts`,
|
||||||
|
])
|
||||||
|
.map((p) => basename(p, ".ts"))
|
||||||
|
.sort();
|
||||||
|
}
|
||||||
|
|
||||||
|
const ACTION_NAMES = findActionNames();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate the source for the shared entry point. The generated module dispatches at runtime to the
|
||||||
|
* Action selected by `CODEQL_ACTION_ENTRYPOINT`, using `require()` to incorporate each Action's
|
||||||
|
* code without executing the top-level side effects.
|
||||||
|
*/
|
||||||
|
function generateEntrypointTypescriptSource() {
|
||||||
|
const cases = ACTION_NAMES
|
||||||
|
.map(
|
||||||
|
(name) =>
|
||||||
|
` case ${JSON.stringify(name)}:\n require("./${name}");\n break;`,
|
||||||
|
)
|
||||||
|
.join("\n");
|
||||||
|
return `const entrypoint = process.env.CODEQL_ACTION_ENTRYPOINT;
|
||||||
|
switch (entrypoint) {
|
||||||
|
${cases}
|
||||||
|
default:
|
||||||
|
throw new Error(
|
||||||
|
\`Unknown CodeQL Action entrypoint: \${JSON.stringify(entrypoint)}. \` +
|
||||||
|
"This file is intended to be invoked via the generated stubs in lib/.",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve the virtual shared entry point and provide its generated source to esbuild without
|
||||||
|
* writing it to disk.
|
||||||
|
*
|
||||||
|
* @type {esbuild.Plugin}
|
||||||
|
*/
|
||||||
|
const virtualEntrypointPlugin = {
|
||||||
|
name: "virtual-actions-entrypoint",
|
||||||
|
setup(build) {
|
||||||
|
const namespace = "actions-entrypoint";
|
||||||
|
// Ideally, we'd `RegExp.escape` the entrypoint here, but that API isn't supported in Node 20. Since we're dealing with a hardcoded string, this isn't too much of a problem.
|
||||||
|
build.onResolve({ filter: new RegExp(`^${SHARED_ENTRYPOINT}$`) }, () => ({
|
||||||
|
path: SHARED_ENTRYPOINT,
|
||||||
|
namespace,
|
||||||
|
}));
|
||||||
|
// Restrict using the namespace. The path filter does not need to discriminate any further.
|
||||||
|
build.onLoad({ filter: /.*/, namespace }, () => ({
|
||||||
|
contents: generateEntrypointTypescriptSource(),
|
||||||
|
resolveDir: SRC_DIR,
|
||||||
|
loader: "ts",
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clean the output directory before building.
|
* Clean the output directory before building.
|
||||||
*
|
*
|
||||||
@@ -62,18 +128,48 @@ const onEndPlugin = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emit a tiny stub file for each Action entrypoint. Each stub sets an environment variable
|
||||||
|
* identifying which action was invoked and then `require()`s the shared bundle, which dispatches to
|
||||||
|
* the correct Action's code.
|
||||||
|
*
|
||||||
|
* @type {esbuild.Plugin}
|
||||||
|
*/
|
||||||
|
const emitActionStubsPlugin = {
|
||||||
|
name: "emit-action-stubs",
|
||||||
|
setup(build) {
|
||||||
|
build.onEnd(async () => {
|
||||||
|
await Promise.all(
|
||||||
|
ACTION_NAMES.map(async (name) => {
|
||||||
|
const stub =
|
||||||
|
`"use strict";\n` +
|
||||||
|
`process.env.CODEQL_ACTION_ENTRYPOINT = ${JSON.stringify(name)};\n` +
|
||||||
|
`require("./${SHARED_ENTRYPOINT}.js");\n`;
|
||||||
|
await writeFile(join(OUT_DIR, `${name}.js`), stub);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
const context = await esbuild.context({
|
const context = await esbuild.context({
|
||||||
// Include upload-lib.ts as an entry point for use in testing environments.
|
// Bundle every action together via the shared entry point. We also keep
|
||||||
entryPoints: globSync([
|
// `upload-lib.ts` as a separate entry point for use in testing environments.
|
||||||
`${SRC_DIR}/*-action.ts`,
|
entryPoints: [
|
||||||
`${SRC_DIR}/*-action-post.ts`,
|
{ in: SHARED_ENTRYPOINT, out: SHARED_ENTRYPOINT },
|
||||||
"src/upload-lib.ts",
|
join(SRC_DIR, "upload-lib.ts"),
|
||||||
]),
|
],
|
||||||
bundle: true,
|
bundle: true,
|
||||||
format: "cjs",
|
format: "cjs",
|
||||||
outdir: OUT_DIR,
|
outdir: OUT_DIR,
|
||||||
platform: "node",
|
platform: "node",
|
||||||
plugins: [cleanPlugin, copyDefaultsPlugin, onEndPlugin],
|
plugins: [
|
||||||
|
cleanPlugin,
|
||||||
|
copyDefaultsPlugin,
|
||||||
|
virtualEntrypointPlugin,
|
||||||
|
emitActionStubsPlugin,
|
||||||
|
onEndPlugin,
|
||||||
|
],
|
||||||
target: ["node20"],
|
target: ["node20"],
|
||||||
define: {
|
define: {
|
||||||
__CODEQL_ACTION_VERSION__: JSON.stringify(pkg.version),
|
__CODEQL_ACTION_VERSION__: JSON.stringify(pkg.version),
|
||||||
|
|||||||
Generated
+162149
File diff suppressed because one or more lines are too long
Generated
+2
-129182
File diff suppressed because one or more lines are too long
Generated
+2
-96037
File diff suppressed because one or more lines are too long
Generated
+2
-88243
File diff suppressed because one or more lines are too long
Generated
+2
-136976
File diff suppressed because one or more lines are too long
Generated
+2
-93005
File diff suppressed because one or more lines are too long
Generated
+2
-87797
File diff suppressed because one or more lines are too long
Generated
+2
-89619
File diff suppressed because one or more lines are too long
Generated
+2
-127994
File diff suppressed because one or more lines are too long
Generated
+2
-105057
File diff suppressed because one or more lines are too long
Generated
+2
-128019
File diff suppressed because one or more lines are too long
Generated
+2
-94426
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user