UNPKG

simple-serverless-uploader

Version:
230 lines (208 loc) 8.54 kB
#!/usr/bin/env node "use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); // src/index.ts var import_commander = require("commander"); // src/config/appVersion.ts var APP_VERSION = "0.0.1"; // src/constants/DeploymentType.ts var DeploymentTypes = { S3_WEBSITE: "s3-website", LAMBDA_SERVER: "lambda-server" }; // src/utils/shellExec.ts var import_shelljs = __toESM(require("shelljs")); // src/utils/log/colorToLog.ts function colorToLog(color, log) { const colors = { red: "\x1B[31m", green: "\x1B[32m", blue: "\x1B[34m" }; const reset = "\x1B[0m"; return `${colors[color]}${log}${reset}`; } // src/utils/log/logRun.ts function logRun(message) { console.log(colorToLog("blue", `\u276F ${message}`)); } // src/utils/shellExec.ts function shellExec(command, options = {}) { logRun(command); const result = import_shelljs.default.exec(command, options); if (result.code !== 0) throw Error(`shellExec(${command}) failed to run`); return result; } // src/git/utils/currentGitBranchIs.ts function currentGitBranchIs(value) { const result = shellExec("git rev-parse --abbrev-ref HEAD"); return new RegExp(`^${value}$`, "m").test(result.stdout); } // src/utils/string/isString.ts var isString = (value) => typeof value === "string"; // src/utils/string/isBlankString.ts function isBlankString(value) { if (!value) { return true; } if (!isString(value)) { return false; } return value.trim() === ""; } // src/git/utils/thereAreFilesToCommit.ts function thereAreFilesToCommit() { const result = shellExec("git status -s"); return !isBlankString(result.stdout); } // src/git/utils/thereAreRemoteChanges.ts function thereAreRemoteChanges() { const result = shellExec("git status -uno"); return !new RegExp("^Your branch is up to date with ", "m").test(result.stdout); } // src/utils/exit.ts function exit() { process.exit(1); } // src/utils/log/logError.ts function logError(message) { console.log(colorToLog("red", `\u274C\uFE0F ${message}`)); } // src/utils/log/logErrorAndExit.ts function logErrorAndExit(message) { logError(message); exit(); } // src/git/verifyGitConditions.ts async function verifyGitConditions({ mainBranch, isProduction, productionStageName }) { if (isProduction && !currentGitBranchIs(mainBranch)) { logErrorAndExit(`You can only release to ${productionStageName} from the main branch!`); } if (thereAreFilesToCommit()) logErrorAndExit("There are uncommitted files, commit files before running script!"); if (thereAreFilesToCommit()) logErrorAndExit("There are uncommitted files, commit files before running script!"); if (thereAreRemoteChanges()) logErrorAndExit("There are remote changes not pulled or local changes not pushed, make sure to git pull changes before running script!"); } // src/utils/confirm/confirmProdStage.ts var import_readline_sync = __toESM(require("readline-sync")); function confirmProdStage(projectName, prodStageName) { const answer = import_readline_sync.default.question(colorToLog("red", ` WARNING you are running a script in the production environment. Type ${prodStageName} to continue `)); if (answer === prodStageName) return; console.log(colorToLog("red", `Exiting without releasing ${projectName}!`)); process.exit(1); } // src/utils/tagWithDate.ts var import_moment_timezone = __toESM(require("moment-timezone")); function tagWithDate(tag) { const dateTime = import_moment_timezone.default.tz("America/Monterrey").format("YYYY-MM-DD_HH.mm"); return `${tag}-${dateTime}`; } // src/deployProject.ts async function deployProject(request) { var _a, _b, _c, _d, _e, _f, _g; try { console.log(`Starting deploy for project ${request.projectName} \u{1F680}`); console.log(`Selected stage: ${request.stage}`); if (!request.availableStages.includes(request.stage)) { console.log(colorToLog("red", `\u274C\uFE0F Exiting without releasing ${request.projectName} since passed stage "${request.stage}" is not supported!`)); process.exit(1); } const productionStage = ((_a = request.options) == null ? void 0 : _a.productionStage) || "prod"; const isProductionStage = request.stage === productionStage; const isGitImplementationEnabled = (_b = request.options) == null ? void 0 : _b.gitImplementationEnabled; const mainBranchName = ((_c = request.options) == null ? void 0 : _c.mainGitBranch) || "main"; if (isProductionStage && !((_d = request.options) == null ? void 0 : _d.confirmSkipped)) confirmProdStage(request.projectName, productionStage); console.time(colorToLog("blue", "Runtime")); if (isGitImplementationEnabled && !((_e = request.options) == null ? void 0 : _e.isForced)) { verifyGitConditions({ mainBranch: mainBranchName, isProduction: isProductionStage, productionStageName: productionStage }); } shellExec("yarn"); if (!((_f = request.options) == null ? void 0 : _f.isForced)) shellExec("yarn lint"); if (!((_g = request.options) == null ? void 0 : _g.isForced)) shellExec("yarn typescript"); shellExec(`npx sls deploy --stage ${request.stage} --param="online" --aws-profile softii`); const tagName = tagWithDate(request.stage); try { shellExec(`git tag -f ${tagName}`); shellExec(`git push origin ${tagName}`); } catch (e) { console.log("Tag no seted"); } console.timeEnd(colorToLog("blue", "Runtime")); } catch (e) { console.log(colorToLog("red", `\u274C\uFE0F Something went wrong ${e}`)); console.timeEnd(colorToLog("blue", "RunTime")); process.exit(1); } } // src/utils/loadSSUConfig.ts var import_fs = __toESM(require("fs")); var import_path = __toESM(require("path")); var defaultConfig = { projectName: "My Project ", stages: ["prod", "dev"], serverlessFile: "./serverless.yml" }; async function loadUserConfig() { const filenames = ["ssu.config.js", "ssu.config.cjs"]; for (const filename of filenames) { const fullPath = import_path.default.resolve(process.cwd(), filename); if (import_fs.default.existsSync(fullPath)) { try { const configModule = await import(fullPath); return configModule.default || configModule; } catch (error) { console.error(`\u274C Error loading config file ${filename}:`, error); return defaultConfig; } } } console.warn("\u26A0\uFE0F No config file found. Using defaults."); return defaultConfig; } // src/index.ts async function main() { const program = new import_commander.Command(); const userConfig = await loadUserConfig(); program.name("ssu").description("Simple Serverless Upload CLI").version(APP_VERSION); program.command("deploy <type>").description(`Deploy to AWS (${DeploymentTypes.S3_WEBSITE} or ${DeploymentTypes.LAMBDA_SERVER})`).option("--stage <stage>", `Deployment stage [${userConfig.stages.join(",")}]`).action(async (type, { stage, skipConfirm, sc, force, f }) => { await deployProject({ type, stage, availableStages: userConfig.stages, projectName: userConfig.projectName, options: { confirmSkipped: skipConfirm || sc, productionStage: userConfig.productionStage, gitImplementationEnabled: userConfig.gitImplementationEnabled, mainGitBranch: userConfig.mainGitBranch, isForced: force || f } }); }); program.parse(process.argv); } main(); //# sourceMappingURL=index.js.map