mirror of
https://github.com/Sea-Haven-Industries/payments-dashboard.git
synced 2026-09-30 13:33:12 +00:00
92 lines
2.9 KiB
JavaScript
92 lines
2.9 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Build one Node zip per Lambda key. Used by deploy.yaml.
|
|
* Each zip is functions/<name>/<sha>.zip on S3. GIT_SHA is written to
|
|
* src/buildInfo.js inside the zip so a deploy is identifiable without a
|
|
* Terraform-owned env var.
|
|
*/
|
|
import { spawn, spawnSync } from "node:child_process";
|
|
import { cpSync, existsSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
import { tmpdir } from "node:os";
|
|
import { join, resolve } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
const ROOT = fileURLToPath(new URL("..", import.meta.url));
|
|
|
|
const FUNCTIONS = [
|
|
"process_csv",
|
|
"slack_app_home",
|
|
"fetch_boa",
|
|
"expense_receiver",
|
|
"expense_processor",
|
|
];
|
|
|
|
function parseArgs(argv) {
|
|
const out = { gitSha: "", outDir: join(ROOT, "build", "packages"), only: [] };
|
|
for (let i = 0; i < argv.length; i += 1) {
|
|
const arg = argv[i];
|
|
if (arg === "--git-sha") {
|
|
out.gitSha = argv[++i];
|
|
} else if (arg === "--out-dir") {
|
|
out.outDir = resolve(argv[++i]);
|
|
} else if (arg === "--only") {
|
|
out.only.push(argv[++i]);
|
|
} else {
|
|
throw new Error(`unknown argument: ${arg}`);
|
|
}
|
|
}
|
|
if (!out.gitSha) {
|
|
throw new Error("--git-sha is required");
|
|
}
|
|
return out;
|
|
}
|
|
|
|
function zipDir(srcDir, zipPath) {
|
|
return new Promise((resolve, reject) => {
|
|
const child = spawn("zip", ["-qr", zipPath, "."], { cwd: srcDir, stdio: "inherit" });
|
|
child.on("exit", (code) => {
|
|
if (code === 0) resolve();
|
|
else reject(new Error(`zip exited ${code}`));
|
|
});
|
|
});
|
|
}
|
|
|
|
async function build(name, gitSha, outDir) {
|
|
const dest = mkdtempSync(join(tmpdir(), `payments-${name}-`));
|
|
try {
|
|
cpSync(join(ROOT, "src"), join(dest, "src"), { recursive: true });
|
|
cpSync(join(ROOT, "package.json"), join(dest, "package.json"));
|
|
if (existsSync(join(ROOT, "package-lock.json"))) {
|
|
cpSync(join(ROOT, "package-lock.json"), join(dest, "package-lock.json"));
|
|
}
|
|
writeFileSync(
|
|
join(dest, "src", "buildInfo.js"),
|
|
`export const GIT_SHA = ${JSON.stringify(gitSha)};\n`,
|
|
"utf8",
|
|
);
|
|
const npm = spawnSync("npm", ["ci", "--omit=dev"], { cwd: dest, stdio: "inherit" });
|
|
if (npm.status !== 0) {
|
|
throw new Error("npm ci --omit=dev failed");
|
|
}
|
|
mkdirSync(outDir, { recursive: true });
|
|
const zipPath = resolve(outDir, `${name}.zip`);
|
|
rmSync(zipPath, { force: true });
|
|
await zipDir(dest, zipPath);
|
|
return zipPath;
|
|
} finally {
|
|
rmSync(dest, { recursive: true, force: true });
|
|
}
|
|
}
|
|
|
|
const args = parseArgs(process.argv.slice(2));
|
|
const selected = args.only.length ? args.only : FUNCTIONS;
|
|
const unknown = selected.filter((name) => !FUNCTIONS.includes(name));
|
|
if (unknown.length) {
|
|
console.error(`unknown function keys: ${unknown.join(", ")}`);
|
|
process.exit(2);
|
|
}
|
|
|
|
for (const name of selected) {
|
|
const path = await build(name, args.gitSha, args.outDir);
|
|
console.log(path);
|
|
}
|