UNPKG

@tinymce/beehive-flow

Version:

A CLI tool implementing the beehive flow git branching process

186 lines 7.99 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createReleaseBranch = exports.getBranchDetails = exports.readModulesIfEnabled = exports.readModules = exports.isValidPrerelease = exports.getBranchType = exports.mainBranchName = exports.versionFromReleaseBranch = exports.getReleaseBranchName = void 0; const tslib_1 = require("tslib"); const fs = tslib_1.__importStar(require("fs")); const path = tslib_1.__importStar(require("path")); const O = tslib_1.__importStar(require("fp-ts/Option")); const simple_git_1 = require("simple-git"); const PromiseUtils = tslib_1.__importStar(require("../utils/PromiseUtils")); const StringUtils_1 = require("../utils/StringUtils"); const Git = tslib_1.__importStar(require("../utils/Git")); const BuildProperties_1 = require("./BuildProperties"); const Version = tslib_1.__importStar(require("./Version")); const PreRelease = tslib_1.__importStar(require("./PreRelease")); const PackageJson = tslib_1.__importStar(require("./PackageJson")); const YarnWorkspaces = tslib_1.__importStar(require("./YarnWorkspaces")); const getReleaseBranchName = ({ major, minor }) => `release/${major}.${minor}`; exports.getReleaseBranchName = getReleaseBranchName; const versionFromReleaseBranch = async (branchName) => { const regexp = /^release\/(?<major>0|[1-9]\d*)\.(?<minor>0|[1-9]\d*)$/; const r = regexp.exec(branchName); if (r === null || r.groups === undefined) { return PromiseUtils.fail('Could not parse major.minor version from branch name'); } else { const g = r.groups; const major = parseInt(g.major, 10); const minor = parseInt(g.minor, 10); return { major, minor }; } }; exports.versionFromReleaseBranch = versionFromReleaseBranch; exports.mainBranchName = 'main'; const getBranchType = (branchName) => { if (branchName === exports.mainBranchName) { return O.some("main" /* BranchType.Main */); } else { const parts = branchName.split('/'); switch (parts[0]) { case 'feature': return O.some("feature" /* BranchType.Feature */); case 'hotfix': return O.some("hotfix" /* BranchType.Hotfix */); case 'spike': return O.some("spike" /* BranchType.Spike */); case 'release': return O.some("release" /* BranchType.Release */); case 'dependabot': return O.some("dependabot" /* BranchType.Dependabot */); default: return O.none; } } }; exports.getBranchType = getBranchType; const isValidPrerelease = (actual, expected) => actual !== undefined && (actual === expected || actual.startsWith(`${expected}.`)); exports.isValidPrerelease = isValidPrerelease; const findChangelog = (dir) => { const changelogFile = path.join(dir, 'CHANGELOG.md'); if (fs.existsSync(changelogFile)) { return { changelogFile, changelogFormat: 'keepachangelog' }; } else { return { changelogFile: '', changelogFormat: 'none' }; } }; const readModule = async (dir) => { const packageJsonFile = path.join(dir, 'package.json'); const packageJson = await PackageJson.parsePackageJsonFile(packageJsonFile); const changelog = findChangelog(dir); return { packageJson, packageJsonFile, ...changelog }; }; const readModules = async (dir) => { const ws = await YarnWorkspaces.info(dir); return PromiseUtils.parMapRecord(ws, (w) => readModule(path.join(dir, w.location))); }; exports.readModules = readModules; const readModulesIfEnabled = async (dir, packageJson) => { const workspacesEnabled = packageJson.workspaces !== undefined; if (workspacesEnabled) { return { workspacesEnabled, modules: await (0, exports.readModules)(dir) }; } else { return { workspacesEnabled, modules: {} }; } }; exports.readModulesIfEnabled = readModulesIfEnabled; const getBranchDetails = async (dir) => { const fail = PromiseUtils.fail; const git = (0, simple_git_1.gitP)(dir); await git.checkIsRepo(simple_git_1.CheckRepoActions.IS_REPO_ROOT); const currentBranch = await Git.currentBranch(git); const rootModule = await readModule(dir); const { workspacesEnabled, modules } = await (0, exports.readModulesIfEnabled)(dir, rootModule.packageJson); const version = rootModule.packageJson.version; if (version === undefined) { throw new Error('Version missing in package.json file'); } const baseState = { currentBranch, version, rootModule }; const loc = `${currentBranch} branch: package.json version`; const sPackageVersion = Version.versionToString(version); const sPre = (0, StringUtils_1.showStringOrUndefined)(version.preRelease); const rcOrReleaseReady = async () => { if (version.preRelease === undefined) { return "releaseReady" /* BranchState.ReleaseReady */; } else if ((0, exports.isValidPrerelease)(version.preRelease, PreRelease.releaseCandidate)) { return "releaseCandidate" /* BranchState.ReleaseCandidate */; } else { const rc = PreRelease.releaseCandidate; return fail(`${loc}: prerelease version part should be either "${rc}" or start with "${rc}." or not be set, but it is "${sPre}"`); } }; const validateMainBranch = rcOrReleaseReady; const validateReleaseBranch = async () => { const branchVersion = await (0, exports.versionFromReleaseBranch)(currentBranch); const sBranchVersion = Version.majorMinorVersionToString(branchVersion); if (version.major !== branchVersion.major || version.minor !== branchVersion.minor) { return fail(`${loc}: major.minor of branch (${sBranchVersion}) is not consistent with package version (${sPackageVersion})`); } else { return rcOrReleaseReady(); } }; const detect = async (branchType) => { switch (branchType) { case "main" /* BranchType.Main */: return validateMainBranch(); case "feature" /* BranchType.Feature */: case "dependabot" /* BranchType.Dependabot */: return "feature" /* BranchState.Feature */; case "hotfix" /* BranchType.Hotfix */: return "hotfix" /* BranchState.Hotfix */; case "spike" /* BranchType.Spike */: return "spike" /* BranchState.Spike */; case "release" /* BranchType.Release */: return validateReleaseBranch(); } }; if (version.buildMetaData !== undefined) { return fail(`package.json version has an unexpected buildMetaData part`); } else { const obt = (0, exports.getBranchType)(currentBranch); if (O.isNone(obt)) { return fail('Invalid branch name. beehive-flow is strict about branch names. Valid names: main, feature/*, hotfix/*, spike/*, release/x.y'); } else { const branchType = obt.value; const branchState = await detect(branchType); return { ...baseState, branchState, branchType, workspacesEnabled, modules }; } } }; exports.getBranchDetails = getBranchDetails; const createReleaseBranch = async (releaseBranchName, git, dir) => { console.log(`Creating ${releaseBranchName} branch`); await Git.checkoutNewBranch(git, releaseBranchName); const buildPropertiesFile = await (0, BuildProperties_1.writeBuildPropertiesFile)(dir, releaseBranchName); await git.add([buildPropertiesFile]); await git.commit(`Creating release branch: ${releaseBranchName}`); }; exports.createReleaseBranch = createReleaseBranch; //# sourceMappingURL=BranchLogic.js.map