UNPKG

@golemio/cli

Version:

Collection of executables intended for use with Golemio services and modules

305 lines 16.6 kB
"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 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