|
| 1 | +// tslint:disable:no-var-requires |
| 2 | +// tslint:disable:no-console |
| 3 | + |
| 4 | +/* |
| 5 | +
|
| 6 | + Bumps the package version and releases a new tag |
| 7 | + to set off a CI and npm release run |
| 8 | +
|
| 9 | + CALL THIS WITH: |
| 10 | + npm run release -- [<releaseType> [<postfix]] [--dry] |
| 11 | + or |
| 12 | + npm run release -- <version> [--dry] |
| 13 | +
|
| 14 | +*/ |
| 15 | + |
| 16 | +import { execSync } from "child_process"; |
| 17 | +import * as fs from "fs"; |
| 18 | +import * as path from "path"; |
| 19 | +import * as readline from "readline"; |
| 20 | +const semver = require("semver"); |
| 21 | +const colors = require("colors/safe"); |
| 22 | +import { argv } from "yargs"; |
| 23 | + |
| 24 | +const rootDir = path.resolve(__dirname, "../"); |
| 25 | + |
| 26 | +const packPath = path.join(rootDir, "package.json"); |
| 27 | +const pack = require(packPath); |
| 28 | +// const ioPackPath = path.join(rootDir, "io-package.json"); |
| 29 | +// const ioPack = require(ioPackPath); |
| 30 | + |
| 31 | +function fail(reason: string) { |
| 32 | + console.error(""); |
| 33 | + console.error(colors.red(reason)); |
| 34 | + console.error(""); |
| 35 | + process.exit(0); |
| 36 | +} |
| 37 | + |
| 38 | +// check if there are untracked changes |
| 39 | +const gitStatus = execSync("git status", {cwd: rootDir, encoding: "utf8"}); |
| 40 | +if (/have diverged/.test(gitStatus)) { |
| 41 | + if (!argv.dry) fail(colors.red("Cannot continue, the local branch has diverged from the git repo!")); |
| 42 | + else console.log(colors.yellow("This is a dry run. The full run would fail due to a diverged branch\n")); |
| 43 | +} else if (!/working tree clean/.test(gitStatus)) { |
| 44 | + if (!argv.dry) fail(colors.red("Cannot continue, the local branch has uncommited changes!")); |
| 45 | + else console.log(colors.yellow("This is a dry run. The full run would fail due to uncommited changes\n")); |
| 46 | +} else if (/Your branch is behind/.test(gitStatus)) { |
| 47 | + if (!argv.dry) fail(colors.red("Cannot continue, the local branch is behind the remote changes!")); |
| 48 | + else console.log(colors.yellow("This is a dry run. The full run would fail due to the local branch being behind\n")); |
| 49 | +} else if (/Your branch is up\-to\-date/.test(gitStatus) || /Your branch is ahead/.test(gitStatus)) { |
| 50 | + // all good |
| 51 | +} |
| 52 | + |
| 53 | +const releaseTypes = ["major", "premajor", "minor", "preminor", "patch", "prepatch", "prerelease"]; |
| 54 | + |
| 55 | +const releaseType = argv._[0] || "patch"; |
| 56 | +let newVersion = releaseType; |
| 57 | +const oldVersion = pack.version as string; |
| 58 | +if (releaseTypes.indexOf(releaseType) > -1) { |
| 59 | + if (releaseType.startsWith("pre") && argv._.length >= 2) { |
| 60 | + // increment to pre-release with an additional prerelease string |
| 61 | + newVersion = semver.inc(oldVersion, releaseType, argv._[1]); |
| 62 | + } else { |
| 63 | + newVersion = semver.inc(oldVersion, releaseType); |
| 64 | + } |
| 65 | + console.log(`bumping version ${colors.blue(oldVersion)} to ${colors.gray(releaseType)} version ${colors.green(newVersion)}\n`); |
| 66 | +} else { |
| 67 | + // increment to specific version |
| 68 | + newVersion = semver.clean(newVersion); |
| 69 | + if (newVersion == null) { |
| 70 | + fail(`invalid version string "${newVersion}"`); |
| 71 | + } else { |
| 72 | + // valid version string => check if its actually newer |
| 73 | + if (!semver.gt(newVersion, pack.version)) { |
| 74 | + fail(`new version ${newVersion} is NOT > than package.json version ${pack.version}`); |
| 75 | + } |
| 76 | + // if (!semver.gt(newVersion, ioPack.common.version)) { |
| 77 | + // fail(`new version ${newVersion} is NOT > than io-package.json version ${ioPack.common.version}`); |
| 78 | + // } |
| 79 | + } |
| 80 | + console.log(`bumping version ${oldVersion} to specific version ${newVersion}`); |
| 81 | +} |
| 82 | + |
| 83 | +if (argv.dry) { |
| 84 | + console.log(colors.yellow("dry run:") + " not updating package files"); |
| 85 | +} else { |
| 86 | + console.log(`updating package.json from ${colors.blue(pack.version)} to ${colors.green(newVersion)}`); |
| 87 | + pack.version = newVersion; |
| 88 | + fs.writeFileSync(packPath, JSON.stringify(pack, null, 2)); |
| 89 | + |
| 90 | + // console.log(`updating io-package.json from ${colors.blue(ioPack.common.version)} to ${colors.green(newVersion)}`); |
| 91 | + // ioPack.common.version = newVersion; |
| 92 | + // fs.writeFileSync(ioPackPath, JSON.stringify(ioPack, null, 4)); |
| 93 | +} |
| 94 | + |
| 95 | +const gitCommands = [ |
| 96 | + `git add -A`, |
| 97 | + `git commit -m "release v${newVersion} [skip ci]"`, |
| 98 | + `git push`, |
| 99 | + `git tag v${newVersion}`, |
| 100 | + `git push origin --tags`, |
| 101 | +]; |
| 102 | +if (argv.dry) { |
| 103 | + console.log(colors.yellow("dry run:") + " I would execute this:"); |
| 104 | + for (const command of gitCommands) { |
| 105 | + console.log(" " + command); |
| 106 | + } |
| 107 | +} else { |
| 108 | + for (const command of gitCommands) { |
| 109 | + console.log(`executing "${colors.blue(command)}" ...`); |
| 110 | + execSync(command, {cwd: rootDir}); |
| 111 | + } |
| 112 | +} |
| 113 | + |
| 114 | +console.log(""); |
| 115 | +console.log(colors.green("done!")); |
| 116 | +console.log(""); |
| 117 | + |
| 118 | +process.exit(0); |
0 commit comments