backport
Version:
A CLI tool that automates the process of backporting commits
198 lines • 7.58 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getActiveOptionsFormatted = exports.getOptions = exports.defaultConfigOptions = void 0;
const chalk_1 = __importDefault(require("chalk"));
const lodash_1 = require("lodash");
const BackportError_1 = require("../lib/BackportError");
const env_1 = require("../lib/env");
const getOptionsFromGithub_1 = require("../lib/github/v4/getOptionsFromGithub/getOptionsFromGithub");
const getRepoOwnerAndNameFromGitRemotes_1 = require("../lib/github/v4/getRepoOwnerAndNameFromGitRemotes");
const logger_1 = require("../lib/logger");
const config_1 = require("./config/config");
const PROJECT_CONFIG_DOCS_LINK = 'https://github.com/sorenlouv/backport/blob/main/docs/config-file-options.md#project-config-backportrcjson';
const GLOBAL_CONFIG_DOCS_LINK = 'https://github.com/sorenlouv/backport/blob/main/docs/config-file-options.md#global-config-backportconfigjson';
exports.defaultConfigOptions = {
assignees: [],
autoAssign: false,
autoMerge: false,
autoMergeMethod: 'merge',
backportBinary: 'backport',
cherrypickRef: true,
commitConflicts: false,
commitPaths: [],
copySourcePRLabels: false,
copySourcePRReviewers: false,
cwd: process.cwd(),
dateSince: null,
dateUntil: null,
details: false,
draft: false,
fork: true,
gitHostname: 'github.com',
interactive: true,
maxNumber: 10,
multipleBranches: true,
multipleCommits: false,
noVerify: true,
publishStatusCommentOnAbort: false,
publishStatusCommentOnFailure: false,
publishStatusCommentOnSuccess: true,
resetAuthor: false,
reviewers: [],
signoff: false,
sourcePRLabels: [],
noUnmergedBackportsHelp: false,
targetBranchChoices: [],
targetBranches: [],
targetPRLabels: [],
telemetry: true,
};
async function getOptions({ optionsFromCliArgs, optionsFromModule, }) {
const optionsFromConfigFiles = await (0, config_1.getOptionsFromConfigFiles)({
optionsFromCliArgs,
optionsFromModule,
});
// combined options from cli and config files
const combined = getMergedOptionsFromConfigAndCli({
optionsFromConfigFiles,
optionsFromCliArgs,
});
const { accessToken, repoName, repoOwner } = await getRequiredOptions(combined);
// update logger
(0, logger_1.setAccessToken)(accessToken);
const optionsFromGithub = await (0, getOptionsFromGithub_1.getOptionsFromGithub)({
...combined,
// required options
accessToken,
repoName,
repoOwner,
});
const options = {
// default author to filter commits by
author: optionsFromGithub.authenticatedUsername,
// default fork owner
repoForkOwner: optionsFromGithub.authenticatedUsername,
// default values have lowest precedence
...exports.defaultConfigOptions,
// local config options override default options
...optionsFromConfigFiles,
// remote config options override local config options
...optionsFromGithub,
// cli args override the above
...optionsFromCliArgs,
editor: optionsFromCliArgs.editor === 'false' ? undefined : combined.editor,
// required properties
accessToken,
repoName,
repoOwner,
};
throwForRequiredOptions(options);
return options;
}
exports.getOptions = getOptions;
async function getRequiredOptions(combined) {
const { accessToken, repoName, repoOwner, globalConfigFile } = combined;
if (accessToken && repoName && repoOwner) {
return { accessToken, repoName, repoOwner };
}
// require access token
if (!accessToken) {
const globalConfigPath = (0, env_1.getGlobalConfigPath)(globalConfigFile);
throw new BackportError_1.BackportError(`Please update your config file: "${globalConfigPath}".\nIt must contain a valid "accessToken".\n\nRead more: ${GLOBAL_CONFIG_DOCS_LINK}`);
}
// attempt to retrieve repo-owner and repo-name from git remote
const gitRemote = await (0, getRepoOwnerAndNameFromGitRemotes_1.getRepoOwnerAndNameFromGitRemotes)({
cwd: combined.cwd,
githubApiBaseUrlV4: combined.githubApiBaseUrlV4,
accessToken,
});
if (!gitRemote.repoName || !gitRemote.repoOwner) {
throw new BackportError_1.BackportError(`Please specify a repository: "--repo elastic/kibana".\n\nRead more: ${PROJECT_CONFIG_DOCS_LINK}`);
}
return {
accessToken,
repoName: gitRemote.repoName,
repoOwner: gitRemote.repoOwner,
};
}
function throwForRequiredOptions(options) {
// ensure `targetBranches` or `targetBranchChoices` are given
if ((0, lodash_1.isEmpty)(options.targetBranches) &&
(0, lodash_1.isEmpty)(options.targetBranchChoices) &&
// this is primarily necessary on CI where `targetBranches` and `targetBranchChoices` and not given
(0, lodash_1.isEmpty)(options.branchLabelMapping)) {
throw new BackportError_1.BackportError(`Please specify a target branch: "--branch 6.1".\n\nRead more: ${PROJECT_CONFIG_DOCS_LINK}`);
}
const optionKeys = [
'accessToken',
'author',
'autoMergeMethod',
'backportBinary',
'backportBranchName',
'dir',
'editor',
'gitHostname',
'githubApiBaseUrlV3',
'githubApiBaseUrlV4',
'logFilePath',
'prDescription',
'projectConfigFile',
'prTitle',
'repoForkOwner',
'repoName',
'repoOwner',
'sha',
'sourceBranch',
];
// Disallow empty strings
// this is primarily an issue in Github actions where inputs default to empty strings instead of undefined
// in those cases failing early provides a better UX
optionKeys.forEach((optionName) => {
const option = options[optionName];
if (option === '') {
throw new BackportError_1.BackportError(`"${optionName}" cannot be empty!`);
}
});
}
function getMergedOptionsFromConfigAndCli({ optionsFromConfigFiles, optionsFromCliArgs, }) {
return {
...exports.defaultConfigOptions,
...optionsFromConfigFiles,
...optionsFromCliArgs,
};
}
function getActiveOptionsFormatted(options) {
const customOptions = [
['repo', `${options.repoOwner}/${options.repoName}`],
['sourceBranch', `${options.sourceBranch}`],
];
if (options.pullNumber) {
customOptions.push(['pullNumber', `${options.pullNumber}`]);
}
if (options.sha) {
customOptions.push(['sha', `${options.sha}`]);
}
if (options.author) {
customOptions.push(['author', `${options.author}`]);
}
if (options.autoMerge === true) {
customOptions.push(['autoMerge', `${options.autoMerge}`]);
}
if (options.maxNumber !== exports.defaultConfigOptions.maxNumber) {
customOptions.push(['maxNumber', `${options.maxNumber}`]);
}
if (options.dateSince) {
customOptions.push(['since', `${options.dateSince}`]);
}
if (options.dateUntil) {
customOptions.push(['until', `${options.dateUntil}`]);
}
return (customOptions
.map(([key, value]) => `${key}: ${chalk_1.default.bold(value)}`)
.join(' 🔹 ') + `\n`);
}
exports.getActiveOptionsFormatted = getActiveOptionsFormatted;
//# sourceMappingURL=options.js.map