Updates
This commit is contained in:
Executable
+137
@@ -0,0 +1,137 @@
|
||||
// @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);
|
||||
}
|
||||
});
|
||||
Executable
+95
@@ -0,0 +1,95 @@
|
||||
// @ts-check
|
||||
|
||||
import http from "http";
|
||||
import path from "path";
|
||||
import childProcess, { ChildProcess } from "child_process";
|
||||
const { spawn, spawnSync, execSync } = childProcess;
|
||||
|
||||
require("dotenv").config({
|
||||
path: path.resolve(__dirname, "../.env"),
|
||||
});
|
||||
|
||||
const environment = process.env.NODE_ENVIRONMENT;
|
||||
|
||||
const workingDirectory = path.resolve(__dirname, "../");
|
||||
|
||||
// process.stdin.addListener("data", (message) => {
|
||||
// console.log("MEssage received =>", message);
|
||||
// });
|
||||
|
||||
process.on("message", (message) => {
|
||||
console.log("Message received =>", message);
|
||||
if (message == "exit") {
|
||||
process.exit();
|
||||
}
|
||||
});
|
||||
|
||||
const args = environment?.match(/prod/i) ? ["start"] : ["run", "dev"];
|
||||
|
||||
let child: ChildProcess = spawn("bun", args, {
|
||||
cwd: workingDirectory,
|
||||
stdio: "inherit",
|
||||
shell: environment?.match(/prod/i) ? undefined : "bash.exe",
|
||||
});
|
||||
|
||||
const PORT = process.env.DSQL_DEPLOY_SERVER_PORT || 1276;
|
||||
|
||||
// deepcode ignore NoRateLimitingForExpensiveWebOperation: <Web Server is only accessible locally>, deepcode ignore HttpToHttps: <Server is not exposed to the web>
|
||||
http.createServer((req, res) => {
|
||||
if (req.url == "/" + process.env.DEPLOY_ROUTE) {
|
||||
async function redeploy() {
|
||||
/** @type {import("child_process").SpawnSyncOptionsWithBufferEncoding} */
|
||||
const options: import("child_process").SpawnSyncOptionsWithBufferEncoding =
|
||||
{
|
||||
cwd: workingDirectory,
|
||||
stdio: "inherit",
|
||||
};
|
||||
|
||||
if (process.platform?.match(/win/i)) {
|
||||
options.shell = "bash.exe";
|
||||
}
|
||||
|
||||
if (environment?.match(/prod/i)) {
|
||||
spawnSync("git", ["checkout", "."], options);
|
||||
spawnSync("git", ["pull"], options);
|
||||
spawnSync("bun", ["install"], options);
|
||||
spawnSync("bun", ["run", "build"], options);
|
||||
|
||||
try {
|
||||
child.kill();
|
||||
const existingProcessId = execSync(
|
||||
`lsof -i :2763 | grep LISTEN | awk '{print $2}'`
|
||||
);
|
||||
console.log(
|
||||
"Existing Process Id GREPED",
|
||||
existingProcessId.toString()
|
||||
);
|
||||
execSync(`kill ${existingProcessId.toString()}`);
|
||||
// spawnSync("kill", [existingProcessId.toString()], options);
|
||||
// spawnSync("kill", [`${child.pid}`], options);
|
||||
} catch (/** @type {any} */ error: any) {
|
||||
console.log("Error killing child process", error.message);
|
||||
}
|
||||
|
||||
child = spawn("bun", args, {
|
||||
cwd: workingDirectory,
|
||||
stdio: "inherit",
|
||||
shell: environment?.match(/prod/i) ? undefined : "bash.exe",
|
||||
});
|
||||
} else {
|
||||
spawnSync("git", ["status"], options);
|
||||
spawnSync("bun", ["list", "next"], options);
|
||||
|
||||
console.log("Not in production, Continuing ...");
|
||||
}
|
||||
}
|
||||
|
||||
redeploy();
|
||||
|
||||
res.statusCode = 200;
|
||||
res.end("Deployed");
|
||||
} else {
|
||||
res.statusCode = 402;
|
||||
res.end("Unauthorized");
|
||||
}
|
||||
}).listen(PORT, () => console.log("Deployment Server Started on Port", PORT));
|
||||
@@ -0,0 +1,13 @@
|
||||
server {
|
||||
listen 7071;
|
||||
|
||||
root /root/datasquirel_static;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name localhost;
|
||||
|
||||
root /static;
|
||||
}
|
||||
Reference in New Issue
Block a user