UNPKG

backport

Version:

A CLI tool that automates the process of backporting commits

168 lines 6.95 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.backportRun = void 0; const chalk_1 = __importDefault(require("chalk")); const elastic_apm_node_1 = __importDefault(require("elastic-apm-node")); const BackportError_1 = require("./lib/BackportError"); const apm_1 = require("./lib/apm"); const env_1 = require("./lib/env"); const getCommits_1 = require("./lib/getCommits"); const getTargetBranches_1 = require("./lib/getTargetBranches"); const createStatusComment_1 = require("./lib/github/v3/createStatusComment"); const graphqlClient_1 = require("./lib/github/v4/client/graphqlClient"); const logger_1 = require("./lib/logger"); const ora_1 = require("./lib/ora"); const registerHandlebarsHelpers_1 = require("./lib/registerHandlebarsHelpers"); const runSequentially_1 = require("./lib/runSequentially"); const setupRepo_1 = require("./lib/setupRepo"); const cliArgs_1 = require("./options/cliArgs"); const options_1 = require("./options/options"); (0, registerHandlebarsHelpers_1.registerHandlebarsHelpers)(); let _apmTransaction; async function backportRun({ processArgs, optionsFromModule = {}, exitCodeOnFailure, apmTransaction, }) { _apmTransaction = apmTransaction; const { interactive, logFilePath } = (0, cliArgs_1.getRuntimeArguments)(processArgs, optionsFromModule); const logger = (0, logger_1.initLogger)({ interactive, logFilePath }); let optionsFromCliArgs; try { optionsFromCliArgs = (0, cliArgs_1.getOptionsFromCliArgs)(processArgs); } catch (e) { elastic_apm_node_1.default.captureError(e); if (e instanceof Error) { (0, logger_1.consoleLog)(e.message); (0, logger_1.consoleLog)(`Run "backport --help" to see all options`); return { status: 'failure', error: e, errorMessage: e.message, commits: [], }; } throw e; } let options = null; let commits = []; const spinner = (0, ora_1.ora)(interactive).start('Initializing...'); try { options = await (0, options_1.getOptions)({ optionsFromCliArgs, optionsFromModule }); if (!options.telemetry) { (0, apm_1.disableApm)(); } apmTransaction?.setLabel('cli_options', JSON.stringify(optionsFromCliArgs)); Object.entries(options).forEach(([key, value]) => { apmTransaction?.setLabel(`option__${key}`, JSON.stringify(value)); }); logger.info('Backporting options', options); spinner.stop(); (0, logger_1.consoleLog)((0, options_1.getActiveOptionsFormatted)(options)); const commitsSpan = elastic_apm_node_1.default.startSpan(`Get commits`); commits = await (0, getCommits_1.getCommits)(options); commitsSpan?.setLabel('commit_count', commits.length); commitsSpan?.end(); logger.info('Commits', commits); if (options.ls) { return { status: 'success', commits, results: [] }; } const targetBranchesSpan = elastic_apm_node_1.default.startSpan('Get target branches'); const targetBranches = await (0, getTargetBranches_1.getTargetBranches)(options, commits); targetBranchesSpan?.setLabel('target-branches-count', targetBranches.length); targetBranchesSpan?.end(); logger.info('Target branches', targetBranches); const setupRepoSpan = elastic_apm_node_1.default.startSpan('Setup repository'); await (0, setupRepo_1.setupRepo)(options); setupRepoSpan?.end(); const backportCommitsSpan = elastic_apm_node_1.default.startSpan('Backport commits'); const results = await (0, runSequentially_1.runSequentially)({ options, commits, targetBranches, }); logger.info('Results', results); backportCommitsSpan?.end(); const backportResponse = { status: 'success', commits, results, }; await (0, createStatusComment_1.createStatusComment)({ options, backportResponse }); return backportResponse; } catch (e) { spinner.stop(); let backportResponse; if (e instanceof BackportError_1.BackportError && e.errorContext.code === 'no-branches-exception') { backportResponse = { status: 'aborted', commits, error: e, errorMessage: e.message, }; // this will catch both BackportError and Error } else if (e instanceof Error) { backportResponse = { status: 'failure', commits, error: e, errorMessage: e.message, }; } else { throw e; } if (options) { await (0, createStatusComment_1.createStatusComment)({ options, backportResponse }); } outputError({ e, logFilePath }); // only change exit code for failures while in cli mode if (exitCodeOnFailure && backportResponse.status === 'failure') { process.exitCode = 1; } logger.error('Unhandled exception:', e); return backportResponse; } } exports.backportRun = backportRun; function outputError({ e, logFilePath, }) { if (e instanceof BackportError_1.BackportError || e instanceof graphqlClient_1.GithubV4Exception) { (0, logger_1.consoleLog)(e.message); return; } if (e instanceof Error) { // output (0, logger_1.consoleLog)('\n'); (0, logger_1.consoleLog)(chalk_1.default.bold('⚠️ Ouch! An unhandled error occured 😿')); (0, logger_1.consoleLog)(e.stack ? e.stack : e.message); (0, logger_1.consoleLog)('Please open an issue in https://github.com/sorenlouv/backport/issues or contact me directly on https://twitter.com/sorenlouv'); const infoLogPath = (0, env_1.getLogfilePath)({ logFilePath, logLevel: 'info' }); (0, logger_1.consoleLog)(chalk_1.default.italic(`For additional details see the logs: ${infoLogPath}`)); } } let didFlush = false; process.on('exit', () => { if (!didFlush) { didFlush = true; _apmTransaction?.end('exit'); elastic_apm_node_1.default.flush(() => process.exit()); } }); process.on('uncaughtException', () => { if (!didFlush) { didFlush = true; _apmTransaction?.end('exit'); elastic_apm_node_1.default.flush(() => process.exit()); } }); process.on('SIGINT', () => { if (!didFlush) { didFlush = true; _apmTransaction?.end('SIGINT'); elastic_apm_node_1.default.flush(() => process.exit()); } }); //# sourceMappingURL=backportRun.js.map