Compare commits
No commits in common. "a3e20f15efc2ca775e171e2dca21793bf08e478a" and "05f380f691f158da4b7aaba5eced3ac84ee83056" have entirely different histories.
a3e20f15ef
...
05f380f691
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,2 @@
|
|||||||
node_modules
|
node_modules
|
||||||
/node_modules
|
|
||||||
/test
|
/test
|
2
.npmrc
2
.npmrc
@ -1,2 +0,0 @@
|
|||||||
@moduletrace:registry=https://git.tben.me/api/packages/moduletrace/npm/
|
|
||||||
//git.tben.me/api/packages/moduletrace/npm/:_authToken=${GITBEN_NPM_TOKEN}
|
|
9
.vscode/settings.json
vendored
9
.vscode/settings.json
vendored
@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"files.associations": {
|
|
||||||
"ostream": "cpp"
|
|
||||||
},
|
|
||||||
"[python]": {
|
|
||||||
"editor.defaultFormatter": "ms-python.autopep8"
|
|
||||||
},
|
|
||||||
"python.formatting.provider": "none"
|
|
||||||
}
|
|
14
README.md
14
README.md
@ -1,10 +1,5 @@
|
|||||||
# Simple CI/CD package for any application
|
# Simple CI/CD package for any application
|
||||||
|
|
||||||
[](https://npmjs.org/package/nodecid)
|
|
||||||
[](https://npmjs.org/package/nodecid)
|
|
||||||
[](https://github.com/RichardLitt/standard-readme)
|
|
||||||
[](https://npmjs.org/package/nodecid)
|
|
||||||
|
|
||||||
Integrate a simple CI/CD process into your application without the hassle.
|
Integrate a simple CI/CD process into your application without the hassle.
|
||||||
|
|
||||||
_**NOTE:** This package needs `node` installed to work_
|
_**NOTE:** This package needs `node` installed to work_
|
||||||
@ -95,15 +90,6 @@ _NOTE:_ This also works for other languages, example:
|
|||||||
|
|
||||||
This app just runs whatever command you send it in an isolated child process, the command will be run as if being run in a terminal.
|
This app just runs whatever command you send it in an isolated child process, the command will be run as if being run in a terminal.
|
||||||
|
|
||||||
#### All Available options in `nodecid.config.json` file
|
|
||||||
|
|
||||||
- **`start`**: _string_: The start Command
|
|
||||||
- **`preflight`**: _string | Array_: Array of commands or shell script file to run before reloading application
|
|
||||||
- **`postflight`**: _string | Array_: _Optional_: Array of commands or shell script file to run after reloading application
|
|
||||||
- **`redeploy_path`**: _string_: _Optional_: The path to trigger a redeployment. Default `./REDEPLOY`
|
|
||||||
- **`port`**: _string | number | (string | number)[]_: _Optional_: A port(or array of ports) to kill if running a server. _NOTE_: it is important to provide this option if running a server else the process may not terminate properly
|
|
||||||
- **`first_run`**: _boolean_: _Optional_: If the preflight should run on first run. Default `false`.
|
|
||||||
|
|
||||||
### Redeployment
|
### Redeployment
|
||||||
|
|
||||||
For continuos deployment and integration there needs to be a text file located in your project which the application can watch. Any time the content of this file is changed the application will rebuild and rerun your `start` command.
|
For continuos deployment and integration there needs to be a text file located in your project which the application can watch. Any time the content of this file is changed the application will rebuild and rerun your `start` command.
|
||||||
|
BIN
bin/nodecid
BIN
bin/nodecid
Binary file not shown.
@ -3,17 +3,7 @@
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"start": {
|
"start": {
|
||||||
"anyOf": [
|
"type": "string"
|
||||||
{
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"preflight": {
|
"preflight": {
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
@ -30,9 +20,6 @@
|
|||||||
},
|
},
|
||||||
"redeploy_path": {
|
"redeploy_path": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
|
||||||
"first_run": {
|
|
||||||
"type": "boolean"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": ["start", "preflight"]
|
"required": ["start", "preflight"]
|
||||||
|
143
deploy/start.js
Executable file
143
deploy/start.js
Executable file
@ -0,0 +1,143 @@
|
|||||||
|
// @ts-check
|
||||||
|
|
||||||
|
const path = require("path");
|
||||||
|
const fs = require("fs");
|
||||||
|
const {
|
||||||
|
execSync,
|
||||||
|
spawnSync,
|
||||||
|
spawn,
|
||||||
|
execFile,
|
||||||
|
execFileSync,
|
||||||
|
ChildProcess,
|
||||||
|
} = require("child_process");
|
||||||
|
const colors = require("../utils/console-colors");
|
||||||
|
|
||||||
|
////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* # Start the process
|
||||||
|
* @param {object} param0
|
||||||
|
* @param {string} param0.command
|
||||||
|
* @param {string[] | string} param0.preflight
|
||||||
|
* @param {string} param0.redeploy_file
|
||||||
|
*/
|
||||||
|
function startProcess({ command, preflight, redeploy_file }) {
|
||||||
|
/** @type {ChildProcess | null} */
|
||||||
|
let childProcess = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const runPreflight = preflightFn(preflight);
|
||||||
|
|
||||||
|
if (!preflight) {
|
||||||
|
process.exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
childProcess = run(command);
|
||||||
|
|
||||||
|
if (!childProcess) {
|
||||||
|
console.log(
|
||||||
|
`${colors.FgRed}Error:${colors.Reset} Process couldn't start. Exiting...`
|
||||||
|
);
|
||||||
|
process.exit();
|
||||||
|
}
|
||||||
|
} catch (/** @type {*} */ error) {
|
||||||
|
console.log(
|
||||||
|
`${colors.FgRed}Error:${colors.Reset} First run failed! => ${error.message}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.watchFile(redeploy_file, { interval: 1000 }, (curr, prev) => {
|
||||||
|
if (childProcess) {
|
||||||
|
console.log("Rebuilding ...");
|
||||||
|
|
||||||
|
try {
|
||||||
|
const runPreflight = preflightFn(preflight);
|
||||||
|
|
||||||
|
if (!preflight) {
|
||||||
|
process.exit();
|
||||||
|
}
|
||||||
|
childProcess.kill("SIGTERM");
|
||||||
|
} catch (/** @type {*} */ error) {
|
||||||
|
console.log(
|
||||||
|
`${colors.FgRed}Error:${colors.Reset} killing child processes => ${error.message}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
childProcess = run(command);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ## Preflight Function
|
||||||
|
* @param {string} command
|
||||||
|
* @returns {ChildProcess | null}
|
||||||
|
*/
|
||||||
|
function run(command) {
|
||||||
|
const startCommandArray = command.split(" ").filter((str) => str.trim());
|
||||||
|
|
||||||
|
try {
|
||||||
|
const firstCommand = startCommandArray.shift()?.[0];
|
||||||
|
|
||||||
|
if (!firstCommand) {
|
||||||
|
throw new Error("No Starting Command Found in command string!");
|
||||||
|
}
|
||||||
|
|
||||||
|
let childProcess = spawn(firstCommand, ["server.js"], {
|
||||||
|
cwd: process.cwd(),
|
||||||
|
stdio: "inherit",
|
||||||
|
});
|
||||||
|
|
||||||
|
return childProcess;
|
||||||
|
} catch (/** @type {*} */ error) {
|
||||||
|
console.log(
|
||||||
|
`${colors.FgRed}Error:${colors.Reset} running start command => ${error.message}`
|
||||||
|
);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ## Preflight Function
|
||||||
|
* @param {string[] | string} preflight
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
function preflightFn(preflight) {
|
||||||
|
console.log("Preflight Running ...");
|
||||||
|
|
||||||
|
/** @type {import("child_process").ExecSyncOptions} */
|
||||||
|
const options = {
|
||||||
|
cwd: process.cwd(),
|
||||||
|
stdio: "inherit",
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (typeof preflight == "string") {
|
||||||
|
execFileSync(preflight, options);
|
||||||
|
} else if (typeof preflight == "object" && preflight?.[0]) {
|
||||||
|
preflight.forEach((cmd) => execSync(cmd, options));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} catch (error) {
|
||||||
|
console.log(
|
||||||
|
`${colors.FgRed}Error:${colors.Reset} Preflight Failed! => ${error.message}`
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////
|
||||||
|
|
||||||
|
module.exports = startProcess;
|
1
dist/index.d.ts
vendored
1
dist/index.d.ts
vendored
@ -1 +0,0 @@
|
|||||||
export {};
|
|
50
dist/index.js
vendored
50
dist/index.js
vendored
@ -1,50 +0,0 @@
|
|||||||
"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();
|
|
||||||
function run() {
|
|
||||||
try {
|
|
||||||
const configText = fs_1.default.readFileSync(path_1.default.join(WORK_DIR, "nodecid.config.json"), "utf-8");
|
|
||||||
const config = JSON.parse(configText);
|
|
||||||
const { start, preflight, postflight, build, redeploy_path, first_run, port, } = config;
|
|
||||||
/** @type {string | undefined} */
|
|
||||||
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 ...");
|
|
||||||
});
|
|
1
dist/tsconfig.tsbuildinfo
vendored
1
dist/tsconfig.tsbuildinfo
vendored
File diff suppressed because one or more lines are too long
13
dist/types.d.ts
vendored
13
dist/types.d.ts
vendored
@ -1,13 +0,0 @@
|
|||||||
export interface NodeCIConfig {
|
|
||||||
start: string;
|
|
||||||
preflight: string[] | string;
|
|
||||||
postflight?: string[] | string;
|
|
||||||
redeploy_path?: string;
|
|
||||||
first_run?: boolean;
|
|
||||||
port?: string | number | (string | number)[];
|
|
||||||
build?: NodeCIBuild;
|
|
||||||
}
|
|
||||||
export interface NodeCIBuild {
|
|
||||||
paradigm: "Next.JS" | "Remix";
|
|
||||||
out_dir?: string;
|
|
||||||
}
|
|
2
dist/types.js
vendored
2
dist/types.js
vendored
@ -1,2 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
28
dist/utils/console-colors.d.ts
vendored
28
dist/utils/console-colors.d.ts
vendored
@ -1,28 +0,0 @@
|
|||||||
declare const colors: {
|
|
||||||
Reset: string;
|
|
||||||
Bright: string;
|
|
||||||
Dim: string;
|
|
||||||
Underscore: string;
|
|
||||||
Blink: string;
|
|
||||||
Reverse: string;
|
|
||||||
Hidden: string;
|
|
||||||
FgBlack: string;
|
|
||||||
FgRed: string;
|
|
||||||
FgGreen: string;
|
|
||||||
FgYellow: string;
|
|
||||||
FgBlue: string;
|
|
||||||
FgMagenta: string;
|
|
||||||
FgCyan: string;
|
|
||||||
FgWhite: string;
|
|
||||||
FgGray: string;
|
|
||||||
BgBlack: string;
|
|
||||||
BgRed: string;
|
|
||||||
BgGreen: string;
|
|
||||||
BgYellow: string;
|
|
||||||
BgBlue: string;
|
|
||||||
BgMagenta: string;
|
|
||||||
BgCyan: string;
|
|
||||||
BgWhite: string;
|
|
||||||
BgGray: string;
|
|
||||||
};
|
|
||||||
export default colors;
|
|
6
dist/utils/kill-child.d.ts
vendored
6
dist/utils/kill-child.d.ts
vendored
@ -1,6 +0,0 @@
|
|||||||
/**
|
|
||||||
* ## Kill Child Process Function
|
|
||||||
* @param {string | number | (string | number)[]} [port]
|
|
||||||
* @returns {Promise<boolean>}
|
|
||||||
*/
|
|
||||||
export default function killChild(port?: string | number | (string | number)[]): Promise<boolean>;
|
|
47
dist/utils/kill-child.js
vendored
47
dist/utils/kill-child.js
vendored
@ -1,47 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
||||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
||||||
return new (P || (P = Promise))(function (resolve, reject) {
|
|
||||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
||||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
||||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
||||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
||||||
});
|
|
||||||
};
|
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.default = killChild;
|
|
||||||
const console_colors_1 = __importDefault(require("./console-colors"));
|
|
||||||
const kill_port_1 = __importDefault(require("kill-port"));
|
|
||||||
let childProcess = null;
|
|
||||||
/**
|
|
||||||
* ## Kill Child Process Function
|
|
||||||
* @param {string | number | (string | number)[]} [port]
|
|
||||||
* @returns {Promise<boolean>}
|
|
||||||
*/
|
|
||||||
function killChild(port) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
if (!childProcess)
|
|
||||||
return false;
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (port) {
|
|
||||||
yield (0, kill_port_1.default)(Number(port));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
console.log(`${console_colors_1.default.FgRed}Error:${console_colors_1.default.Reset} Child Process couldn't be killed! ${error.message}`);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
7
dist/utils/preflight.d.ts
vendored
7
dist/utils/preflight.d.ts
vendored
@ -1,7 +0,0 @@
|
|||||||
/**
|
|
||||||
* ## Preflight Function
|
|
||||||
* @param {string[] | string} preflight
|
|
||||||
* @param {boolean} [postflight]
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
export default function preflightFn(preflight?: string[] | string, postflight?: boolean): boolean;
|
|
45
dist/utils/preflight.js
vendored
45
dist/utils/preflight.js
vendored
@ -1,45 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.default = preflightFn;
|
|
||||||
const child_process_1 = require("child_process");
|
|
||||||
const console_colors_1 = __importDefault(require("../utils/console-colors"));
|
|
||||||
/**
|
|
||||||
* ## Preflight Function
|
|
||||||
* @param {string[] | string} preflight
|
|
||||||
* @param {boolean} [postflight]
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
function preflightFn(preflight, postflight) {
|
|
||||||
const tag = postflight ? "Postflight" : "Preflight";
|
|
||||||
console.log(`${tag} Running ...`);
|
|
||||||
const options = {
|
|
||||||
cwd: process.cwd(),
|
|
||||||
stdio: "inherit",
|
|
||||||
};
|
|
||||||
try {
|
|
||||||
if (typeof preflight == "string") {
|
|
||||||
(0, child_process_1.execFileSync)(preflight, options);
|
|
||||||
}
|
|
||||||
else if (typeof preflight == "object" && (preflight === null || preflight === void 0 ? void 0 : preflight[0])) {
|
|
||||||
for (let i = 0; i < preflight.length; i++) {
|
|
||||||
const cmd = preflight[i];
|
|
||||||
try {
|
|
||||||
const execCmd = (0, child_process_1.execSync)(cmd, options);
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
console.log(`${console_colors_1.default.FgRed}Error:${console_colors_1.default.Reset} ${tag} command ${cmd} Failed! => ${error.message}`);
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
console.log(`${console_colors_1.default.FgRed}Error:${console_colors_1.default.Reset} ${tag} Failed! => ${error.message}`);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
7
dist/utils/run.d.ts
vendored
7
dist/utils/run.d.ts
vendored
@ -1,7 +0,0 @@
|
|||||||
import { ChildProcess } from "child_process";
|
|
||||||
/**
|
|
||||||
* ## Preflight Function
|
|
||||||
* @param {string} command
|
|
||||||
* @returns {ChildProcess | null}
|
|
||||||
*/
|
|
||||||
export default function run(command: string): ChildProcess | null;
|
|
37
dist/utils/run.js
vendored
37
dist/utils/run.js
vendored
@ -1,37 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.default = run;
|
|
||||||
const child_process_1 = require("child_process");
|
|
||||||
const console_colors_1 = __importDefault(require("./console-colors"));
|
|
||||||
let redeployments = 0;
|
|
||||||
const KILL_SIGNAL = "SIGTERM";
|
|
||||||
/**
|
|
||||||
* ## Preflight Function
|
|
||||||
* @param {string} command
|
|
||||||
* @returns {ChildProcess | null}
|
|
||||||
*/
|
|
||||||
function run(command) {
|
|
||||||
console.log("\n******************************");
|
|
||||||
console.log(`****** ${console_colors_1.default.FgGreen}Starting App ...${console_colors_1.default.Reset} ******`);
|
|
||||||
console.log("******************************\n");
|
|
||||||
const startCommandArray = command.split(" ").filter((str) => str.trim());
|
|
||||||
try {
|
|
||||||
const firstCommand = startCommandArray.shift();
|
|
||||||
if (!firstCommand) {
|
|
||||||
throw new Error("No Starting Command Found in command string!");
|
|
||||||
}
|
|
||||||
let childProcess = (0, child_process_1.spawn)(firstCommand, startCommandArray, {
|
|
||||||
stdio: "inherit",
|
|
||||||
killSignal: KILL_SIGNAL,
|
|
||||||
});
|
|
||||||
redeployments++;
|
|
||||||
return childProcess;
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
console.log(`${console_colors_1.default.FgRed}Error:${console_colors_1.default.Reset} running start command => ${error.message}`);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
18
dist/utils/start.d.ts
vendored
18
dist/utils/start.d.ts
vendored
@ -1,18 +0,0 @@
|
|||||||
/**
|
|
||||||
* # Start the process
|
|
||||||
* @param {object} param0
|
|
||||||
* @param {string} param0.command
|
|
||||||
* @param {string[] | string} param0.preflight
|
|
||||||
* @param {string[] | string} [param0.postflight]
|
|
||||||
* @param {string} param0.redeploy_file
|
|
||||||
* @param {string | number | (string | number)[]} [param0.port] - The port to kill on rebuild
|
|
||||||
* @param {boolean} [param0.first_run] - Whether to run the preflight on first run. Default `false`
|
|
||||||
*/
|
|
||||||
export default function startProcess({ command, preflight, postflight, redeploy_file, port, first_run, }: {
|
|
||||||
command: string;
|
|
||||||
preflight: string[] | string;
|
|
||||||
postflight?: string[] | string;
|
|
||||||
redeploy_file: string;
|
|
||||||
port?: string | number | (string | number)[];
|
|
||||||
first_run?: boolean;
|
|
||||||
}): void;
|
|
84
dist/utils/start.js
vendored
84
dist/utils/start.js
vendored
@ -1,84 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.default = startProcess;
|
|
||||||
const fs_1 = __importDefault(require("fs"));
|
|
||||||
const console_colors_1 = __importDefault(require("./console-colors"));
|
|
||||||
const preflight_1 = __importDefault(require("./preflight"));
|
|
||||||
const run_1 = __importDefault(require("./run"));
|
|
||||||
const kill_child_1 = __importDefault(require("./kill-child"));
|
|
||||||
let redeployments = 0;
|
|
||||||
let childProcess = null;
|
|
||||||
const pTitle = "nodecid";
|
|
||||||
process.title = pTitle;
|
|
||||||
/**
|
|
||||||
* # Start the process
|
|
||||||
* @param {object} param0
|
|
||||||
* @param {string} param0.command
|
|
||||||
* @param {string[] | string} param0.preflight
|
|
||||||
* @param {string[] | string} [param0.postflight]
|
|
||||||
* @param {string} param0.redeploy_file
|
|
||||||
* @param {string | number | (string | number)[]} [param0.port] - The port to kill on rebuild
|
|
||||||
* @param {boolean} [param0.first_run] - Whether to run the preflight on first run. Default `false`
|
|
||||||
*/
|
|
||||||
function startProcess({ command, preflight, postflight, redeploy_file, port, first_run, }) {
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
childProcess = (0, run_1.default)(command);
|
|
||||||
if (!childProcess) {
|
|
||||||
console.log(`${console_colors_1.default.FgRed}Error:${console_colors_1.default.Reset} Process couldn't start. Exiting...`);
|
|
||||||
process.exit();
|
|
||||||
}
|
|
||||||
console.log("Watching", redeploy_file);
|
|
||||||
fs_1.default.watchFile(redeploy_file, { interval: 100 }, (curr, prev) => {
|
|
||||||
console.log(`${console_colors_1.default.BgBlue}File Changed${console_colors_1.default.Reset}`);
|
|
||||||
if (redeployments == 0)
|
|
||||||
return;
|
|
||||||
if (childProcess) {
|
|
||||||
console.log("******************************");
|
|
||||||
console.log(`******** ${console_colors_1.default.FgBlue}Rebuilding ${console_colors_1.default.FgMagenta}${redeployments}${console_colors_1.default.Reset} ********`);
|
|
||||||
console.log("******************************");
|
|
||||||
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 {
|
|
||||||
(0, kill_child_1.default)(port).then((kill) => {
|
|
||||||
if (kill) {
|
|
||||||
childProcess = (0, run_1.default)(command);
|
|
||||||
if (postflight) {
|
|
||||||
const runPostflight = (0, preflight_1.default)(postflight, true);
|
|
||||||
if (!runPostflight) {
|
|
||||||
// TODO: Action to take if postflight fails
|
|
||||||
console.log(`${console_colors_1.default.FgRed}Error:${console_colors_1.default.Reset} Postflight Failed.`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
process.exit();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
console.log(`${console_colors_1.default.FgRed}Error:${console_colors_1.default.Reset} killing child processes => ${error.message}`);
|
|
||||||
process.exit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
console.log(`${console_colors_1.default.FgRed}Error:${console_colors_1.default.Reset} First run failed! => ${error.message}`);
|
|
||||||
}
|
|
||||||
}
|
|
1
dist/utils/triggers/github.d.ts
vendored
1
dist/utils/triggers/github.d.ts
vendored
@ -1 +0,0 @@
|
|||||||
declare function githubWebhook(): boolean;
|
|
56
index.js
Normal file
56
index.js
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
#! /usr/bin/env node
|
||||||
|
// @ts-check
|
||||||
|
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
const colors = require("./utils/console-colors");
|
||||||
|
const startProcess = require("./deploy/start");
|
||||||
|
|
||||||
|
///////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////
|
||||||
|
|
||||||
|
const WORK_DIR = process.cwd();
|
||||||
|
|
||||||
|
///////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////
|
||||||
|
|
||||||
|
try {
|
||||||
|
const configText = fs.readFileSync(
|
||||||
|
path.join(WORK_DIR, "nodecid.config.json"),
|
||||||
|
"utf-8"
|
||||||
|
);
|
||||||
|
|
||||||
|
/** @type {NodeCIConfig} */
|
||||||
|
const config = JSON.parse(configText);
|
||||||
|
|
||||||
|
const { start, preflight, redeploy_path } = config;
|
||||||
|
|
||||||
|
/** @type {string | undefined} */
|
||||||
|
let redeployFile;
|
||||||
|
|
||||||
|
if (!redeploy_path) {
|
||||||
|
fs.writeFileSync(
|
||||||
|
path.join(WORK_DIR, "REDEPLY"),
|
||||||
|
Date.now().toString(),
|
||||||
|
"utf-8"
|
||||||
|
);
|
||||||
|
|
||||||
|
redeployFile = path.join(WORK_DIR, "REDEPLY");
|
||||||
|
} else {
|
||||||
|
redeployFile = path.resolve(WORK_DIR, redeploy_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!redeployFile) throw new Error("Redeploy file not found!");
|
||||||
|
|
||||||
|
startProcess({
|
||||||
|
command: start,
|
||||||
|
preflight,
|
||||||
|
redeploy_file: redeployFile,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.log(
|
||||||
|
`${colors.FgRed}ERROR:${colors.Reset} CI process failed! => ${error.message}`
|
||||||
|
);
|
||||||
|
}
|
73
index.ts
73
index.ts
@ -1,73 +0,0 @@
|
|||||||
import fs from "fs";
|
|
||||||
import path from "path";
|
|
||||||
import colors from "./utils/console-colors";
|
|
||||||
import startProcess from "./utils/start";
|
|
||||||
import type { NodeCIConfig } from "./types";
|
|
||||||
|
|
||||||
const WORK_DIR = process.cwd();
|
|
||||||
|
|
||||||
function run() {
|
|
||||||
try {
|
|
||||||
const configText = fs.readFileSync(
|
|
||||||
path.join(WORK_DIR, "nodecid.config.json"),
|
|
||||||
"utf-8"
|
|
||||||
);
|
|
||||||
|
|
||||||
const config: NodeCIConfig = JSON.parse(configText);
|
|
||||||
|
|
||||||
const {
|
|
||||||
start,
|
|
||||||
preflight,
|
|
||||||
postflight,
|
|
||||||
build,
|
|
||||||
redeploy_path,
|
|
||||||
first_run,
|
|
||||||
port,
|
|
||||||
} = config;
|
|
||||||
|
|
||||||
/** @type {string | undefined} */
|
|
||||||
let redeployFile;
|
|
||||||
|
|
||||||
if (!redeploy_path) {
|
|
||||||
const defaultRedeployPath = path.join(WORK_DIR, "REDEPLOY");
|
|
||||||
const checkExistingPath = fs.existsSync(defaultRedeployPath);
|
|
||||||
|
|
||||||
if (!checkExistingPath) {
|
|
||||||
fs.writeFileSync(
|
|
||||||
defaultRedeployPath,
|
|
||||||
Date.now().toString(),
|
|
||||||
"utf-8"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
redeployFile = path.join(WORK_DIR, "REDEPLOY");
|
|
||||||
} else {
|
|
||||||
redeployFile = path.resolve(WORK_DIR, redeploy_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!redeployFile) throw new Error("Redeploy file not found!");
|
|
||||||
|
|
||||||
startProcess({
|
|
||||||
command: start,
|
|
||||||
preflight,
|
|
||||||
redeploy_file: redeployFile,
|
|
||||||
first_run,
|
|
||||||
port,
|
|
||||||
postflight,
|
|
||||||
});
|
|
||||||
} catch (error: any) {
|
|
||||||
console.log(
|
|
||||||
`${colors.FgRed}ERROR:${colors.Reset} CI process failed! => ${error.message}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
run();
|
|
||||||
|
|
||||||
process.on("exit", () => {
|
|
||||||
console.log("Process exiting ...");
|
|
||||||
});
|
|
||||||
|
|
||||||
process.on("beforeExit", () => {
|
|
||||||
console.log("Process Before exit ...");
|
|
||||||
});
|
|
@ -1,27 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
// Enable latest features
|
|
||||||
"lib": ["ESNext", "DOM"],
|
|
||||||
"target": "ESNext",
|
|
||||||
"module": "ESNext",
|
|
||||||
"moduleDetection": "force",
|
|
||||||
"jsx": "react-jsx",
|
|
||||||
"allowJs": true,
|
|
||||||
|
|
||||||
// Bundler mode
|
|
||||||
"moduleResolution": "bundler",
|
|
||||||
"allowImportingTsExtensions": true,
|
|
||||||
"verbatimModuleSyntax": true,
|
|
||||||
"noEmit": true,
|
|
||||||
|
|
||||||
// Best practices
|
|
||||||
"strict": true,
|
|
||||||
"skipLibCheck": true,
|
|
||||||
"noFallthroughCasesInSwitch": true,
|
|
||||||
|
|
||||||
// Some stricter flags (disabled by default)
|
|
||||||
"noUnusedLocals": false,
|
|
||||||
"noUnusedParameters": false,
|
|
||||||
"noPropertyAccessFromIndexSignature": false
|
|
||||||
}
|
|
||||||
}
|
|
25
package.json
25
package.json
@ -1,14 +1,11 @@
|
|||||||
{
|
{
|
||||||
"name": "@moduletrace/nodecid",
|
"name": "nodecid",
|
||||||
"version": "1.0.7",
|
"version": "1.0.0",
|
||||||
"description": "Simple CI/CD process",
|
"description": "Simple CI/CD process",
|
||||||
"main": "dist/index.js",
|
"main": "index.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
"nodecid": "./dist/index.js",
|
"nodecid": "./index.js",
|
||||||
"node-ci-cd": "./dist/index.js"
|
"node-ci-cd": "./index.js"
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"compile": "bun build --compile --minify --sourcemap --bytecode index.ts --outfile bin/nodecid"
|
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"CI/CD",
|
"CI/CD",
|
||||||
@ -16,15 +13,5 @@
|
|||||||
"Continous Deployment"
|
"Continous Deployment"
|
||||||
],
|
],
|
||||||
"author": "Benjamin Toby",
|
"author": "Benjamin Toby",
|
||||||
"license": "MIT",
|
"license": "MIT"
|
||||||
"dependencies": {
|
|
||||||
"kill-port": "^2.0.1"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/bun": "latest",
|
|
||||||
"@types/node": "^22.10.7"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"typescript": "^5.0.0"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
14
publish.sh
14
publish.sh
@ -1,14 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
tsc
|
|
||||||
|
|
||||||
if [ -z "$1" ]; then
|
|
||||||
msg="Updates"
|
|
||||||
else
|
|
||||||
msg="$1"
|
|
||||||
fi
|
|
||||||
|
|
||||||
git add .
|
|
||||||
git commit -m "$msg"
|
|
||||||
git push
|
|
||||||
npm publish
|
|
@ -1,21 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"target": "ES2015",
|
|
||||||
"module": "commonjs",
|
|
||||||
"maxNodeModuleJsDepth": 10,
|
|
||||||
"esModuleInterop": true,
|
|
||||||
"forceConsistentCasingInFileNames": true,
|
|
||||||
"strict": true,
|
|
||||||
"skipLibCheck": true,
|
|
||||||
"lib": ["dom", "dom.iterable", "esnext"],
|
|
||||||
"allowJs": true,
|
|
||||||
"incremental": true,
|
|
||||||
"resolveJsonModule": true,
|
|
||||||
"jsx": "preserve",
|
|
||||||
"moduleResolution": "node",
|
|
||||||
"declaration": true,
|
|
||||||
"outDir": "dist"
|
|
||||||
},
|
|
||||||
"include": ["**/*.ts"],
|
|
||||||
"exclude": ["node_modules", "dist"]
|
|
||||||
}
|
|
8
types.d.js
Normal file
8
types.d.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
/**
|
||||||
|
* @typedef {object} NodeCIConfig
|
||||||
|
* @property {string} start - Start command. Eg `node index.js`
|
||||||
|
* @property {string[] | string} preflight - And array of commands to run before
|
||||||
|
* the application starts, or a single `.sh` file path.
|
||||||
|
* @property {string} [redeploy_path] - The path to the file that will trigger a
|
||||||
|
* redeployment if content is changed. Default file path is `./REDEPLOY`
|
||||||
|
*/
|
14
types.ts
14
types.ts
@ -1,14 +0,0 @@
|
|||||||
export interface NodeCIConfig {
|
|
||||||
start: string;
|
|
||||||
preflight: string[] | string;
|
|
||||||
postflight?: string[] | string;
|
|
||||||
redeploy_path?: string;
|
|
||||||
first_run?: boolean;
|
|
||||||
port?: string | number | (string | number)[];
|
|
||||||
build?: NodeCIBuild;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface NodeCIBuild {
|
|
||||||
paradigm: "Next.JS" | "Remix";
|
|
||||||
out_dir?: string;
|
|
||||||
}
|
|
61
dist/utils/console-colors.js → utils/console-colors.js
Normal file → Executable file
61
dist/utils/console-colors.js → utils/console-colors.js
Normal file → Executable file
@ -1,30 +1,31 @@
|
|||||||
"use strict";
|
const colors = {
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Reset: "\x1b[0m",
|
||||||
const colors = {
|
Bright: "\x1b[1m",
|
||||||
Reset: "\x1b[0m",
|
Dim: "\x1b[2m",
|
||||||
Bright: "\x1b[1m",
|
Underscore: "\x1b[4m",
|
||||||
Dim: "\x1b[2m",
|
Blink: "\x1b[5m",
|
||||||
Underscore: "\x1b[4m",
|
Reverse: "\x1b[7m",
|
||||||
Blink: "\x1b[5m",
|
Hidden: "\x1b[8m",
|
||||||
Reverse: "\x1b[7m",
|
|
||||||
Hidden: "\x1b[8m",
|
FgBlack: "\x1b[30m",
|
||||||
FgBlack: "\x1b[30m",
|
FgRed: "\x1b[31m",
|
||||||
FgRed: "\x1b[31m",
|
FgGreen: "\x1b[32m",
|
||||||
FgGreen: "\x1b[32m",
|
FgYellow: "\x1b[33m",
|
||||||
FgYellow: "\x1b[33m",
|
FgBlue: "\x1b[34m",
|
||||||
FgBlue: "\x1b[34m",
|
FgMagenta: "\x1b[35m",
|
||||||
FgMagenta: "\x1b[35m",
|
FgCyan: "\x1b[36m",
|
||||||
FgCyan: "\x1b[36m",
|
FgWhite: "\x1b[37m",
|
||||||
FgWhite: "\x1b[37m",
|
FgGray: "\x1b[90m",
|
||||||
FgGray: "\x1b[90m",
|
|
||||||
BgBlack: "\x1b[40m",
|
BgBlack: "\x1b[40m",
|
||||||
BgRed: "\x1b[41m",
|
BgRed: "\x1b[41m",
|
||||||
BgGreen: "\x1b[42m",
|
BgGreen: "\x1b[42m",
|
||||||
BgYellow: "\x1b[43m",
|
BgYellow: "\x1b[43m",
|
||||||
BgBlue: "\x1b[44m",
|
BgBlue: "\x1b[44m",
|
||||||
BgMagenta: "\x1b[45m",
|
BgMagenta: "\x1b[45m",
|
||||||
BgCyan: "\x1b[46m",
|
BgCyan: "\x1b[46m",
|
||||||
BgWhite: "\x1b[47m",
|
BgWhite: "\x1b[47m",
|
||||||
BgGray: "\x1b[100m",
|
BgGray: "\x1b[100m",
|
||||||
};
|
};
|
||||||
exports.default = colors;
|
|
||||||
|
module.exports = colors;
|
@ -1,31 +0,0 @@
|
|||||||
const colors = {
|
|
||||||
Reset: "\x1b[0m",
|
|
||||||
Bright: "\x1b[1m",
|
|
||||||
Dim: "\x1b[2m",
|
|
||||||
Underscore: "\x1b[4m",
|
|
||||||
Blink: "\x1b[5m",
|
|
||||||
Reverse: "\x1b[7m",
|
|
||||||
Hidden: "\x1b[8m",
|
|
||||||
|
|
||||||
FgBlack: "\x1b[30m",
|
|
||||||
FgRed: "\x1b[31m",
|
|
||||||
FgGreen: "\x1b[32m",
|
|
||||||
FgYellow: "\x1b[33m",
|
|
||||||
FgBlue: "\x1b[34m",
|
|
||||||
FgMagenta: "\x1b[35m",
|
|
||||||
FgCyan: "\x1b[36m",
|
|
||||||
FgWhite: "\x1b[37m",
|
|
||||||
FgGray: "\x1b[90m",
|
|
||||||
|
|
||||||
BgBlack: "\x1b[40m",
|
|
||||||
BgRed: "\x1b[41m",
|
|
||||||
BgGreen: "\x1b[42m",
|
|
||||||
BgYellow: "\x1b[43m",
|
|
||||||
BgBlue: "\x1b[44m",
|
|
||||||
BgMagenta: "\x1b[45m",
|
|
||||||
BgCyan: "\x1b[46m",
|
|
||||||
BgWhite: "\x1b[47m",
|
|
||||||
BgGray: "\x1b[100m",
|
|
||||||
};
|
|
||||||
|
|
||||||
export default colors;
|
|
@ -1,37 +0,0 @@
|
|||||||
import { ChildProcess } from "child_process";
|
|
||||||
import colors from "./console-colors";
|
|
||||||
import kill from "kill-port";
|
|
||||||
|
|
||||||
let childProcess: ChildProcess | null = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ## Kill Child Process Function
|
|
||||||
* @param {string | number | (string | number)[]} [port]
|
|
||||||
* @returns {Promise<boolean>}
|
|
||||||
*/
|
|
||||||
export default async function killChild(
|
|
||||||
port?: string | number | (string | number)[]
|
|
||||||
): Promise<boolean> {
|
|
||||||
if (!childProcess) return false;
|
|
||||||
|
|
||||||
try {
|
|
||||||
const childProcessPID = childProcess.pid;
|
|
||||||
childProcess.kill();
|
|
||||||
|
|
||||||
if (typeof port == "object" && port?.[0]) {
|
|
||||||
for (let i = 0; i < port.length; i++) {
|
|
||||||
const singlePort = port[i];
|
|
||||||
await kill(Number(singlePort));
|
|
||||||
}
|
|
||||||
} else if (port) {
|
|
||||||
await kill(Number(port));
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} catch (error: any) {
|
|
||||||
console.log(
|
|
||||||
`${colors.FgRed}Error:${colors.Reset} Child Process couldn't be killed! ${error.message}`
|
|
||||||
);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
import { execSync, execFileSync, type ExecSyncOptions } from "child_process";
|
|
||||||
import colors from "../utils/console-colors";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ## Preflight Function
|
|
||||||
* @param {string[] | string} preflight
|
|
||||||
* @param {boolean} [postflight]
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
export default function preflightFn(
|
|
||||||
preflight?: string[] | string,
|
|
||||||
postflight?: boolean
|
|
||||||
): boolean {
|
|
||||||
const tag = postflight ? "Postflight" : "Preflight";
|
|
||||||
console.log(`${tag} Running ...`);
|
|
||||||
|
|
||||||
const options: ExecSyncOptions = {
|
|
||||||
cwd: process.cwd(),
|
|
||||||
stdio: "inherit",
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (typeof preflight == "string") {
|
|
||||||
execFileSync(preflight, options);
|
|
||||||
} else if (typeof preflight == "object" && preflight?.[0]) {
|
|
||||||
for (let i = 0; i < preflight.length; i++) {
|
|
||||||
const cmd = preflight[i];
|
|
||||||
try {
|
|
||||||
const execCmd = execSync(cmd, options);
|
|
||||||
} catch (error: any) {
|
|
||||||
console.log(
|
|
||||||
`${colors.FgRed}Error:${colors.Reset} ${tag} command ${cmd} Failed! => ${error.message}`
|
|
||||||
);
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
} catch (error: any) {
|
|
||||||
console.log(
|
|
||||||
`${colors.FgRed}Error:${colors.Reset} ${tag} Failed! => ${error.message}`
|
|
||||||
);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
43
utils/run.ts
43
utils/run.ts
@ -1,43 +0,0 @@
|
|||||||
import { spawn, ChildProcess } from "child_process";
|
|
||||||
import colors from "./console-colors";
|
|
||||||
|
|
||||||
let redeployments = 0;
|
|
||||||
|
|
||||||
const KILL_SIGNAL: NodeJS.Signals | number = "SIGTERM";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ## Preflight Function
|
|
||||||
* @param {string} command
|
|
||||||
* @returns {ChildProcess | null}
|
|
||||||
*/
|
|
||||||
export default function run(command: string): ChildProcess | null {
|
|
||||||
console.log("\n******************************");
|
|
||||||
console.log(
|
|
||||||
`****** ${colors.FgGreen}Starting App ...${colors.Reset} ******`
|
|
||||||
);
|
|
||||||
console.log("******************************\n");
|
|
||||||
|
|
||||||
const startCommandArray = command.split(" ").filter((str) => str.trim());
|
|
||||||
|
|
||||||
try {
|
|
||||||
const firstCommand = startCommandArray.shift();
|
|
||||||
|
|
||||||
if (!firstCommand) {
|
|
||||||
throw new Error("No Starting Command Found in command string!");
|
|
||||||
}
|
|
||||||
|
|
||||||
let childProcess = spawn(firstCommand, startCommandArray, {
|
|
||||||
stdio: "inherit",
|
|
||||||
killSignal: KILL_SIGNAL,
|
|
||||||
});
|
|
||||||
|
|
||||||
redeployments++;
|
|
||||||
|
|
||||||
return childProcess;
|
|
||||||
} catch (error: any) {
|
|
||||||
console.log(
|
|
||||||
`${colors.FgRed}Error:${colors.Reset} running start command => ${error.message}`
|
|
||||||
);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
123
utils/start.ts
123
utils/start.ts
@ -1,123 +0,0 @@
|
|||||||
import fs from "fs";
|
|
||||||
import { ChildProcess } from "child_process";
|
|
||||||
import colors from "./console-colors";
|
|
||||||
import kill from "kill-port";
|
|
||||||
import preflightFn from "./preflight";
|
|
||||||
import run from "./run";
|
|
||||||
import killChild from "./kill-child";
|
|
||||||
|
|
||||||
let redeployments = 0;
|
|
||||||
|
|
||||||
let childProcess: ChildProcess | null = null;
|
|
||||||
|
|
||||||
const pTitle = "nodecid";
|
|
||||||
process.title = pTitle;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* # Start the process
|
|
||||||
* @param {object} param0
|
|
||||||
* @param {string} param0.command
|
|
||||||
* @param {string[] | string} param0.preflight
|
|
||||||
* @param {string[] | string} [param0.postflight]
|
|
||||||
* @param {string} param0.redeploy_file
|
|
||||||
* @param {string | number | (string | number)[]} [param0.port] - The port to kill on rebuild
|
|
||||||
* @param {boolean} [param0.first_run] - Whether to run the preflight on first run. Default `false`
|
|
||||||
*/
|
|
||||||
export default function startProcess({
|
|
||||||
command,
|
|
||||||
preflight,
|
|
||||||
postflight,
|
|
||||||
redeploy_file,
|
|
||||||
port,
|
|
||||||
first_run,
|
|
||||||
}: {
|
|
||||||
command: string;
|
|
||||||
preflight: string[] | string;
|
|
||||||
postflight?: string[] | string;
|
|
||||||
redeploy_file: string;
|
|
||||||
port?: string | number | (string | number)[];
|
|
||||||
first_run?: boolean;
|
|
||||||
}) {
|
|
||||||
try {
|
|
||||||
if (first_run) {
|
|
||||||
console.log("First Run ...");
|
|
||||||
const runPreflight = preflightFn(preflight);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!preflight) {
|
|
||||||
console.log(
|
|
||||||
`${colors.FgRed}Error:${colors.Reset} No preflight included in config file. If you don't want to run any preflight command simply add an empty array.`
|
|
||||||
);
|
|
||||||
process.exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
childProcess = run(command);
|
|
||||||
|
|
||||||
if (!childProcess) {
|
|
||||||
console.log(
|
|
||||||
`${colors.FgRed}Error:${colors.Reset} Process couldn't start. Exiting...`
|
|
||||||
);
|
|
||||||
process.exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("Watching", redeploy_file);
|
|
||||||
|
|
||||||
fs.watchFile(redeploy_file, { interval: 100 }, (curr, prev) => {
|
|
||||||
console.log(`${colors.BgBlue}File Changed${colors.Reset}`);
|
|
||||||
|
|
||||||
if (redeployments == 0) return;
|
|
||||||
|
|
||||||
if (childProcess) {
|
|
||||||
console.log("******************************");
|
|
||||||
console.log(
|
|
||||||
`******** ${colors.FgBlue}Rebuilding ${colors.FgMagenta}${redeployments}${colors.Reset} ********`
|
|
||||||
);
|
|
||||||
console.log("******************************");
|
|
||||||
|
|
||||||
try {
|
|
||||||
const runPreflight = preflightFn(preflight);
|
|
||||||
|
|
||||||
if (!runPreflight) {
|
|
||||||
// TODO: Action to take if preflight fails
|
|
||||||
|
|
||||||
console.log(
|
|
||||||
`${colors.FgRed}Error:${colors.Reset} Preflight Failed.`
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
killChild(port).then((kill) => {
|
|
||||||
if (kill) {
|
|
||||||
childProcess = run(command);
|
|
||||||
|
|
||||||
if (postflight) {
|
|
||||||
const runPostflight = preflightFn(
|
|
||||||
postflight,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!runPostflight) {
|
|
||||||
// TODO: Action to take if postflight fails
|
|
||||||
|
|
||||||
console.log(
|
|
||||||
`${colors.FgRed}Error:${colors.Reset} Postflight Failed.`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
process.exit();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch (error: any) {
|
|
||||||
console.log(
|
|
||||||
`${colors.FgRed}Error:${colors.Reset} killing child processes => ${error.message}`
|
|
||||||
);
|
|
||||||
process.exit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (error: any) {
|
|
||||||
console.log(
|
|
||||||
`${colors.FgRed}Error:${colors.Reset} First run failed! => ${error.message}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +1,3 @@
|
|||||||
"use strict";
|
|
||||||
function githubWebhook() {
|
function githubWebhook() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user