@golemio/cli
Version:
Collection of executables intended for use with Golemio services and modules
305 lines • 16.6 kB
JavaScript
;
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 open_1 = __importDefault(require("open"));
const path_1 = __importDefault(require("path"));
const release_utils_1 = require("../utils/release.utils");
const TMP_DIR = path_1.default.resolve(process.cwd(), "tmp");
const command = {
description: "Prepare new release",
alias: "rls",
run: async ({ parameters, print, prompt }) => {
var _a;
const [action] = parameters.array;
const { skip, only, interactive, scope } = parameters.options;
if (!process.env.GITLAB_API_TOKEN) {
print.error("Environmental variable GITLAB_API_TOKEN is not defined");
process.exitCode = 1;
return;
}
if (skip && only) {
print.warning("Option --skip was skipped. Only one of --only or --skip can be used.");
}
if ((!scope || !Object.values(release_utils_1.ReleaseScopeEnum).includes(scope)) &&
["check", "merge", "check-mr-pipelines", "sync-branches", "create-tags"].includes(action)) {
print.error(`Option --scope is not defined or does not match ${Object.values(release_utils_1.ReleaseScopeEnum).join(", ")}`);
process.exitCode = 1;
return;
}
let repos = [];
let releaseCandidates = [];
let released = [];
const releaseBranchName = process.env.RELEASE_BRANCH_NAME || "release";
const targetBranchName = process.env.TARGET_BRANCH_NAME || "master";
switch (action) {
case "help":
case "h":
default:
(0, release_utils_1.printCommandHelp)();
break;
case "check-modules-integrity":
const missing = await (0, release_utils_1.checkModulesIntegrity)();
if (missing.length > 0) {
for (const miss of missing) {
print.warning(`Repository ${miss.name} (${miss.id}) missing in Core or module ids`);
}
}
else {
print.success("Core and module ids are up-to-date");
}
break;
case "print-release-issue":
await (0, release_utils_1.printReleaseCandidateIssues)();
let releaseCandidatesCore = [];
let releaseCandidatesModules = [];
// TODO services
try {
const releaseCandidatesFileCore = fs_1.default.readFileSync(path_1.default.join(TMP_DIR, `release-candidates_core.json`));
releaseCandidatesCore = JSON.parse(releaseCandidatesFileCore.toString());
const releaseCandidatesFileModules = fs_1.default.readFileSync(path_1.default.join(TMP_DIR, `release-candidates_modules.json`));
releaseCandidatesModules = JSON.parse(releaseCandidatesFileModules.toString());
}
catch (err) {
print.warning(`Release candidates file(s) not found.`);
if (!(await prompt.confirm("Do you want continue?", false))) {
return;
}
}
await (0, release_utils_1.printReleaseCandidateRepos)("Core", releaseCandidatesCore);
await (0, release_utils_1.printReleaseCandidateRepos)("Modules", releaseCandidatesModules);
// TODO services
break;
case "check":
repos = (0, release_utils_1.filterIds)(scope, { skip, only });
for (const repoId of repos) {
const repo = await (0, release_utils_1.getGitlabRepo)(repoId);
print.highlight(` ➔ ${repo.name} (${repo.id})`);
if (interactive) {
if (!(await prompt.confirm("Next?", true))) {
continue;
}
}
const clonedRepo = await (0, release_utils_1.cloneRepo)(repo);
const checked = await (0, release_utils_1.check)(Object.assign(Object.assign({}, clonedRepo), { url: repo.web_url }));
if (checked.someDiffs) {
print.info(print.colors.yellow(` ‼ Anything changed`));
print.info(JSON.stringify(Object.assign(Object.assign({}, checked.diff), { files: (_a = checked.diff) === null || _a === void 0 ? void 0 : _a.files.map((f) => f.file).join(", ") }), null, 2));
print.info(print.colors.yellow(` ★ Changelog`));
print.info(checked.changelog);
print.info(print.colors.yellow(` ★ Link to graph`));
print.info(`${checked.webUrl}/-/network/${releaseBranchName}`);
// ask if repo is ready to release
if (await prompt.confirm("Is this repository release candidate?", true)) {
// save repo id for later
releaseCandidates.push(repoId);
}
}
else if (checked.errorMessage) {
print.info(print.colors.bgRed(` ‼ Something went wrong`));
print.info(print.colors.muted(` \t${checked.errorMessage}`));
}
else {
print.info(print.colors.muted(` \tNo diffs`));
// ask to force add repo to release candidates
if (scope === release_utils_1.ReleaseScopeEnum.SERVICES) {
if (await prompt.confirm("Despite of no diffs do you want set this repository as release candidate?", true)) {
// save repo id for later
releaseCandidates.push(repoId);
}
}
}
// delete repo directory
(0, release_utils_1.removeRepoDir)(clonedRepo.dir);
}
// write release candidate repo ids to file
fs_1.default.writeFileSync(path_1.default.join(TMP_DIR, `release-candidates_${scope}.json`), JSON.stringify(releaseCandidates));
break;
case "merge":
try {
const releaseCandidatesFile = fs_1.default.readFileSync(path_1.default.join(TMP_DIR, `release-candidates_${scope}.json`));
releaseCandidates = JSON.parse(releaseCandidatesFile.toString());
}
catch (err) {
print.warning(`Release candidates file not found.`);
if (!(await prompt.confirm("Do you want continue?", false))) {
return;
}
}
if (releaseCandidates.length === 0) {
print.warning(`Release candidates file is empty.`);
if (!(await prompt.confirm("Do you want continue?", false))) {
return;
}
repos = (0, release_utils_1.filterIds)(scope, { skip, only });
}
else {
repos = releaseCandidates;
}
for (const repoId of repos) {
const repo = await (0, release_utils_1.getGitlabRepo)(repoId);
print.highlight(` ➔ ${repo.name} (${repo.id})`);
if (interactive) {
if (!(await prompt.confirm("Next?", true))) {
continue;
}
}
const { id, name, url, dir, git } = await (0, release_utils_1.cloneRepo)(repo);
// show versions in branches and write correct version to package.json
const versions = await (0, release_utils_1.getVersions)(dir, url, git);
print.info(` ★ Target branch version (${targetBranchName}): ${versions.target}`);
print.info(` ★ Current branch version (${releaseBranchName}): ${versions.current}`);
const { version } = (await prompt.ask([
{
type: "input",
name: "version",
message: "Specify the version",
},
])) || versions.current;
await (0, release_utils_1.bumpVersionAndChangelog)(version, dir, git);
// upgrade @golemio dependencies
if (await prompt.confirm("Do you want upgrade @golemio dependencies?", true)) {
print.info(`✔ Upgrade @golemio dependencies to latest version`);
await (0, release_utils_1.upgradeGolemioDependencies)(dir, release_utils_1.VersionTagEnum.LATEST);
}
// commit package.json and CHANGELOG.md
await (0, release_utils_1.commitChanges)(git);
// create new MR
const mr = await (0, release_utils_1.createMR)(id, name);
print.success(` ★ Merge request was created (${mr.title}) ${mr.web_url}`);
await (0, open_1.default)(mr.web_url);
// save repo id for later
released.push(repoId);
// delete repo directory
(0, release_utils_1.removeRepoDir)(dir);
}
// write released repo ids to file
fs_1.default.writeFileSync(path_1.default.join(TMP_DIR, `released_${scope}.json`), JSON.stringify(released));
break;
case "check-mr-pipelines":
try {
const releasedFile = fs_1.default.readFileSync(path_1.default.join(TMP_DIR, `released_${scope}.json`));
released = JSON.parse(releasedFile.toString());
}
catch (err) {
print.warning(`Released repos file not found.`);
if (!(await prompt.confirm("Do you want continue?", false))) {
return;
}
}
if (released.length === 0) {
print.warning(`Released repos file is empty.`);
if (!(await prompt.confirm("Do you want continue?", false))) {
return;
}
repos = (0, release_utils_1.filterIds)(scope, { skip, only });
}
else {
repos = released;
}
for (const repoId of repos) {
const repo = await (0, release_utils_1.getGitlabRepo)(repoId);
print.highlight(` ➔ ${repo.name} (${repo.id})`);
if (interactive) {
if (!(await prompt.confirm("Next?", true))) {
continue;
}
}
const openMRPipelines = await (0, release_utils_1.checkOpenMRPipeline)(repo.id);
if (openMRPipelines && (openMRPipelines === null || openMRPipelines === void 0 ? void 0 : openMRPipelines.length) > 0) {
// MR is not merged yet, show MR pipelines
for (const pipeline of openMRPipelines) {
pipeline.status === "success"
? print.success(`Merge request pipeline ${pipeline.id} passed\n${pipeline.web_url}`)
: print.warning(`Pipeline still running or failed. Status: ${pipeline.status}\n${pipeline.web_url}`);
}
}
else {
// MR was merged, show last pipeline for target branch
print.info("No open Merge Requests");
const mergedPipeline = await (0, release_utils_1.checkMergedPipeline)(repo.id);
(mergedPipeline === null || mergedPipeline === void 0 ? void 0 : mergedPipeline.status) === "success"
? print.success(`Pipeline to ${process.env.TARGET_BRANCH_NAME} ${mergedPipeline.id} passed` +
`\n${mergedPipeline.web_url}`)
: print.warning(`Pipeline to ${process.env.TARGET_BRANCH_NAME} still running or failed. ` +
`Status: ${mergedPipeline === null || mergedPipeline === void 0 ? void 0 : mergedPipeline.status}\n${mergedPipeline === null || mergedPipeline === void 0 ? void 0 : mergedPipeline.web_url}`);
}
}
break;
case "sync-branches":
try {
const releasedFile = fs_1.default.readFileSync(path_1.default.join(TMP_DIR, `released_${scope}.json`));
released = JSON.parse(releasedFile.toString());
}
catch (err) {
print.warning(`Released repos file not found.`);
if (!(await prompt.confirm("Do you want continue?", false))) {
return;
}
}
if (released.length === 0) {
print.warning(`Released repos file is empty.`);
if (!(await prompt.confirm("Do you want continue?", false))) {
return;
}
repos = (0, release_utils_1.filterIds)(scope, { skip, only });
}
else {
repos = released;
}
for (const repoId of repos) {
const repo = await (0, release_utils_1.getGitlabRepo)(repoId);
print.highlight(` ➔ ${repo.name} (${repo.id})`);
if (interactive) {
if (!(await prompt.confirm("Next?", true))) {
continue;
}
}
const { dir, git } = await (0, release_utils_1.cloneRepo)(repo);
// after merge changes to target branch, merge changes back to release and development branches
await (0, release_utils_1.syncBranches)(repo, dir, git, true);
(0, release_utils_1.removeRepoDir)(dir);
}
break;
case "create-tags":
try {
const releasedFile = fs_1.default.readFileSync(path_1.default.join(TMP_DIR, `released_${scope}.json`));
released = JSON.parse(releasedFile.toString());
}
catch (err) {
print.warning(`Released repos file not found.`);
if (!(await prompt.confirm("Do you want continue?", false))) {
return;
}
}
if (released.length === 0) {
print.warning(`Released repos file is empty.`);
if (!(await prompt.confirm("Do you want continue?", false))) {
return;
}
repos = (0, release_utils_1.filterIds)(scope, { skip, only });
}
else {
repos = released;
}
for (const repoId of repos) {
const repo = await (0, release_utils_1.getGitlabRepo)(repoId);
print.highlight(` ➔ ${repo.name} (${repo.id})`);
if (interactive) {
if (!(await prompt.confirm("Next?", true))) {
continue;
}
}
const { dir, url, git } = await (0, release_utils_1.cloneRepo)(repo);
// create new tag and release from target branch
await (0, release_utils_1.createTagAndRelease)(repo.id, dir, url, git);
(0, release_utils_1.removeRepoDir)(dir);
}
break;
}
},
};
exports.default = command;
//# sourceMappingURL=release.js.map