Skip to content

Commit f225533

Browse files
committed
Release script updates
1 parent ed301bb commit f225533

File tree

2 files changed

+84
-58
lines changed

2 files changed

+84
-58
lines changed

package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@
1717
"@types/shelljs": "0.3.32",
1818
"chokidar": "1.6.0",
1919
"intern": "~3.4.0",
20-
"shelljs": "0.7.4",
21-
"typescript": "~2.0.0"
20+
"shelljs": "0.7.4",
21+
"typescript": "~2.0.0",
22+
"semver": "5.3.0"
2223
},
2324
"peerDependencies": {
2425
"intern": "~3.4.0"
@@ -39,4 +40,4 @@
3940
"watch": "node ./support/watch.js",
4041
"release": "node ./support/release.js"
4142
}
42-
}
43+
}

support/release.js

Lines changed: 80 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,25 @@
11
/* global Promise */
22

3+
// Release versioning:
4+
//
5+
// If the user supplies a version q.r.s, it must be >= version x.y.z that is the version in the current branch. If an
6+
// x.y branch is being released and the user supplies a version. the version must be x.y.q >= the x.y.z-pre version of
7+
// the branch.
8+
//
9+
// 1. If releasing from master
10+
// A) and major version is 0.x.0-pre
11+
// i) release is 0.x.0
12+
// ii) next is 0.<x+1>.0-pre
13+
// B) and major version is x.y.0(-pre) (patch version must be 0)
14+
// i) release is x.y.0
15+
// ii) create new branch x.y
16+
// iii) next is x.<y+1>.0-pre
17+
// 2. If releasing from branch x.y, version x.y.z(-pre)
18+
// A) release is x.y.z
19+
// B) next is x.y.<z+1>-pre
20+
321
var shell = require('shelljs');
22+
var semver = require('semver');
423
var fs = require('fs');
524
var path = require('path');
625
var util = require('util');
@@ -20,11 +39,11 @@ function print() {
2039
}
2140

2241
function printUsage() {
23-
print('Usage: %s [options] [branch] [version]\n', process.argv[1]);
42+
print('Usage: %s [--help] [branch [version]]\n', process.argv[1]);
2443
print('\n');
25-
print('Branch defaults to "master".\n');
26-
print('Version defaults to what is listed in package.json in the branch.\n');
27-
print('Version should only be specified for pre-releases.\n');
44+
print('<branch> defaults to "master".\n');
45+
print('<version> is the version to release, and defaults to what is listed in the\n');
46+
print(' package.json in the branch. It should only be specified for pre-releases\n');
2847
}
2948

3049
function prompt() {
@@ -69,12 +88,15 @@ var buildDir = path.join(rootDir, '_build');
6988
var branch = args[0] || 'master';
7089
var pushBranches = [ branch ];
7190
var npmTag = 'latest';
91+
92+
// the version to be released
7293
var version;
73-
var releaseTag;
74-
var makeBranch;
94+
// the next pre-release version that will be set on the original branch after tagging
7595
var preVersion;
96+
// the name of the new release branch that should be created if this is not a patch release
97+
var newBranch;
98+
// the pre-release version that will be set on the minor release branch
7699
var branchVersion;
77-
var tagVersion;
78100

79101
if (args[1]) {
80102
version = args[1];
@@ -121,56 +143,54 @@ run('git config receive.denyCurrentBranch').then(
121143
var packageJson = loadPackageJson();
122144

123145
// Determine the proper version numbers for release and for repo post-release
146+
124147
if (!version) {
125-
version = packageJson.version.replace('-pre', '');
126-
preVersion = version.split('.').map(Number);
127-
128-
// If the last digit is a 0, this is a new major/minor release
129-
if (preVersion[2] === 0) {
130-
// We'll be creating a new minor release branch for this version for any future patch releases
131-
// e.g., current is 2.1.0, branch will be 2.1.1-pre
132-
branchVersion = util.format('%s.%s.%s-pre', preVersion[0], preVersion[1], preVersion[2] + 1);
133-
134-
// makeBranch is the new branch we'll be making for this major/minor release
135-
makeBranch = util.format('%s.%s', preVersion[0], preVersion[1]);
136-
137-
// The next release is usually going to be a minor release; if the next version is to be a major release,
138-
// the package version will need to be manually updated in Git before release
139-
// e.g., current is 2.1.0, pre will be 2.2.0-pre
140-
preVersion = util.format('%s.%s.0-pre', preVersion[0], preVersion[1] + 1);
141-
}
142-
// If the last digit isn't a 0, this is a new patch release
143-
else {
144-
// Patch releases do not get a branch, and the next release version will always be another patch version
145-
// e.g., current is 2.1.0, pre will be 2.1.1-pre
146-
preVersion = util.format('%s.%s.%s-pre', preVersion[0], preVersion[1], preVersion[2] + 1);
148+
// Use the version from package.json in the currently checked out branch
149+
version = packageJson.version;
150+
151+
if (!semver.prerelease(version)) {
152+
throw new Error('Releases may only be generated from pre-release versions');
147153
}
154+
155+
version = semver.major(version) + '.' + semver.minor(version) + '.' + semver.patch(version);
148156
}
149157
else {
150-
preVersion = packageJson.version + '-pre';
158+
if (semver.gte(version, packageJson.version)) {
159+
throw new Error('Provided version must be >= current version');
160+
}
151161
}
152162

153-
releaseTag = tagVersion = version;
154-
155-
// At this point:
156-
// `version` is the version of the package that is being released;
157-
// `tagVersion` is the name that will be used for the Git tag for the release
158-
// `preVersion` is the next pre-release version that will be set on the original branch after tagging
159-
// `makeBranch` is the name of the new release branch that should be created if this is not a patch release
160-
// `branchVersion` is the pre-release version that will be set on the minor release branch
161-
163+
// Check that the version hasn't already been tagged
162164
return run('git tag').then(function (tags) {
163165
tags.split('\n').forEach(function (tag) {
164-
if (tag === tagVersion) {
166+
if (tag === version) {
165167
throw new Error('Version ' + tag + ' has already been tagged');
166168
}
167169
});
168170
});
171+
}).then(function () {
172+
// Pre-release or non-branching updates
173+
if (semver.major(version) === 0 || semver.patch(version) !== 0) {
174+
preVersion = semver.inc(version, 'patch') + '-pre';
175+
}
176+
// If the patch digit is a 0, this is a new major/minor release
177+
else {
178+
// The new branch we'll be making for this major/minor release
179+
newBranch = util.format('%s.%s', semver.major(version), semver.minor(version));
180+
181+
// The full version of the next release in the new branch
182+
branchVersion = semver.inc(version, 'patch') + '-pre';
183+
184+
// The next version on master is usually going to be a minor release; if the next version is to be a major
185+
// release, the package version will need to be manually updated in Git before release e.g., current is
186+
// 2.1.0, pre will be 2.2.0-pre
187+
preVersion = semver.inc(version, 'minor') + '-pre';
188+
}
169189
}).then(function () {
170190
// Set the package version to release version and commit the new release
171191
updatePackageVersion(version);
172192
return run('git commit -m "Updating metadata for ' + version + '" package.json').then(function () {
173-
return run('git tag -a -m "Release ' + version + '" ' + tagVersion);
193+
return run('git tag -a -m "Release ' + version + '" ' + version);
174194
});
175195
}).then(function () {
176196
// Check out the previous package.json
@@ -183,22 +203,22 @@ run('git config receive.denyCurrentBranch').then(
183203
return run('git commit -m "Updating source version to ' + preVersion + '" package.json');
184204
}).then(function () {
185205
// If this is a major/minor release, we also create a new branch for it
186-
if (makeBranch) {
187-
print('Creating new branch %s...\n', makeBranch);
206+
if (newBranch) {
207+
print('Creating new branch %s...\n', newBranch);
188208
// Create the new branch starting at the tagged release version
189-
return run('git checkout -b ' + makeBranch + ' ' + tagVersion).then(function () {
209+
return run('git checkout -b ' + newBranch + ' ' + version).then(function () {
190210
// Set the package version to the next patch pre-release version and commit the pre-release
191211
updatePackageVersion(branchVersion);
192212
return run('git commit -m "Updating source version to ' + branchVersion + '" package.json');
193213
}).then(function () {
194214
// Store the branch as one that needs to be pushed when we are ready to deploy the release
195-
pushBranches.push(makeBranch);
215+
pushBranches.push(newBranch);
196216
});
197217
}
198218
}).then(function () {
199219
// Checkout and build the new release in preparation for publishing
200-
print('Checking out and building %s...\n', releaseTag);
201-
return run('git checkout ' + releaseTag).then(function () {
220+
print('Checking out and building %s...\n', version);
221+
return run('git checkout ' + version).then(function () {
202222
return run('npm install');
203223
}).then(function () {
204224
return run('node ./support/build.js dist');
@@ -208,13 +228,12 @@ run('git config receive.denyCurrentBranch').then(
208228
print('\nDone!\n\n');
209229

210230
var question = 'Please confirm packaging success, then enter "y" to publish to npm\n' +
211-
npmTag + ', push tags ' + releaseTag + ', and upload. Enter any other key to bail.\n' +
231+
npmTag + ', push tags ' + version + ', and upload. Enter any other key to bail.\n' +
212232
'> ';
213233

214234
return prompt(question).then(function (answer) {
215235
if (answer !== 'y') {
216-
cleanup();
217-
process.exit(0);
236+
throw new Error('Aborted');
218237
}
219238
});
220239
}).then(function () {
@@ -228,12 +247,18 @@ run('git config receive.denyCurrentBranch').then(
228247
return run('git push origin --tags');
229248
});
230249
}).then(function () {
250+
rl.close();
231251
cleanup();
232252
print('\nAll done! Yay!\n');
233-
process.exit(0);
234253
}).catch(function (error) {
235-
// Something broke -- display an error
236-
print(error + '\n');
237-
print('Aborted.\n');
238-
process.exit(1);
254+
rl.close();
255+
if (error.message === 'Aborted') {
256+
cleanup();
257+
}
258+
else {
259+
// Something broke -- display an error
260+
print(error + '\n');
261+
print('Aborted.\n');
262+
process.exit(1);
263+
}
239264
});

0 commit comments

Comments
 (0)