release-it 15.0.0-esm.2 → 15.0.0-esm.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -16
- package/config/release-it.json +5 -1
- package/lib/config.js +7 -15
- package/lib/index.js +13 -21
- package/lib/log.js +1 -1
- package/lib/plugin/GitBase.js +2 -2
- package/lib/plugin/GitRelease.js +1 -1
- package/lib/plugin/Plugin.js +1 -1
- package/lib/plugin/factory.js +5 -5
- package/lib/plugin/git/Git.js +11 -4
- package/lib/plugin/github/GitHub.js +59 -15
- package/lib/plugin/gitlab/GitLab.js +69 -15
- package/lib/plugin/npm/npm.js +3 -2
- package/lib/plugin/version/Version.js +5 -5
- package/lib/shell.js +3 -3
- package/lib/spinner.js +3 -3
- package/lib/util.js +2 -2
- package/package.json +36 -42
- package/test/config.js +21 -28
- package/test/git.init.js +32 -7
- package/test/git.js +5 -2
- package/test/github.js +116 -19
- package/test/gitlab.js +69 -18
- package/test/log.js +1 -1
- package/test/npm.js +12 -3
- package/test/plugins.js +34 -22
- package/test/spinner.js +8 -11
- package/test/stub/config/default/.release-it.json +5 -0
- package/test/stub/config/invalid-config-rc +1 -0
- package/test/stub/config/invalid-config-txt +2 -0
- package/test/stub/config/merge/.release-it.json +5 -0
- package/test/stub/config/merge/package.json +7 -0
- package/test/stub/config/toml/.release-it.toml +2 -0
- package/test/stub/config/yaml/.release-it.yaml +2 -0
- package/test/stub/config/yml/.release-it.yml +2 -0
- package/test/stub/github.js +26 -10
- package/test/stub/gitlab.js +15 -7
- package/test/stub/shell.js +2 -2
- package/test/tasks.interactive.js +2 -3
- package/test/tasks.js +44 -4
- package/test/util/helpers.js +6 -6
- package/test/util/index.js +13 -18
- package/test/utils.js +1 -1
- package/test/version.js +14 -9
- package/config/.codecov.yml +0 -5
- package/config/deprecated.json +0 -1
- package/lib/deprecated.js +0 -22
- package/lib/metrics.js +0 -76
- package/test/deprecated.js +0 -11
- package/test/metrics.js +0 -17
|
@@ -53,10 +53,6 @@ class Version extends Plugin {
|
|
|
53
53
|
this.registerPrompts(prompts);
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
getLatestVersion() {
|
|
57
|
-
return '0.0.0';
|
|
58
|
-
}
|
|
59
|
-
|
|
60
56
|
getIncrement(options) {
|
|
61
57
|
return options.increment;
|
|
62
58
|
}
|
|
@@ -110,7 +106,11 @@ class Version extends Plugin {
|
|
|
110
106
|
}
|
|
111
107
|
|
|
112
108
|
if (this.config.isCI && !increment) {
|
|
113
|
-
|
|
109
|
+
if (isPreRelease) {
|
|
110
|
+
return semver.inc(latestVersion, 'prepatch', preReleaseId);
|
|
111
|
+
} else {
|
|
112
|
+
return semver.inc(latestVersion, 'patch');
|
|
113
|
+
}
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
const normalizedType = RELEASE_TYPES.includes(increment) && isPreRelease ? `pre${increment}` : increment;
|
package/lib/shell.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import util from 'node:util';
|
|
1
2
|
import sh from 'shelljs';
|
|
2
|
-
import execa from 'execa';
|
|
3
|
-
import _debug from 'debug';
|
|
3
|
+
import { execa } from 'execa';
|
|
4
4
|
import { format } from './util.js';
|
|
5
5
|
|
|
6
|
-
const debug =
|
|
6
|
+
const debug = util.debug('release-it:shell');
|
|
7
7
|
|
|
8
8
|
sh.config.silent = !debug.enabled;
|
|
9
9
|
|
package/lib/spinner.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { oraPromise } from 'ora';
|
|
2
2
|
import { format } from './util.js';
|
|
3
3
|
|
|
4
4
|
const noop = Promise.resolve();
|
|
@@ -6,7 +6,7 @@ const noop = Promise.resolve();
|
|
|
6
6
|
class Spinner {
|
|
7
7
|
constructor({ container = {} } = {}) {
|
|
8
8
|
this.config = container.config;
|
|
9
|
-
this.ora = container.ora ||
|
|
9
|
+
this.ora = container.ora || oraPromise;
|
|
10
10
|
}
|
|
11
11
|
show({ enabled = true, task, label, external = false, context }) {
|
|
12
12
|
if (!enabled) return noop;
|
|
@@ -19,7 +19,7 @@ class Spinner {
|
|
|
19
19
|
|
|
20
20
|
if (!this.isSpinnerDisabled || (external && this.canForce)) {
|
|
21
21
|
const text = format(label, context);
|
|
22
|
-
this.ora
|
|
22
|
+
this.ora(awaitTask, text);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
return awaitTask;
|
package/lib/util.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "release-it",
|
|
3
|
-
"version": "15.0.0-esm.
|
|
3
|
+
"version": "15.0.0-esm.5",
|
|
4
4
|
"description": "Generic CLI tool to automate versioning and package publishing related tasks.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"build",
|
|
@@ -49,10 +49,7 @@
|
|
|
49
49
|
"scripts": {
|
|
50
50
|
"lint": "eslint lib test",
|
|
51
51
|
"format": "prettier --write \"{lib,test}/**/*.js\"",
|
|
52
|
-
"test": "ava --
|
|
53
|
-
"coverage": "nyc --reporter=lcov --reporter=html --config=config/.codecov.yml npm test",
|
|
54
|
-
"codecov": "nyc --reporter=json --config=config/.codecov.yml npm test && codecov -f coverage/coverage-final.json",
|
|
55
|
-
"readme": "markdown-toc README.md -i --maxdepth=2 --bullets=-",
|
|
52
|
+
"test": "ava --no-worker-threads",
|
|
56
53
|
"release": "./bin/release-it.js"
|
|
57
54
|
},
|
|
58
55
|
"author": {
|
|
@@ -62,52 +59,49 @@
|
|
|
62
59
|
"license": "MIT",
|
|
63
60
|
"dependencies": {
|
|
64
61
|
"@iarna/toml": "2.2.5",
|
|
65
|
-
"@octokit/rest": "18.
|
|
66
|
-
"async-retry": "1.3.
|
|
67
|
-
"chalk": "
|
|
68
|
-
"cosmiconfig": "7.0.
|
|
69
|
-
"
|
|
70
|
-
"deprecated-obj": "2.0.0",
|
|
71
|
-
"execa": "5.1.1",
|
|
72
|
-
"find-up": "5.0.0",
|
|
62
|
+
"@octokit/rest": "18.12.0",
|
|
63
|
+
"async-retry": "1.3.3",
|
|
64
|
+
"chalk": "5.0.1",
|
|
65
|
+
"cosmiconfig": "7.0.1",
|
|
66
|
+
"execa": "6.1.0",
|
|
73
67
|
"form-data": "4.0.0",
|
|
74
|
-
"git-url-parse": "11.
|
|
75
|
-
"globby": "
|
|
76
|
-
"got": "
|
|
77
|
-
"inquirer": "8.
|
|
78
|
-
"is-ci": "3.0.
|
|
68
|
+
"git-url-parse": "11.6.0",
|
|
69
|
+
"globby": "13.1.1",
|
|
70
|
+
"got": "12.0.4",
|
|
71
|
+
"inquirer": "8.2.3",
|
|
72
|
+
"is-ci": "3.0.1",
|
|
79
73
|
"lodash": "4.17.21",
|
|
80
|
-
"mime-types": "2.1.
|
|
81
|
-
"
|
|
82
|
-
"
|
|
83
|
-
"
|
|
84
|
-
"
|
|
85
|
-
"
|
|
74
|
+
"mime-types": "2.1.35",
|
|
75
|
+
"new-github-release-url": "2.0.0",
|
|
76
|
+
"open": "8.4.0",
|
|
77
|
+
"ora": "6.1.0",
|
|
78
|
+
"os-name": "5.0.1",
|
|
79
|
+
"promise.allsettled": "1.0.5",
|
|
80
|
+
"proxy-agent": "5.0.0",
|
|
81
|
+
"semver": "7.3.7",
|
|
82
|
+
"shelljs": "0.8.5",
|
|
86
83
|
"update-notifier": "5.1.0",
|
|
87
|
-
"url-join": "
|
|
88
|
-
"
|
|
89
|
-
"
|
|
90
|
-
"yargs-parser": "20.2.9"
|
|
84
|
+
"url-join": "5.0.0",
|
|
85
|
+
"wildcard-match": "5.1.2",
|
|
86
|
+
"yargs-parser": "21.0.1"
|
|
91
87
|
},
|
|
92
88
|
"devDependencies": {
|
|
93
89
|
"@octokit/request-error": "2.1.0",
|
|
94
|
-
"ava": "
|
|
95
|
-
"
|
|
96
|
-
"eslint": "
|
|
97
|
-
"eslint-
|
|
98
|
-
"eslint-plugin-
|
|
99
|
-
"eslint-plugin-
|
|
100
|
-
"
|
|
101
|
-
"markdown-toc": "1.2.0",
|
|
102
|
-
"mock-fs": "5.0.0",
|
|
90
|
+
"ava": "4.2.0",
|
|
91
|
+
"eslint": "8.14.0",
|
|
92
|
+
"eslint-config-prettier": "8.5.0",
|
|
93
|
+
"eslint-plugin-ava": "13.2.0",
|
|
94
|
+
"eslint-plugin-import": "2.26.0",
|
|
95
|
+
"eslint-plugin-prettier": "4.0.0",
|
|
96
|
+
"mock-fs": "5.1.2",
|
|
103
97
|
"mock-stdio": "1.0.3",
|
|
104
|
-
"nock": "13.
|
|
98
|
+
"nock": "13.2.4",
|
|
105
99
|
"nyc": "15.1.0",
|
|
106
|
-
"prettier": "2.
|
|
107
|
-
"sinon": "
|
|
108
|
-
"strip-ansi": "
|
|
100
|
+
"prettier": "2.6.2",
|
|
101
|
+
"sinon": "13.0.2",
|
|
102
|
+
"strip-ansi": "7.0.1"
|
|
109
103
|
},
|
|
110
104
|
"engines": {
|
|
111
|
-
"node": "
|
|
105
|
+
"node": ">=14.9"
|
|
112
106
|
}
|
|
113
107
|
}
|
package/test/config.js
CHANGED
|
@@ -1,29 +1,30 @@
|
|
|
1
1
|
import test from 'ava';
|
|
2
|
-
import
|
|
2
|
+
import isCI from 'is-ci';
|
|
3
3
|
import Config from '../lib/config.js';
|
|
4
4
|
import { readJSON } from '../lib/util.js';
|
|
5
5
|
|
|
6
6
|
const defaultConfig = readJSON(new URL('../config/release-it.json', import.meta.url));
|
|
7
|
+
const projectConfig = readJSON(new URL('../.release-it.json', import.meta.url));
|
|
7
8
|
|
|
8
9
|
const localConfig = { github: { release: true } };
|
|
9
10
|
|
|
10
|
-
test
|
|
11
|
-
|
|
12
|
-
test('should contain default values', t => {
|
|
13
|
-
mock({ '../.release-it.json': JSON.stringify(localConfig) });
|
|
11
|
+
test("should read this project's own configuration", t => {
|
|
14
12
|
const config = new Config();
|
|
15
13
|
t.deepEqual(config.constructorConfig, {});
|
|
14
|
+
t.deepEqual(config.localConfig, projectConfig);
|
|
15
|
+
t.deepEqual(config.defaultConfig, defaultConfig);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
test('should contain default values', t => {
|
|
19
|
+
const config = new Config({ configDir: './test/stub/config/default' });
|
|
20
|
+
t.deepEqual(config.constructorConfig, { configDir: './test/stub/config/default' });
|
|
16
21
|
t.deepEqual(config.localConfig, localConfig);
|
|
17
22
|
t.deepEqual(config.defaultConfig, defaultConfig);
|
|
18
|
-
mock.restore();
|
|
19
23
|
});
|
|
20
24
|
|
|
21
25
|
test('should merge provided options', t => {
|
|
22
|
-
mock({
|
|
23
|
-
'package.json': JSON.stringify({ 'release-it': { git: { push: false } } }),
|
|
24
|
-
'../.release-it.json': JSON.stringify(localConfig)
|
|
25
|
-
});
|
|
26
26
|
const config = new Config({
|
|
27
|
+
configDir: './test/stub/config/merge',
|
|
27
28
|
increment: '1.0.0',
|
|
28
29
|
verbose: true,
|
|
29
30
|
github: {
|
|
@@ -36,7 +37,6 @@ test('should merge provided options', t => {
|
|
|
36
37
|
t.is(options.increment, '1.0.0');
|
|
37
38
|
t.is(options.git.push, false);
|
|
38
39
|
t.is(options.github.release, true);
|
|
39
|
-
mock.restore();
|
|
40
40
|
});
|
|
41
41
|
|
|
42
42
|
test('should set CI mode', t => {
|
|
@@ -44,8 +44,7 @@ test('should set CI mode', t => {
|
|
|
44
44
|
t.is(config.isCI, true);
|
|
45
45
|
});
|
|
46
46
|
|
|
47
|
-
test('should detect CI mode',
|
|
48
|
-
const { default: isCI } = await import('is-ci');
|
|
47
|
+
test('should detect CI mode', t => {
|
|
49
48
|
const config = new Config();
|
|
50
49
|
t.is(config.options.ci, isCI);
|
|
51
50
|
t.is(config.isCI, isCI);
|
|
@@ -57,24 +56,18 @@ test('should override --no-npm.publish', t => {
|
|
|
57
56
|
});
|
|
58
57
|
|
|
59
58
|
test('should read YAML config', t => {
|
|
60
|
-
|
|
61
|
-
const config = new Config({ config: '.release-it.yaml' });
|
|
59
|
+
const config = new Config({ configDir: './test/stub/config/yaml' });
|
|
62
60
|
t.deepEqual(config.options.foo, { bar: 1 });
|
|
63
|
-
mock.restore();
|
|
64
61
|
});
|
|
65
62
|
|
|
66
63
|
test('should read YML config', t => {
|
|
67
|
-
|
|
68
|
-
const config = new Config({ config: '.release-it.yml' });
|
|
64
|
+
const config = new Config({ configDir: './test/stub/config/yml' });
|
|
69
65
|
t.deepEqual(config.options.foo, { bar: 1 });
|
|
70
|
-
mock.restore();
|
|
71
66
|
});
|
|
72
67
|
|
|
73
68
|
test('should read TOML config', t => {
|
|
74
|
-
|
|
75
|
-
const config = new Config({ config: '.release-it.toml' });
|
|
69
|
+
const config = new Config({ configDir: './test/stub/config/toml' });
|
|
76
70
|
t.deepEqual(config.options.foo, { bar: 1 });
|
|
77
|
-
mock.restore();
|
|
78
71
|
});
|
|
79
72
|
|
|
80
73
|
test('should throw if provided config file is not found', t => {
|
|
@@ -82,15 +75,15 @@ test('should throw if provided config file is not found', t => {
|
|
|
82
75
|
});
|
|
83
76
|
|
|
84
77
|
test('should throw if provided config file is invalid (cosmiconfig exception)', t => {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
78
|
+
t.throws(() => new Config({ config: './test/stub/config/invalid-config-txt' }), {
|
|
79
|
+
message: /Invalid configuration file at/
|
|
80
|
+
});
|
|
88
81
|
});
|
|
89
82
|
|
|
90
83
|
test('should throw if provided config file is invalid (no object)', t => {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
84
|
+
t.throws(() => new Config({ config: './test/stub/config/invalid-config-rc' }), {
|
|
85
|
+
message: /Invalid configuration file at/
|
|
86
|
+
});
|
|
94
87
|
});
|
|
95
88
|
|
|
96
89
|
test('should not set default increment (for CI mode)', t => {
|
package/test/git.init.js
CHANGED
|
@@ -26,6 +26,19 @@ test.serial('should throw if on wrong branch', async t => {
|
|
|
26
26
|
await t.throwsAsync(gitClient.init(), { message: /^Must be on branch dev/ });
|
|
27
27
|
});
|
|
28
28
|
|
|
29
|
+
test.serial('should not throw if required branch matches', async t => {
|
|
30
|
+
const options = { git: { requireBranch: 'ma?*' } };
|
|
31
|
+
const gitClient = factory(Git, { options });
|
|
32
|
+
await t.notThrowsAsync(gitClient.init());
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test.serial('should not throw if one of required branch matches', async t => {
|
|
36
|
+
const options = { git: { requireBranch: ['release/*', 'hotfix/*'] } };
|
|
37
|
+
const gitClient = factory(Git, { options });
|
|
38
|
+
sh.exec('git checkout -b release/v1');
|
|
39
|
+
await t.notThrowsAsync(gitClient.init());
|
|
40
|
+
});
|
|
41
|
+
|
|
29
42
|
test.serial('should throw if there is no remote Git url', async t => {
|
|
30
43
|
const gitClient = factory(Git, { options: { git } });
|
|
31
44
|
sh.exec('git remote remove origin');
|
|
@@ -143,19 +156,13 @@ test.serial('should get the latest custom tag after fetch when tagName is config
|
|
|
143
156
|
test.serial('should get the latest tag based on tagMatch', async t => {
|
|
144
157
|
const shell = factory(Shell);
|
|
145
158
|
const gitClient = factory(Git, {
|
|
146
|
-
options: { git: { tagMatch: '[0-9][0-9]
|
|
159
|
+
options: { git: { tagMatch: '[0-9][0-9]\\.[0-1][0-9]\\.[0-9]*' } },
|
|
147
160
|
container: { shell }
|
|
148
161
|
});
|
|
149
|
-
const { bare, target } = t.context;
|
|
150
|
-
const other = mkTmpDir();
|
|
151
|
-
sh.exec('git push');
|
|
152
|
-
sh.exec(`git clone ${bare} ${other}`);
|
|
153
|
-
sh.pushd('-q', other);
|
|
154
162
|
sh.exec('git tag 1.0.0');
|
|
155
163
|
sh.exec('git tag 21.04.3');
|
|
156
164
|
sh.exec('git tag 1.0.1');
|
|
157
165
|
sh.exec('git push --tags');
|
|
158
|
-
sh.pushd('-q', target);
|
|
159
166
|
await gitClient.init();
|
|
160
167
|
t.is(gitClient.config.getContext('latestTag'), '21.04.3');
|
|
161
168
|
});
|
|
@@ -169,3 +176,21 @@ test.serial('should generate correct changelog', async t => {
|
|
|
169
176
|
const changelog = await gitClient.getChangelog();
|
|
170
177
|
t.regex(changelog, /\* Add file \(\w{7}\)\n\* Add file \(\w{7}\)/);
|
|
171
178
|
});
|
|
179
|
+
|
|
180
|
+
test.serial('should get the full changelog since latest major tag', async t => {
|
|
181
|
+
const shell = factory(Shell);
|
|
182
|
+
const gitClient = factory(Git, {
|
|
183
|
+
options: { git: { tagMatch: '[0-9]\\.[0-9]\\.[0-9]', changelog: git.changelog } },
|
|
184
|
+
container: { shell }
|
|
185
|
+
});
|
|
186
|
+
sh.exec('git tag 1.0.0');
|
|
187
|
+
gitAdd('line', 'file', 'Add file');
|
|
188
|
+
sh.exec('git tag 2.0.0-rc.0');
|
|
189
|
+
gitAdd('line', 'file', 'Add file');
|
|
190
|
+
sh.exec('git tag 2.0.0-rc.1');
|
|
191
|
+
gitAdd('line', 'file', 'Add file');
|
|
192
|
+
await gitClient.init();
|
|
193
|
+
t.is(gitClient.config.getContext('latestTag'), '1.0.0');
|
|
194
|
+
const changelog = await gitClient.getChangelog();
|
|
195
|
+
t.regex(changelog, /\* Add file \(\w{7}\)\n\* Add file \(\w{7}\)\n\* Add file \(\w{7}\)/);
|
|
196
|
+
});
|
package/test/git.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EOL } from 'os';
|
|
1
|
+
import { EOL } from 'node:os';
|
|
2
2
|
import test from 'ava';
|
|
3
3
|
import sinon from 'sinon';
|
|
4
4
|
import sh from 'shelljs';
|
|
@@ -228,7 +228,10 @@ test.serial('should push to remote name (not "origin")', async t => {
|
|
|
228
228
|
gitAdd('line', 'file', 'Add file');
|
|
229
229
|
await gitClient.push();
|
|
230
230
|
t.deepEqual(spy.lastCall.args[0], ['git', 'push', '--set-upstream', 'upstream', 'foo']);
|
|
231
|
-
t.regex(
|
|
231
|
+
t.regex(
|
|
232
|
+
await spy.lastCall.returnValue,
|
|
233
|
+
/branch .?foo.? set up to track (remote branch .?foo.? from .?upstream.?|.?upstream\/foo.?)/i
|
|
234
|
+
);
|
|
232
235
|
}
|
|
233
236
|
spy.restore();
|
|
234
237
|
});
|
package/test/github.js
CHANGED
|
@@ -15,18 +15,14 @@ import {
|
|
|
15
15
|
const tokenRef = 'GITHUB_TOKEN';
|
|
16
16
|
const pushRepo = 'git://github.com:user/repo';
|
|
17
17
|
const host = 'github.com';
|
|
18
|
-
const git = { changelog:
|
|
18
|
+
const git = { changelog: '' };
|
|
19
19
|
const requestErrorOptions = { request: { url: '', headers: {} }, response: { headers: {} } };
|
|
20
20
|
|
|
21
|
-
test.serial('should
|
|
21
|
+
test.serial('should check token and perform checks', async t => {
|
|
22
22
|
const tokenRef = 'MY_GITHUB_TOKEN';
|
|
23
23
|
const options = { github: { release: true, tokenRef, pushRepo } };
|
|
24
24
|
const github = factory(GitHub, { options });
|
|
25
|
-
delete process.env[tokenRef];
|
|
26
25
|
|
|
27
|
-
await t.throwsAsync(github.init(), {
|
|
28
|
-
message: /^Environment variable "MY_GITHUB_TOKEN" is required for GitHub releases/
|
|
29
|
-
});
|
|
30
26
|
process.env[tokenRef] = '123'; // eslint-disable-line require-atomic-updates
|
|
31
27
|
|
|
32
28
|
interceptAuthentication();
|
|
@@ -34,6 +30,18 @@ test.serial('should validate token', async t => {
|
|
|
34
30
|
await t.notThrowsAsync(github.init());
|
|
35
31
|
});
|
|
36
32
|
|
|
33
|
+
test.serial('should check token and warn', async t => {
|
|
34
|
+
const tokenRef = 'MY_GITHUB_TOKEN';
|
|
35
|
+
const options = { github: { release: true, tokenRef, pushRepo } };
|
|
36
|
+
const github = factory(GitHub, { options });
|
|
37
|
+
delete process.env[tokenRef];
|
|
38
|
+
|
|
39
|
+
await t.notThrowsAsync(github.init());
|
|
40
|
+
|
|
41
|
+
t.is(github.log.warn.args[0][0], 'Environment variable "MY_GITHUB_TOKEN" is required for automated GitHub Releases.');
|
|
42
|
+
t.is(github.log.warn.args[1][0], 'Falling back to web-based GitHub Release.');
|
|
43
|
+
});
|
|
44
|
+
|
|
37
45
|
test('should release and upload assets', async t => {
|
|
38
46
|
const options = {
|
|
39
47
|
git,
|
|
@@ -48,6 +56,7 @@ test('should release and upload assets', async t => {
|
|
|
48
56
|
};
|
|
49
57
|
const github = factory(GitHub, { options });
|
|
50
58
|
const exec = sinon.stub(github.shell, 'exec').callThrough();
|
|
59
|
+
exec.withArgs('git log --pretty=format:"* %s (%h)" ${from}...${to}').resolves('');
|
|
51
60
|
exec.withArgs('git describe --tags --match=* --abbrev=0').resolves('2.0.1');
|
|
52
61
|
|
|
53
62
|
interceptAuthentication();
|
|
@@ -77,11 +86,39 @@ test('should create a pre-release and draft release notes', async t => {
|
|
|
77
86
|
};
|
|
78
87
|
const github = factory(GitHub, { options });
|
|
79
88
|
const exec = sinon.stub(github.shell, 'exec').callThrough();
|
|
89
|
+
exec.withArgs('git log --pretty=format:"* %s (%h)" ${from}...${to}').resolves('');
|
|
90
|
+
exec.withArgs('git describe --tags --match=* --abbrev=0').resolves('2.0.1');
|
|
91
|
+
|
|
92
|
+
interceptAuthentication();
|
|
93
|
+
interceptCollaborator();
|
|
94
|
+
interceptCreate({ body: { tag_name: '2.0.2', name: 'Release 2.0.2', prerelease: true, draft: true } });
|
|
95
|
+
|
|
96
|
+
await runTasks(github);
|
|
97
|
+
|
|
98
|
+
const { isReleased, releaseUrl } = github.getContext();
|
|
99
|
+
t.true(isReleased);
|
|
100
|
+
t.is(releaseUrl, 'https://github.com/user/repo/releases/tag/2.0.2');
|
|
101
|
+
exec.restore();
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
test('should create auto-generated release notes', async t => {
|
|
105
|
+
const options = {
|
|
106
|
+
git,
|
|
107
|
+
github: {
|
|
108
|
+
pushRepo,
|
|
109
|
+
tokenRef,
|
|
110
|
+
release: true,
|
|
111
|
+
releaseName: 'Release ${tagName}',
|
|
112
|
+
autoGenerate: true
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
const github = factory(GitHub, { options });
|
|
116
|
+
const exec = sinon.stub(github.shell, 'exec').callThrough();
|
|
80
117
|
exec.withArgs('git describe --tags --match=* --abbrev=0').resolves('2.0.1');
|
|
81
118
|
|
|
82
119
|
interceptAuthentication();
|
|
83
120
|
interceptCollaborator();
|
|
84
|
-
interceptCreate({ body: { tag_name: '2.0.2', name: 'Release 2.0.2',
|
|
121
|
+
interceptCreate({ body: { tag_name: '2.0.2', name: 'Release 2.0.2', generate_release_notes: true, body: '' } });
|
|
85
122
|
|
|
86
123
|
await runTasks(github);
|
|
87
124
|
|
|
@@ -108,9 +145,10 @@ test('should update release and upload assets', async t => {
|
|
|
108
145
|
};
|
|
109
146
|
const github = factory(GitHub, { options });
|
|
110
147
|
const exec = sinon.stub(github.shell, 'exec').callThrough();
|
|
148
|
+
exec.withArgs('git log --pretty=format:"* %s (%h)" ${from}...${to}').resolves('');
|
|
111
149
|
exec.withArgs('git describe --tags --match=* --abbrev=0').resolves('2.0.1');
|
|
112
|
-
exec.withArgs('git rev-list 2.0.1 --tags --max-count=1').resolves('
|
|
113
|
-
exec.withArgs('git describe --tags --
|
|
150
|
+
exec.withArgs('git rev-list 2.0.1 --tags --max-count=1').resolves('a123456');
|
|
151
|
+
exec.withArgs('git describe --tags --abbrev=0 "a123456^"').resolves('2.0.1');
|
|
114
152
|
|
|
115
153
|
interceptAuthentication();
|
|
116
154
|
interceptCollaborator();
|
|
@@ -141,9 +179,10 @@ test('should create new release for unreleased tag', async t => {
|
|
|
141
179
|
};
|
|
142
180
|
const github = factory(GitHub, { options });
|
|
143
181
|
const exec = sinon.stub(github.shell, 'exec').callThrough();
|
|
182
|
+
exec.withArgs('git log --pretty=format:"* %s (%h)" ${from}...${to}').resolves('');
|
|
144
183
|
exec.withArgs('git describe --tags --match=* --abbrev=0').resolves('2.0.1');
|
|
145
|
-
exec.withArgs('git rev-list 2.0.1 --tags --max-count=1').resolves('
|
|
146
|
-
exec.withArgs('git describe --tags --
|
|
184
|
+
exec.withArgs('git rev-list 2.0.1 --tags --max-count=1').resolves('b123456');
|
|
185
|
+
exec.withArgs('git describe --tags --abbrev=0 "b123456^"').resolves('2.0.1');
|
|
147
186
|
|
|
148
187
|
interceptAuthentication();
|
|
149
188
|
interceptCollaborator();
|
|
@@ -179,7 +218,7 @@ test('should release to enterprise host', async t => {
|
|
|
179
218
|
});
|
|
180
219
|
|
|
181
220
|
test('should release to alternative host and proxy', async t => {
|
|
182
|
-
const remote = { api: 'https://
|
|
221
|
+
const remote = { api: 'https://custom.example.org/api/v3', host: 'custom.example.org' };
|
|
183
222
|
interceptAuthentication(remote);
|
|
184
223
|
interceptCollaborator(remote);
|
|
185
224
|
interceptCreate(Object.assign({ body: { tag_name: '1.0.1' } }, remote));
|
|
@@ -187,37 +226,40 @@ test('should release to alternative host and proxy', async t => {
|
|
|
187
226
|
git,
|
|
188
227
|
github: {
|
|
189
228
|
tokenRef,
|
|
190
|
-
pushRepo: `git://
|
|
191
|
-
host: '
|
|
229
|
+
pushRepo: `git://custom.example.org:user/repo`,
|
|
230
|
+
host: 'custom.example.org',
|
|
192
231
|
proxy: 'http://proxy:8080'
|
|
193
232
|
}
|
|
194
233
|
};
|
|
195
234
|
const github = factory(GitHub, { options });
|
|
196
235
|
const exec = sinon.stub(github.shell, 'exec').callThrough();
|
|
236
|
+
exec.withArgs('git log --pretty=format:"* %s (%h)" ${from}...${to}').resolves('');
|
|
197
237
|
exec.withArgs('git describe --tags --match=* --abbrev=0').resolves('1.0.0');
|
|
198
238
|
|
|
199
239
|
await runTasks(github);
|
|
200
240
|
|
|
201
241
|
const { isReleased, releaseUrl } = github.getContext();
|
|
202
242
|
t.true(isReleased);
|
|
203
|
-
t.is(releaseUrl, `https://
|
|
243
|
+
t.is(releaseUrl, `https://custom.example.org/user/repo/releases/tag/1.0.1`);
|
|
244
|
+
t.is(github.options.proxy, 'http://proxy:8080');
|
|
204
245
|
exec.restore();
|
|
205
246
|
});
|
|
206
247
|
|
|
207
248
|
test('should release to git.pushRepo', async t => {
|
|
208
|
-
const remote = { api: 'https://
|
|
249
|
+
const remote = { api: 'https://custom.example.org/api/v3', host: 'custom.example.org' };
|
|
209
250
|
interceptCreate(Object.assign({ body: { tag_name: '1.0.1' } }, remote));
|
|
210
|
-
const options = { git: { pushRepo: 'upstream', changelog:
|
|
251
|
+
const options = { git: { pushRepo: 'upstream', changelog: '' }, github: { tokenRef, skipChecks: true } };
|
|
211
252
|
const github = factory(GitHub, { options });
|
|
212
253
|
const exec = sinon.stub(github.shell, 'exec').callThrough();
|
|
254
|
+
exec.withArgs('git log --pretty=format:"* %s (%h)" ${from}...${to}').resolves('');
|
|
213
255
|
exec.withArgs('git describe --tags --match=* --abbrev=0').resolves('1.0.0');
|
|
214
|
-
exec.withArgs('git remote get-url upstream').resolves('https://
|
|
256
|
+
exec.withArgs('git remote get-url upstream').resolves('https://custom.example.org/user/repo');
|
|
215
257
|
|
|
216
258
|
await runTasks(github);
|
|
217
259
|
|
|
218
260
|
const { isReleased, releaseUrl } = github.getContext();
|
|
219
261
|
t.true(isReleased);
|
|
220
|
-
t.is(releaseUrl, 'https://
|
|
262
|
+
t.is(releaseUrl, 'https://custom.example.org/user/repo/releases/tag/1.0.1');
|
|
221
263
|
exec.restore();
|
|
222
264
|
});
|
|
223
265
|
|
|
@@ -308,6 +350,7 @@ test('should not call octokit client in dry run', async t => {
|
|
|
308
350
|
const github = factory(GitHub, { options });
|
|
309
351
|
const spy = sinon.spy(github, 'client', ['get']);
|
|
310
352
|
const exec = sinon.stub(github.shell, 'exec').callThrough();
|
|
353
|
+
exec.withArgs('git log --pretty=format:"* %s (%h)" ${from}...${to}').resolves('');
|
|
311
354
|
exec.withArgs('git describe --tags --match=* --abbrev=0').resolves('v1.0.0');
|
|
312
355
|
|
|
313
356
|
await runTasks(github);
|
|
@@ -327,3 +370,57 @@ test('should skip checks', async t => {
|
|
|
327
370
|
const github = factory(GitHub, { options });
|
|
328
371
|
await t.notThrowsAsync(github.init());
|
|
329
372
|
});
|
|
373
|
+
|
|
374
|
+
test('should generate GitHub web release url', async t => {
|
|
375
|
+
const options = {
|
|
376
|
+
github: {
|
|
377
|
+
pushRepo,
|
|
378
|
+
release: true,
|
|
379
|
+
web: true,
|
|
380
|
+
releaseName: 'Release ${tagName}',
|
|
381
|
+
releaseNotes: 'echo Custom notes'
|
|
382
|
+
}
|
|
383
|
+
};
|
|
384
|
+
const github = factory(GitHub, { options });
|
|
385
|
+
const exec = sinon.stub(github.shell, 'exec').callThrough();
|
|
386
|
+
exec.withArgs('git log --pretty=format:"* %s (%h)" ${from}...${to}').resolves('');
|
|
387
|
+
exec.withArgs('git describe --tags --match=* --abbrev=0').resolves('2.0.1');
|
|
388
|
+
|
|
389
|
+
await runTasks(github);
|
|
390
|
+
|
|
391
|
+
const { isReleased, releaseUrl } = github.getContext();
|
|
392
|
+
t.true(isReleased);
|
|
393
|
+
t.is(
|
|
394
|
+
releaseUrl,
|
|
395
|
+
'https://github.com/user/repo/releases/new?tag=2.0.2&title=Release+2.0.2&body=Custom+notes&prerelease=false'
|
|
396
|
+
);
|
|
397
|
+
exec.restore();
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
test('should generate GitHub web release url for enterprise host', async t => {
|
|
401
|
+
const options = {
|
|
402
|
+
git,
|
|
403
|
+
github: {
|
|
404
|
+
pushRepo: 'git://custom.example.org:user/repo',
|
|
405
|
+
release: true,
|
|
406
|
+
web: true,
|
|
407
|
+
host: 'custom.example.org',
|
|
408
|
+
releaseName: 'The Launch',
|
|
409
|
+
releaseNotes: 'echo It happened'
|
|
410
|
+
}
|
|
411
|
+
};
|
|
412
|
+
const github = factory(GitHub, { options });
|
|
413
|
+
const exec = sinon.stub(github.shell, 'exec').callThrough();
|
|
414
|
+
exec.withArgs('git log --pretty=format:"* %s (%h)" ${from}...${to}').resolves('');
|
|
415
|
+
exec.withArgs('git describe --tags --match=* --abbrev=0').resolves('2.0.1');
|
|
416
|
+
|
|
417
|
+
await runTasks(github);
|
|
418
|
+
|
|
419
|
+
const { isReleased, releaseUrl } = github.getContext();
|
|
420
|
+
t.true(isReleased);
|
|
421
|
+
t.is(
|
|
422
|
+
releaseUrl,
|
|
423
|
+
'https://custom.example.org/user/repo/releases/new?tag=2.0.2&title=The+Launch&body=It+happened&prerelease=false'
|
|
424
|
+
);
|
|
425
|
+
exec.restore();
|
|
426
|
+
});
|