138 lines
3.9 KiB
TypeScript
138 lines
3.9 KiB
TypeScript
|
// @ts-check
|
||
|
import path from "path";
|
||
|
import fs from "fs";
|
||
|
import { execSync, spawnSync } from "child_process";
|
||
|
|
||
|
require("dotenv").config({
|
||
|
path: path.resolve(__dirname, "../.env"),
|
||
|
});
|
||
|
|
||
|
const isLocal = process.env.NEXT_PUBLIC_DSQL_LOCAL || null;
|
||
|
const DIST_DIR = path.resolve(process.cwd(), "./.dist");
|
||
|
let PREV_BUILD_NO = "0";
|
||
|
|
||
|
const MAX_BUILDS = process.env.DSQL_MAX_BUILDS
|
||
|
? Number(process.env.DSQL_MAX_BUILDS)
|
||
|
: 10;
|
||
|
|
||
|
if (
|
||
|
MAX_BUILDS < 1 ||
|
||
|
Number.isNaN(MAX_BUILDS) ||
|
||
|
typeof MAX_BUILDS !== "number"
|
||
|
) {
|
||
|
throw new Error("Invalid MAX_BUILDS");
|
||
|
}
|
||
|
|
||
|
if (!fs.existsSync(DIST_DIR)) fs.mkdirSync(DIST_DIR);
|
||
|
|
||
|
if (fs.existsSync(`${DIST_DIR}/BUILD`)) {
|
||
|
PREV_BUILD_NO = fs.readFileSync(`${DIST_DIR}/BUILD`, "utf-8");
|
||
|
} else {
|
||
|
fs.writeFileSync(`${DIST_DIR}/BUILD`, "0", "utf-8");
|
||
|
}
|
||
|
|
||
|
try {
|
||
|
const buildNumber = fs.readFileSync(`${DIST_DIR}/BUILD`, "utf-8");
|
||
|
const newBuildNumber = Number(buildNumber) + 1;
|
||
|
|
||
|
if (newBuildNumber < 0) {
|
||
|
throw new Error("Invalid Build Number");
|
||
|
}
|
||
|
|
||
|
fs.writeFileSync(`${DIST_DIR}/BUILD`, String(newBuildNumber));
|
||
|
|
||
|
if (newBuildNumber > MAX_BUILDS) {
|
||
|
const builds = fs.readdirSync(DIST_DIR);
|
||
|
const buildDirs = builds.filter((build) => build.match(/build-\d+/));
|
||
|
for (const buildDir of buildDirs) {
|
||
|
const buildDirPath = path.join(DIST_DIR, buildDir);
|
||
|
const buildDirStat = fs.statSync(buildDirPath);
|
||
|
if (buildDirStat.isDirectory()) {
|
||
|
const buildDirName = buildDir.split("-")[1];
|
||
|
const buildDirNumber = Number(buildDirName);
|
||
|
|
||
|
if (buildDirNumber <= newBuildNumber - MAX_BUILDS) {
|
||
|
fs.rmdirSync(buildDirPath, { recursive: true });
|
||
|
console.log("Deleted Build Directory =>", buildDirPath);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
} catch (error: any) {
|
||
|
console.log("Build Number Parse Error =>", error.message);
|
||
|
process.exit(1);
|
||
|
}
|
||
|
|
||
|
/** @type {import('child_process').SpawnSyncOptionsWithStringEncoding} */
|
||
|
const spawnSyncOptions: import("child_process").SpawnSyncOptionsWithStringEncoding =
|
||
|
{
|
||
|
stdio: "inherit",
|
||
|
encoding: "utf-8",
|
||
|
shell: process.platform?.match(/win32/i) ? "bash.exe" : undefined,
|
||
|
env: {
|
||
|
...process.env,
|
||
|
BUILDING_APP: "true",
|
||
|
},
|
||
|
};
|
||
|
|
||
|
const build = spawnSync("bunx", ["next", "build"], spawnSyncOptions);
|
||
|
|
||
|
/**
|
||
|
* @returns {string}
|
||
|
*/
|
||
|
function grabNewDistDir(): string {
|
||
|
if (isLocal) return ".local_dist";
|
||
|
|
||
|
try {
|
||
|
const buildNumber = fs.readFileSync(`${DIST_DIR}/BUILD`, "utf-8");
|
||
|
return `.dist/build-${buildNumber}`;
|
||
|
} catch (/** @type {*} */ error: any) {
|
||
|
console.log("Build Number Parse Error =>", error.message);
|
||
|
process.exit();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const newDistDir = grabNewDistDir();
|
||
|
|
||
|
/**
|
||
|
* # Revert Directories
|
||
|
* @param {string} dir - New Build Directory Path
|
||
|
*/
|
||
|
function revert(dir: string) {
|
||
|
console.log("Build Failed!", build?.error?.message || build.stderr);
|
||
|
fs.writeFileSync(`${DIST_DIR}/BUILD`, PREV_BUILD_NO, "utf-8");
|
||
|
execSync(`rm -Rf ${dir}`, { cwd: process.cwd() });
|
||
|
|
||
|
const writeErr = build.error
|
||
|
? build.error.message
|
||
|
: build.stderr
|
||
|
? build.stderr.toString()
|
||
|
: "NO BUILD_ID found in New Build Folder";
|
||
|
fs.writeFileSync(
|
||
|
`${DIST_DIR}/LAST_BUILD_FAIL`,
|
||
|
Date() + "\n\n" + writeErr,
|
||
|
"utf-8"
|
||
|
);
|
||
|
|
||
|
process.exit(1);
|
||
|
}
|
||
|
|
||
|
if (
|
||
|
build.error ||
|
||
|
build.stderr ||
|
||
|
build.status != 0 ||
|
||
|
!fs.existsSync(`${newDistDir}/BUILD_ID`)
|
||
|
) {
|
||
|
if (!isLocal) {
|
||
|
revert(newDistDir);
|
||
|
throw new Error("Build Failed!");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
process.on("exit", () => {
|
||
|
const onExitDir = grabNewDistDir();
|
||
|
if (!fs.existsSync(`${onExitDir}/BUILD_ID`) && !isLocal) {
|
||
|
revert(onExitDir);
|
||
|
}
|
||
|
});
|