Auto-generate shared bundle

This commit is contained in:
Michael B. Gale
2026-05-14 18:27:46 +01:00
parent 14085a675c
commit 0d08c01f78
4 changed files with 79 additions and 83 deletions
+51 -3
View File
@@ -1,5 +1,5 @@
import { copyFile, readFile, 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 * as esbuild from "esbuild";
@@ -62,8 +62,14 @@ const onEndPlugin = {
},
};
/** The name of the virtual `entry-points` module. */
const SHARED_ENTRYPOINT = "entry-points";
/**
* Emit a tiny stub file for each Action entrypoint. Each stub imports the shared bundle
* This plugin finds all source files that contain action entry points.
* It then generates the virtual `entry-points` module which imports all identifies files,
* and re-exports their `runWrapper` functions with suitable aliases.
* A tiny stub file is emitted for each Action entrypoint. Each stub imports the shared bundle
* and calls the respective entry point.
*
* @type {esbuild.Plugin}
@@ -71,6 +77,7 @@ const onEndPlugin = {
const entryPointsPlugin = {
name: "entry-points",
setup(build) {
const namespace = "actions";
const actions = [];
const toPascal = (s) =>
@@ -93,6 +100,44 @@ const entryPointsPlugin = {
}
});
// Resolve the virtual `entry-points` file and set the corresponding namespace.
// 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}$`) }, () => {
return { path: SHARED_ENTRYPOINT, namespace };
});
// Generate the virtual `entry-points` file based on the actions we discovered.
// Restrict using the namespace. The path filter does not need to discriminate any further.
build.onLoad({ filter: /.*/, namespace }, async () => {
const wrapperTemplatePath = "entry-wrapper.js.tpl";
const wrapperTemplate = await readFile(
join(SRC_DIR, wrapperTemplatePath),
"utf-8",
);
const actionsSorted = actions.sort((a, b) =>
a.name.localeCompare(b.name),
);
const imports = actionsSorted
.map(
(action) =>
`import * as ${action.pascalCaseName} from "./src/${basename(action.path)}"`,
)
.join("\n");
const wrappers = actionsSorted
.map((action) =>
wrapperTemplate.replaceAll("__ACTION__", action.pascalCaseName),
)
.join("\n\n");
return {
contents: `"use strict";\n${imports}\n\n${wrappers}\n`,
resolveDir: ".",
loader: "ts",
};
});
// Emit entry point stubs for each action using the entry template.
build.onEnd(async (result) => {
// Read the entry point template.
@@ -119,7 +164,10 @@ const entryPointsPlugin = {
const context = await esbuild.context({
// Include upload-lib.ts as an entry point for use in testing environments.
entryPoints: globSync(["src/entry-points.ts", "src/upload-lib.ts"]),
entryPoints: [
{ in: SHARED_ENTRYPOINT, out: SHARED_ENTRYPOINT },
join(SRC_DIR, "upload-lib.ts"),
],
bundle: true,
format: "cjs",
outdir: OUT_DIR,
+25 -25
View File
@@ -144935,7 +144935,7 @@ var require_lib6 = __commonJS({
}
});
// src/entry-points.ts
// actions:entry-points
var entry_points_exports = {};
__export(entry_points_exports, {
runAnalyzeAction: () => runAnalyzeAction,
@@ -161198,39 +161198,39 @@ async function runWrapper11() {
}
}
// src/entry-points.ts
// actions:entry-points
async function runAnalyzeAction() {
void runWrapper();
}
async function runAutobuildAction() {
void runWrapper3();
}
async function runInitAction() {
void runWrapper4();
}
async function runResolveEnvironmentAction() {
void runWrapper6();
}
async function runSetupCodeqlAction() {
void runWrapper7();
}
async function runStartProxyAction() {
void runWrapper8();
}
async function runUploadSarifAction() {
void runWrapper10();
return await runWrapper();
}
async function runAnalyzePostAction() {
void runWrapper2();
return await runWrapper2();
}
async function runAutobuildAction() {
return await runWrapper3();
}
async function runInitAction() {
return await runWrapper4();
}
async function runInitPostAction() {
void runWrapper5();
return await runWrapper5();
}
async function runResolveEnvironmentAction() {
return await runWrapper6();
}
async function runSetupCodeqlAction() {
return await runWrapper7();
}
async function runStartProxyAction() {
return await runWrapper8();
}
async function runStartProxyPostAction() {
void runWrapper9();
return await runWrapper9();
}
async function runUploadSarifAction() {
return await runWrapper10();
}
async function runUploadSarifPostAction() {
void runWrapper11();
return await runWrapper11();
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
-55
View File
@@ -1,55 +0,0 @@
import * as analyzeAction from "./analyze-action";
import * as analyzePostAction from "./analyze-action-post";
import * as autobuildAction from "./autobuild-action";
import * as initAction from "./init-action";
import * as initPostAction from "./init-action-post";
import * as resolveEnvironmentAction from "./resolve-environment-action";
import * as setupCodeqlAction from "./setup-codeql-action";
import * as startProxyAction from "./start-proxy-action";
import * as startProxyPostAction from "./start-proxy-action-post";
import * as uploadSarifAction from "./upload-sarif-action";
import * as uploadSarifPostAction from "./upload-sarif-action-post";
export async function runAnalyzeAction() {
void analyzeAction.runWrapper();
}
export async function runAutobuildAction() {
void autobuildAction.runWrapper();
}
export async function runInitAction() {
void initAction.runWrapper();
}
export async function runResolveEnvironmentAction() {
void resolveEnvironmentAction.runWrapper();
}
export async function runSetupCodeqlAction() {
void setupCodeqlAction.runWrapper();
}
export async function runStartProxyAction() {
void startProxyAction.runWrapper();
}
export async function runUploadSarifAction() {
void uploadSarifAction.runWrapper();
}
export async function runAnalyzePostAction() {
void analyzePostAction.runWrapper();
}
export async function runInitPostAction() {
void initPostAction.runWrapper();
}
export async function runStartProxyPostAction() {
void startProxyPostAction.runWrapper();
}
export async function runUploadSarifPostAction() {
void uploadSarifPostAction.runWrapper();
}
+3
View File
@@ -0,0 +1,3 @@
export async function run__ACTION__() {
return await __ACTION__.runWrapper();
}