Skip to content

Commit 068008d

Browse files
e-cloudbcoe
authored andcommitted
feat: support releasing a custom version, including pre-releases (#129)
1 parent b6e1562 commit 068008d

File tree

7 files changed

+295
-27
lines changed

7 files changed

+295
-27
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,6 @@ npm-debug.log
1111
/.settings
1212
/.idea
1313
/.vscode
14+
15+
# coverage
16+
coverage

README.md

+34
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,40 @@ As long as your git commit messages are conventional and accurate, you no longer
9696

9797
After you cut a release, you can push the new git tag and `npm publish` (or `npm publish --tag next`) when you're ready.
9898

99+
### Release as a pre-release
100+
101+
Use `--prerelease`, you can generate a pre-release.
102+
103+
Suppose the last version of your code is `1.0.0`, and your code to be committed has patched changes. Run
104+
```bash
105+
# npm run script
106+
npm run release -- --prerelease
107+
```
108+
you will get version `1.0.1-0`.
109+
110+
If you want to name the pre-release, you specify the name via `--prerelease <name>`.
111+
112+
For example, the wanted name is `alpha`
113+
. Use the example above:
114+
```bash
115+
# npm run script
116+
npm run release -- --prerelease alpha
117+
```
118+
you will get version `1.0.1-alpha.0`
119+
120+
### Release as a target type imperatively like `npm version`
121+
122+
You can use `--release-as` to generate a `major`, `minor` or `patch` release imperatively.
123+
124+
Suppose the last version of your code is `1.0.0`, and your code to be committed has patched changes. Run
125+
```bash
126+
# npm run script
127+
npm run release -- --release-as minor
128+
```
129+
you will get version `1.1.0` rather than the smartly generated version `1.0.1`.
130+
131+
**NOTE:** you can combine `--release-as` and `--prerelease` to generate a release. That's useful when publishing experimental feature(s).
132+
99133
### Prevent Git Hooks
100134

101135
If you use git hooks, like pre-commit, to test your code before committing, you can prevent hooks from being verified during the commit step by passing the `--no-verify` option:

bin/cli.js

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#!/usr/bin/env node
2+
var standardVersion = require('../index')
3+
var cmdParser = require('../command')
4+
5+
standardVersion(cmdParser.argv, function (err) {
6+
if (err) {
7+
process.exit(1)
8+
}
9+
})

cli.js renamed to command.js

+17-10
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,21 @@
1-
#!/usr/bin/env node
2-
var standardVersion = require('./index')
31
var defaults = require('./defaults')
42

5-
var argv = require('yargs')
3+
module.exports = require('yargs')
64
.usage('Usage: $0 [options]')
5+
.option('release-as', {
6+
alias: 'r',
7+
describe: 'Specify the release type manually. like npm version xxx with limited choices',
8+
requiresArg: true,
9+
string: true,
10+
choices: ['major', 'minor', 'patch'],
11+
global: true
12+
})
13+
.option('prerelease', {
14+
alias: 'p',
15+
describe: 'make a pre-release with optional option value to specify a tag id',
16+
string: true,
17+
global: true
18+
})
719
.option('infile', {
820
alias: 'i',
921
describe: 'Read the CHANGELOG from this file',
@@ -51,15 +63,10 @@ var argv = require('yargs')
5163
default: defaults.silent,
5264
global: true
5365
})
66+
.version()
67+
.alias('version', 'v')
5468
.help()
5569
.alias('help', 'h')
5670
.example('$0', 'Update changelog and tag release')
5771
.example('$0 -m "%s: see changelog for details"', 'Update changelog and tag release with custom commit message')
5872
.wrap(97)
59-
.argv
60-
61-
standardVersion(argv, function (err) {
62-
if (err) {
63-
process.exit(1)
64-
}
65-
})

index.js

+93-12
Original file line numberDiff line numberDiff line change
@@ -16,40 +16,121 @@ module.exports = function standardVersion (argv, done) {
1616
var pkg = require(pkgPath)
1717
var defaults = require('./defaults')
1818

19-
argv = objectAssign(defaults, argv)
19+
var args = objectAssign({}, defaults, argv)
2020

21-
conventionalRecommendedBump({
22-
preset: 'angular'
23-
}, function (err, release) {
21+
bumpVersion(args.releaseAs, function (err, release) {
2422
if (err) {
25-
printError(argv, err.message)
23+
printError(args, err.message)
2624
return done(err)
2725
}
2826

2927
var newVersion = pkg.version
30-
if (!argv.firstRelease) {
31-
newVersion = semver.inc(pkg.version, release.releaseType)
32-
checkpoint(argv, 'bumping version in package.json from %s to %s', [pkg.version, newVersion])
28+
29+
if (!args.firstRelease) {
30+
var releaseType = getReleaseType(args.prerelease, release.releaseType, pkg.version)
31+
newVersion = semver.inc(pkg.version, releaseType, args.prerelease)
32+
33+
checkpoint(args, 'bumping version in package.json from %s to %s', [pkg.version, newVersion])
34+
3335
pkg.version = newVersion
3436
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n', 'utf-8')
3537
} else {
36-
checkpoint(argv, 'skip version bump on first release', [], chalk.red(figures.cross))
38+
checkpoint(args, 'skip version bump on first release', [], chalk.red(figures.cross))
3739
}
3840

39-
outputChangelog(argv, function (err) {
41+
outputChangelog(args, function (err) {
4042
if (err) {
4143
return done(err)
4244
}
43-
commit(argv, newVersion, function (err) {
45+
commit(args, newVersion, function (err) {
4446
if (err) {
4547
return done(err)
4648
}
47-
return tag(newVersion, pkg.private, argv, done)
49+
return tag(newVersion, pkg.private, args, done)
4850
})
4951
})
5052
})
5153
}
5254

55+
function getReleaseType (prerelease, expectedReleaseType, currentVersion) {
56+
if (isString(prerelease)) {
57+
if (isInPrerelease(currentVersion)) {
58+
if (shouldContinuePrerelease(currentVersion, expectedReleaseType) ||
59+
getTypePriority(getCurrentActiveType(currentVersion)) > getTypePriority(expectedReleaseType)
60+
) {
61+
return 'prerelease'
62+
}
63+
}
64+
65+
return 'pre' + expectedReleaseType
66+
} else {
67+
return expectedReleaseType
68+
}
69+
}
70+
71+
function isString (val) {
72+
return typeof val === 'string'
73+
}
74+
75+
/**
76+
* if a version is currently in pre-release state,
77+
* and if it current in-pre-release type is same as expect type,
78+
* it should continue the pre-release with the same type
79+
*
80+
* @param version
81+
* @param expectType
82+
* @return {boolean}
83+
*/
84+
function shouldContinuePrerelease (version, expectType) {
85+
return getCurrentActiveType(version) === expectType
86+
}
87+
88+
function isInPrerelease (version) {
89+
return Array.isArray(semver.prerelease(version))
90+
}
91+
92+
var TypeList = ['major', 'minor', 'patch'].reverse()
93+
94+
/**
95+
* extract the in-pre-release type in target version
96+
*
97+
* @param version
98+
* @return {string}
99+
*/
100+
function getCurrentActiveType (version) {
101+
var typelist = TypeList
102+
for (var i = 0; i < typelist.length; i++) {
103+
if (semver[typelist[i]](version)) {
104+
return typelist[i]
105+
}
106+
}
107+
}
108+
109+
/**
110+
* calculate the priority of release type,
111+
* major - 2, minor - 1, patch - 0
112+
*
113+
* @param type
114+
* @return {number}
115+
*/
116+
function getTypePriority (type) {
117+
return TypeList.indexOf(type)
118+
}
119+
120+
function bumpVersion (releaseAs, callback) {
121+
if (releaseAs) {
122+
callback(null, {
123+
releaseType: releaseAs
124+
})
125+
} else {
126+
conventionalRecommendedBump({
127+
preset: 'angular'
128+
}, function (err, release) {
129+
callback(err, release)
130+
})
131+
}
132+
}
133+
53134
function outputChangelog (argv, cb) {
54135
createIfMissing(argv)
55136
var header = '# Change Log\n\nAll notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.\n'

package.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
"name": "standard-version",
33
"version": "3.0.0",
44
"description": "replacement for `npm version` with automatic CHANGELOG generation",
5-
"bin": "cli.js",
5+
"bin": "bin/cli.js",
66
"scripts": {
77
"pretest": "standard",
88
"coverage": "nyc report --reporter=text-lcov | coveralls",
99
"test": "nyc mocha --timeout=20000 test.js",
10-
"release": "./cli.js"
10+
"release": "bin/cli.js"
1111
},
1212
"repository": {
1313
"type": "git",
@@ -43,6 +43,7 @@
4343
"yargs": "^6.0.0"
4444
},
4545
"devDependencies": {
46+
"bluebird": "^3.4.6",
4647
"chai": "^3.5.0",
4748
"coveralls": "^2.11.9",
4849
"mocha": "^3.1.0",

0 commit comments

Comments
 (0)