This commit is contained in:
Benjamin Toby
2025-02-03 13:41:13 +01:00
parent cee4bc0478
commit 619afc8303
29 changed files with 722 additions and 169 deletions
+5
View File
@@ -0,0 +1,5 @@
#!/usr/bin/env bun
declare global {
var REDEPLOYMENTS: number;
}
export {};
+53
View File
@@ -0,0 +1,53 @@
#!/usr/bin/env bun
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const console_colors_1 = __importDefault(require("./utils/console-colors"));
const start_1 = __importDefault(require("./utils/start"));
const WORK_DIR = process.cwd();
global.REDEPLOYMENTS = 0;
function run() {
try {
const configText = fs_1.default.readFileSync(path_1.default.join(WORK_DIR, "buncid.config.json"), "utf-8");
const config = JSON.parse(configText);
const { start, preflight, postflight, build, redeploy_path, first_run, port, } = config;
let redeployFile;
if (!redeploy_path) {
const defaultRedeployPath = path_1.default.join(WORK_DIR, "REDEPLOY");
const checkExistingPath = fs_1.default.existsSync(defaultRedeployPath);
if (!checkExistingPath) {
fs_1.default.writeFileSync(defaultRedeployPath, Date.now().toString(), "utf-8");
}
redeployFile = path_1.default.join(WORK_DIR, "REDEPLOY");
}
else {
redeployFile = path_1.default.resolve(WORK_DIR, redeploy_path);
}
if (!redeployFile)
throw new Error("Redeploy file variable not provided!");
if (!fs_1.default.existsSync(redeployFile))
throw new Error("Redeploy file not found!");
(0, start_1.default)({
command: start,
preflight,
redeploy_file: redeployFile,
first_run,
port,
postflight,
});
}
catch (error) {
console.log(`${console_colors_1.default.FgRed}ERROR:${console_colors_1.default.Reset} CI process failed! => ${error.message}`);
}
}
run();
process.on("exit", () => {
console.log("Process exiting ...");
});
process.on("beforeExit", () => {
console.log("Process Before exit ...");
});
+9 -5
View File
@@ -1,5 +1,9 @@
#!/usr/bin/env bun
declare global {
var REDEPLOYMENTS: number;
}
export {};
import grabDist from "./rebuilds/next-js/grabDist";
declare const buncid: {
builds: {
nextJs: {
grabDist: typeof grabDist;
};
};
};
export default buncid;
+9 -46
View File
@@ -1,51 +1,14 @@
#!/usr/bin/env bun
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const console_colors_1 = __importDefault(require("./utils/console-colors"));
const start_1 = __importDefault(require("./utils/start"));
const WORK_DIR = process.cwd();
global.REDEPLOYMENTS = 0;
function run() {
try {
const configText = fs_1.default.readFileSync(path_1.default.join(WORK_DIR, "buncid.config.json"), "utf-8");
const config = JSON.parse(configText);
const { start, preflight, postflight, build, redeploy_path, first_run, port, } = config;
let redeployFile;
if (!redeploy_path) {
const defaultRedeployPath = path_1.default.join(WORK_DIR, "REDEPLOY");
const checkExistingPath = fs_1.default.existsSync(defaultRedeployPath);
if (!checkExistingPath) {
fs_1.default.writeFileSync(defaultRedeployPath, Date.now().toString(), "utf-8");
}
redeployFile = path_1.default.join(WORK_DIR, "REDEPLOY");
}
else {
redeployFile = path_1.default.resolve(WORK_DIR, redeploy_path);
}
if (!redeployFile)
throw new Error("Redeploy file not found!");
(0, start_1.default)({
command: start,
preflight,
redeploy_file: redeployFile,
first_run,
port,
postflight,
});
}
catch (error) {
console.log(`${console_colors_1.default.FgRed}ERROR:${console_colors_1.default.Reset} CI process failed! => ${error.message}`);
}
}
run();
process.on("exit", () => {
console.log("Process exiting ...");
});
process.on("beforeExit", () => {
console.log("Process Before exit ...");
});
const grabDist_1 = __importDefault(require("./rebuilds/next-js/grabDist"));
const buncid = {
builds: {
nextJs: {
grabDist: grabDist_1.default,
},
},
};
exports.default = buncid;
+6
View File
@@ -0,0 +1,6 @@
/**
* # Grab the current distribution directory
* @description This returns the relative path from the CWD. Eg `./.dist/build-1`
* @returns {string | undefined}
*/
export default function grabDist(): string | undefined;
+45
View File
@@ -0,0 +1,45 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = grabDist;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const production = process.env.NODE_ENV == "production";
const isBuilding = process.env.BUILDING_APP;
/**
* # Grab the current distribution directory
* @description This returns the relative path from the CWD. Eg `./.dist/build-1`
* @returns {string | undefined}
*/
function grabDist() {
const DIST_DIR = path_1.default.resolve(process.cwd(), "./.dist");
if (isBuilding) {
const distDir = (() => {
try {
const buildNumber = fs_1.default.readFileSync(`${DIST_DIR}/BUILD`, "utf-8");
return `.dist/build-${buildNumber}`;
}
catch ( /** @type {*} */error) {
console.log("Build Number Generation Error =>", error.message);
process.exit();
}
})();
return distDir;
}
if (production) {
const distDir = (() => {
try {
const buildNumber = fs_1.default.readFileSync(`${DIST_DIR}/BUILD`, "utf-8");
return `.dist/build-${buildNumber}`;
}
catch ( /** @type {*} */error) {
console.log("Build Number Parse Error =>", error.message);
process.exit();
}
})();
return distDir;
}
return undefined;
}
+2
View File
@@ -0,0 +1,2 @@
#!/usr/bin/env bun
export {};
+113
View File
@@ -0,0 +1,113 @@
#!/usr/bin/env bun
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
const path_1 = __importDefault(require("path"));
const fs_1 = __importDefault(require("fs"));
const child_process_1 = require("child_process");
const DIST_DIR = path_1.default.resolve(process.cwd(), "./.dist");
let PREV_BUILD_NO = "0";
const MAX_BUILDS = process.env.BUNCID_MAX_BUILDS
? Number(process.env.BUNCID_MAX_BUILDS)
: 10;
if (MAX_BUILDS < 1 ||
Number.isNaN(MAX_BUILDS) ||
typeof MAX_BUILDS !== "number") {
throw new Error("Invalid MAX_BUILDS");
}
if (!fs_1.default.existsSync(DIST_DIR))
fs_1.default.mkdirSync(DIST_DIR);
if (fs_1.default.existsSync(`${DIST_DIR}/BUILD`)) {
PREV_BUILD_NO = fs_1.default.readFileSync(`${DIST_DIR}/BUILD`, "utf-8");
}
else {
fs_1.default.writeFileSync(`${DIST_DIR}/BUILD`, "0", "utf-8");
}
try {
const buildNumber = fs_1.default.readFileSync(`${DIST_DIR}/BUILD`, "utf-8");
const newBuildNumber = Number(buildNumber) + 1;
if (newBuildNumber < 0) {
throw new Error("Invalid Build Number");
}
fs_1.default.writeFileSync(`${DIST_DIR}/BUILD`, String(newBuildNumber));
if (newBuildNumber > MAX_BUILDS) {
const builds = fs_1.default.readdirSync(DIST_DIR);
const buildDirs = builds.filter((build) => build.match(/build-\d+/));
for (const buildDir of buildDirs) {
const buildDirPath = path_1.default.join(DIST_DIR, buildDir);
const buildDirStat = fs_1.default.statSync(buildDirPath);
if (buildDirStat.isDirectory()) {
const buildDirName = buildDir.split("-")[1];
const buildDirNumber = Number(buildDirName);
if (buildDirNumber <= newBuildNumber - MAX_BUILDS) {
fs_1.default.rmdirSync(buildDirPath, { recursive: true });
console.log("Deleted Build Directory =>", buildDirPath);
}
}
}
}
}
catch (error) {
console.log("Build Number Parse Error =>", error.message);
process.exit(1);
}
const spawnSyncOptions = {
stdio: "inherit",
encoding: "utf-8",
shell: ((_a = process.platform) === null || _a === void 0 ? void 0 : _a.match(/win32/i)) ? "bash.exe" : undefined,
env: Object.assign(Object.assign({}, process.env), { BUILDING_APP: "true" }),
};
const build = (0, child_process_1.spawnSync)("bunx", ["next", "build"], spawnSyncOptions);
/**
* @returns {string}
*/
function grabNewDistDir() {
try {
const buildNumber = fs_1.default.readFileSync(`${DIST_DIR}/BUILD`, "utf-8");
return `.dist/build-${buildNumber}`;
}
catch ( /** @type {*} */error) {
console.log("Build Number Parse Error =>", error.message);
process.exit();
}
}
const newDistDir = grabNewDistDir();
// if (!fs.existsSync(newDistDir)) {
// fs.mkdirSync(newDistDir, { recursive: true });
// }
// if (!fs.existsSync(`${newDistDir}/BUILD_ID`)) {
// fs.writeFileSync(`${newDistDir}/BUILD_ID`, "4");
// }
/**
* # Revert Directories
* @param {string} dir - New Build Directory Path
*/
function revert(dir) {
var _a;
console.log("Build Failed!", ((_a = build === null || build === void 0 ? void 0 : build.error) === null || _a === void 0 ? void 0 : _a.message) || build.stderr);
fs_1.default.writeFileSync(`${DIST_DIR}/BUILD`, PREV_BUILD_NO, "utf-8");
(0, child_process_1.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_1.default.writeFileSync(`${DIST_DIR}/LAST_BUILD_FAIL`, Date() + "\n\n" + writeErr, "utf-8");
process.exit(1);
}
if (build.error ||
build.stderr ||
build.status != 0 ||
!fs_1.default.existsSync(`${newDistDir}/BUILD_ID`)) {
revert(newDistDir);
throw new Error("Build Failed!");
}
process.on("exit", () => {
const onExitDir = grabNewDistDir();
if (!fs_1.default.existsSync(`${onExitDir}/BUILD_ID`)) {
revert(onExitDir);
}
});
+6
View File
@@ -0,0 +1,6 @@
/**
* # Grab the current distribution directory
* @description This returns the relative path from the CWD. Eg `./.dist/build-1`
* @returns {string | undefined}
*/
export default function grabDist(): string | undefined;
+45
View File
@@ -0,0 +1,45 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = grabDist;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const production = process.env.NODE_ENV == "production";
const isBuilding = process.env.BUILDING_APP;
/**
* # Grab the current distribution directory
* @description This returns the relative path from the CWD. Eg `./.dist/build-1`
* @returns {string | undefined}
*/
function grabDist() {
const DIST_DIR = path_1.default.resolve(process.cwd(), "./.dist");
if (isBuilding) {
const distDir = (() => {
try {
const buildNumber = fs_1.default.readFileSync(`${DIST_DIR}/BUILD`, "utf-8");
return `.dist/build-${buildNumber}`;
}
catch ( /** @type {*} */error) {
console.log("Build Number Generation Error =>", error.message);
process.exit();
}
})();
return distDir;
}
if (production) {
const distDir = (() => {
try {
const buildNumber = fs_1.default.readFileSync(`${DIST_DIR}/BUILD`, "utf-8");
return `.dist/build-${buildNumber}`;
}
catch ( /** @type {*} */error) {
console.log("Build Number Parse Error =>", error.message);
process.exit();
}
})();
return distDir;
}
return undefined;
}
+3
View File
@@ -0,0 +1,3 @@
import type { NextConfig } from "next";
declare const nextConfig: NextConfig;
export default nextConfig;
+13
View File
@@ -0,0 +1,13 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const grabDist_1 = __importDefault(require("./functions/grabDist"));
const distDir = (0, grabDist_1.default)();
const nextConfig = {
/* config options here */
reactStrictMode: true,
distDir,
};
exports.default = nextConfig;
+6
View File
@@ -0,0 +1,6 @@
import type { NextApiRequest, NextApiResponse } from "next";
type Data = {
name: string;
};
export default function handler(req: NextApiRequest, res: NextApiResponse<Data>): void;
export {};
+6
View File
@@ -0,0 +1,6 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = handler;
function handler(req, res) {
res.status(200).json({ name: "John Doe" });
}
+13
View File
@@ -0,0 +1,13 @@
declare const _default: {
content: string[];
theme: {
extend: {
colors: {
background: string;
foreground: string;
};
};
};
plugins: never[];
};
export default _default;
+18
View File
@@ -0,0 +1,18 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = {
content: [
"./pages/**/*.{js,ts,jsx,tsx,mdx}",
"./components/**/*.{js,ts,jsx,tsx,mdx}",
"./app/**/*.{js,ts,jsx,tsx,mdx}",
],
theme: {
extend: {
colors: {
background: "var(--background)",
foreground: "var(--foreground)",
},
},
},
plugins: [],
};
+1 -1
View File
File diff suppressed because one or more lines are too long
+10 -7
View File
@@ -27,15 +27,18 @@ function killChild(childProcess, port) {
try {
const childProcessPID = childProcess.pid;
childProcess.kill();
if (typeof port == "object" && (port === null || port === void 0 ? void 0 : port[0])) {
for (let i = 0; i < port.length; i++) {
const singlePort = port[i];
yield (0, kill_port_1.default)(Number(singlePort));
try {
if (typeof port == "object" && (port === null || port === void 0 ? void 0 : port[0])) {
for (let i = 0; i < port.length; i++) {
const singlePort = port[i];
yield (0, kill_port_1.default)(Number(singlePort));
}
}
else if (port) {
yield (0, kill_port_1.default)(Number(port));
}
}
else if (port) {
yield (0, kill_port_1.default)(Number(port));
}
catch (error) { }
return true;
}
catch (error) {
+1 -1
View File
@@ -10,7 +10,7 @@
*/
export default function startProcess({ command, preflight, postflight, redeploy_file, port, first_run, }: {
command: string;
preflight: string[] | string;
preflight?: string[] | string;
postflight?: string[] | string;
redeploy_file: string;
port?: string | number | (string | number)[];
+1 -6
View File
@@ -26,11 +26,7 @@ function startProcess({ command, preflight, postflight, redeploy_file, port, fir
try {
if (first_run) {
console.log("First Run ...");
const runPreflight = (0, preflight_1.default)(preflight);
}
if (!preflight) {
console.log(`${console_colors_1.default.FgRed}Error:${console_colors_1.default.Reset} No preflight included in config file. If you don't want to run any preflight command simply add an empty array.`);
process.exit();
const runFirstPreflight = (0, preflight_1.default)(preflight);
}
childProcess = (0, run_1.default)(command);
if (!childProcess) {
@@ -50,7 +46,6 @@ function startProcess({ command, preflight, postflight, redeploy_file, port, fir
try {
const runPreflight = (0, preflight_1.default)(preflight);
if (!runPreflight) {
// TODO: Action to take if preflight fails
console.log(`${console_colors_1.default.FgRed}Error:${console_colors_1.default.Reset} Preflight Failed.`);
}
else {