release-it 19.2.4 → 20.0.0-1
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 +12 -11
- package/lib/log.js +1 -1
- package/lib/plugin/factory.js +1 -1
- package/lib/plugin/git/Git.js +7 -0
- package/lib/plugin/github/GitHub.js +1 -1
- package/lib/plugin/npm/npm.js +22 -12
- package/lib/prompt.js +18 -11
- package/package.json +22 -22
- package/test/git.js +33 -0
- package/test/log.js +8 -0
- package/test/npm.js +17 -11
- package/test/prompt.js +20 -28
- package/test/tasks.interactive.js +14 -14
- package/test/tasks.js +1 -1
package/README.md
CHANGED
|
@@ -44,7 +44,7 @@ npm install -D release-it
|
|
|
44
44
|
"release": "release-it"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"release-it": "^
|
|
47
|
+
"release-it": "^20.0.0"
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
```
|
|
@@ -99,7 +99,7 @@ Here's a quick example `.release-it.json`:
|
|
|
99
99
|
|
|
100
100
|
```json
|
|
101
101
|
{
|
|
102
|
-
"$schema": "https://unpkg.com/release-it@
|
|
102
|
+
"$schema": "https://unpkg.com/release-it@20/schema/release-it.json",
|
|
103
103
|
"git": {
|
|
104
104
|
"commitMessage": "chore: release v${version}"
|
|
105
105
|
},
|
|
@@ -280,7 +280,7 @@ Note that arguments need to be quoted properly when used from the command line:
|
|
|
280
280
|
release-it --'hooks.after:release="echo Successfully released ${name} v${version} to ${repo.repository}."'
|
|
281
281
|
```
|
|
282
282
|
|
|
283
|
-
Using
|
|
283
|
+
Using @inquirer/prompts inside custom hook scripts might cause issues (since release-it also uses this itself).
|
|
284
284
|
|
|
285
285
|
## Dry Runs
|
|
286
286
|
|
|
@@ -353,15 +353,16 @@ release-it programmatically][58] for example code.
|
|
|
353
353
|
|
|
354
354
|
## Node.js version support
|
|
355
355
|
|
|
356
|
-
The latest major version is
|
|
356
|
+
The latest major version is v20, supporting Node.js 20 and up:
|
|
357
357
|
|
|
358
|
-
| release-it | Node.js
|
|
359
|
-
| :--------: |
|
|
360
|
-
|
|
|
361
|
-
|
|
|
362
|
-
|
|
|
363
|
-
|
|
|
364
|
-
|
|
|
358
|
+
| release-it | Node.js |
|
|
359
|
+
| :--------: | :------- |
|
|
360
|
+
| v20 | v20.19.0 |
|
|
361
|
+
| v19 | v20.12.0 |
|
|
362
|
+
| v18 | v20 |
|
|
363
|
+
| v17 | v18 |
|
|
364
|
+
| v16 | v16 |
|
|
365
|
+
| v15 | v14 |
|
|
365
366
|
|
|
366
367
|
Also see [CHANGELOG.md][80] for dates and details.
|
|
367
368
|
|
package/lib/log.js
CHANGED
package/lib/plugin/factory.js
CHANGED
package/lib/plugin/git/Git.js
CHANGED
|
@@ -209,6 +209,13 @@ class Git extends GitBase {
|
|
|
209
209
|
this.disableRollback();
|
|
210
210
|
return push;
|
|
211
211
|
} catch (error) {
|
|
212
|
+
if (this.config.getContext('isReleased')) {
|
|
213
|
+
this.disableRollback();
|
|
214
|
+
this.log.error(error.message || error);
|
|
215
|
+
this.log.warn('The package might have been released, but git push failed.');
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
|
|
212
219
|
try {
|
|
213
220
|
await this.rollbackTagPush();
|
|
214
221
|
} catch (tagError) {
|
|
@@ -453,7 +453,7 @@ class GitHub extends Release {
|
|
|
453
453
|
const { commit: template, excludeMatches = [] } = releaseNotes;
|
|
454
454
|
const commits = await this.getCommits();
|
|
455
455
|
|
|
456
|
-
if (this.options.commit) commits.pop();
|
|
456
|
+
if (this.options.commit || !this.config.isIncrement) commits.pop();
|
|
457
457
|
|
|
458
458
|
return commits
|
|
459
459
|
.map(commit => {
|
package/lib/plugin/npm/npm.js
CHANGED
|
@@ -187,21 +187,25 @@ class npm extends Plugin {
|
|
|
187
187
|
return this.exec(`npm show ${name}@${tag} version${registryArg}`, { options: getOptions() }).catch(() => null);
|
|
188
188
|
}
|
|
189
189
|
|
|
190
|
-
|
|
190
|
+
getRegistryDistTags() {
|
|
191
191
|
return this.exec(`npm view ${this.getName()} dist-tags --json`, { options: getOptions() }).then(
|
|
192
192
|
output => {
|
|
193
193
|
try {
|
|
194
|
-
|
|
195
|
-
return Object.keys(tags).filter(tag => tag !== DEFAULT_TAG);
|
|
194
|
+
return JSON.parse(output);
|
|
196
195
|
} catch (err) {
|
|
197
196
|
this.debug(err);
|
|
198
|
-
return
|
|
197
|
+
return {};
|
|
199
198
|
}
|
|
200
199
|
},
|
|
201
|
-
() =>
|
|
200
|
+
() => ({})
|
|
202
201
|
);
|
|
203
202
|
}
|
|
204
203
|
|
|
204
|
+
async getRegistryPreReleaseTags() {
|
|
205
|
+
const tags = await this.getRegistryDistTags();
|
|
206
|
+
return Object.keys(tags).filter(tag => tag !== DEFAULT_TAG);
|
|
207
|
+
}
|
|
208
|
+
|
|
205
209
|
getPackageUrl() {
|
|
206
210
|
const baseUrl = this.getRegistry() || NPM_BASE_URL;
|
|
207
211
|
const publicPath = this.getPublicPath() || NPM_PUBLIC_PATH;
|
|
@@ -226,13 +230,18 @@ class npm extends Plugin {
|
|
|
226
230
|
}
|
|
227
231
|
|
|
228
232
|
async guessPreReleaseTag() {
|
|
229
|
-
const
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
233
|
+
const distTags = await this.getRegistryDistTags();
|
|
234
|
+
const latestVersion = this.getLatestVersion();
|
|
235
|
+
const match = Object.entries(distTags).find(
|
|
236
|
+
([tag, version]) => tag !== DEFAULT_TAG && version === latestVersion
|
|
237
|
+
);
|
|
238
|
+
if (match) return match[0];
|
|
239
|
+
|
|
240
|
+
const [tag] = Object.keys(distTags).filter(tag => tag !== DEFAULT_TAG);
|
|
241
|
+
if (tag) return tag;
|
|
242
|
+
|
|
243
|
+
this.log.warn(`Unable to get pre-release tag(s) from npm registry. Using "${DEFAULT_TAG_PRERELEASE}".`);
|
|
244
|
+
return DEFAULT_TAG_PRERELEASE;
|
|
236
245
|
}
|
|
237
246
|
|
|
238
247
|
async resolveTag(version) {
|
|
@@ -273,6 +282,7 @@ class npm extends Plugin {
|
|
|
273
282
|
})
|
|
274
283
|
.then(() => {
|
|
275
284
|
this.setContext({ isReleased: true });
|
|
285
|
+
this.config.setContext({ isReleased: true });
|
|
276
286
|
})
|
|
277
287
|
.catch(err => {
|
|
278
288
|
this.debug(err);
|
package/lib/prompt.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { confirm, input, select } from '@inquirer/prompts';
|
|
2
|
+
|
|
3
|
+
const types = { confirm, input, list: select };
|
|
2
4
|
|
|
3
5
|
class Prompt {
|
|
4
6
|
constructor({ container }) {
|
|
5
|
-
this.createPrompt =
|
|
7
|
+
this.createPrompt = container.createPrompt;
|
|
6
8
|
this.prompts = {};
|
|
7
9
|
}
|
|
8
10
|
|
|
@@ -15,18 +17,23 @@ class Prompt {
|
|
|
15
17
|
if (!enabled) return false;
|
|
16
18
|
|
|
17
19
|
const prompt = this.prompts[namespace][promptName];
|
|
18
|
-
const options =
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
const options = {
|
|
21
|
+
message: prompt.message(context)
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
if ('default' in prompt) options.default = prompt.default;
|
|
25
|
+
if ('choices' in prompt) options.choices = prompt.choices(context);
|
|
26
|
+
if ('transformer' in prompt) options.transformer = prompt.transformer(context);
|
|
27
|
+
if ('validate' in prompt) options.validate = prompt.validate;
|
|
28
|
+
if ('pageSize' in prompt) options.pageSize = prompt.pageSize;
|
|
24
29
|
|
|
25
|
-
const
|
|
30
|
+
const answer = await (this.createPrompt
|
|
31
|
+
? this.createPrompt(prompt.type, options)
|
|
32
|
+
: types[prompt.type](options));
|
|
26
33
|
|
|
27
|
-
const doExecute = prompt.type === 'confirm' ?
|
|
34
|
+
const doExecute = prompt.type === 'confirm' ? answer : true;
|
|
28
35
|
|
|
29
|
-
return doExecute && task ? await task(
|
|
36
|
+
return doExecute && task ? await task(answer) : false;
|
|
30
37
|
}
|
|
31
38
|
}
|
|
32
39
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "release-it",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "20.0.0-1",
|
|
4
4
|
"description": "Generic CLI tool to automate versioning and package publishing-related tasks.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"build",
|
|
@@ -78,46 +78,46 @@
|
|
|
78
78
|
},
|
|
79
79
|
"license": "MIT",
|
|
80
80
|
"dependencies": {
|
|
81
|
+
"@inquirer/prompts": "8.3.2",
|
|
81
82
|
"@nodeutils/defaults-deep": "1.1.0",
|
|
82
83
|
"@octokit/rest": "22.0.1",
|
|
83
84
|
"@phun-ky/typeof": "2.0.3",
|
|
84
85
|
"async-retry": "1.3.3",
|
|
85
86
|
"c12": "3.3.3",
|
|
86
|
-
"ci-info": "^4.
|
|
87
|
-
"eta": "4.5.
|
|
87
|
+
"ci-info": "^4.4.0",
|
|
88
|
+
"eta": "4.5.1",
|
|
88
89
|
"git-url-parse": "16.1.0",
|
|
89
|
-
"inquirer": "12.11.1",
|
|
90
90
|
"issue-parser": "7.0.1",
|
|
91
91
|
"lodash.merge": "4.6.2",
|
|
92
92
|
"mime-types": "3.0.2",
|
|
93
93
|
"new-github-release-url": "2.0.0",
|
|
94
|
-
"open": "
|
|
95
|
-
"ora": "9.
|
|
96
|
-
"os-name": "
|
|
97
|
-
"proxy-agent": "
|
|
98
|
-
"semver": "7.7.
|
|
94
|
+
"open": "11.0.0",
|
|
95
|
+
"ora": "9.3.0",
|
|
96
|
+
"os-name": "7.0.0",
|
|
97
|
+
"proxy-agent": "7.0.0",
|
|
98
|
+
"semver": "7.7.4",
|
|
99
99
|
"tinyglobby": "0.2.15",
|
|
100
|
-
"undici": "
|
|
100
|
+
"undici": "7.24.5",
|
|
101
101
|
"url-join": "5.0.0",
|
|
102
102
|
"wildcard-match": "5.1.4",
|
|
103
|
-
"yargs-parser": "
|
|
103
|
+
"yargs-parser": "22.0.0"
|
|
104
104
|
},
|
|
105
105
|
"devDependencies": {
|
|
106
|
-
"@eslint/js": "
|
|
106
|
+
"@eslint/js": "10.0.1",
|
|
107
107
|
"@octokit/request-error": "7.1.0",
|
|
108
108
|
"@types/node": "24.10.9",
|
|
109
|
-
"eslint": "
|
|
110
|
-
"eslint-plugin-import-x": "4.16.
|
|
111
|
-
"globals": "
|
|
112
|
-
"installed-check": "
|
|
113
|
-
"knip": "
|
|
109
|
+
"eslint": "10.1.0",
|
|
110
|
+
"eslint-plugin-import-x": "4.16.2",
|
|
111
|
+
"globals": "17.4.0",
|
|
112
|
+
"installed-check": "10.0.1",
|
|
113
|
+
"knip": "6.0.5",
|
|
114
114
|
"mentoss": "0.13.0",
|
|
115
115
|
"mock-stdio": "1.0.3",
|
|
116
|
-
"prettier": "3.8.
|
|
116
|
+
"prettier": "3.8.1",
|
|
117
117
|
"remark-cli": "12.0.1",
|
|
118
|
-
"remark-preset-webpro": "2.1.
|
|
119
|
-
"tar": "7.5.
|
|
120
|
-
"typescript": "
|
|
118
|
+
"remark-preset-webpro": "2.1.1",
|
|
119
|
+
"tar": "7.5.13",
|
|
120
|
+
"typescript": "6.0.2"
|
|
121
121
|
},
|
|
122
122
|
"overrides": {
|
|
123
123
|
"pac-resolver": "7.0.1",
|
|
@@ -125,7 +125,7 @@
|
|
|
125
125
|
"glob": "13.0.0"
|
|
126
126
|
},
|
|
127
127
|
"engines": {
|
|
128
|
-
"node": "^20.
|
|
128
|
+
"node": "^20.19.0 || ^22.13.0 || >=24.0.0"
|
|
129
129
|
},
|
|
130
130
|
"remarkConfig": {
|
|
131
131
|
"plugins": [
|
package/test/git.js
CHANGED
|
@@ -348,6 +348,39 @@ describe('git', () => {
|
|
|
348
348
|
assert.equal(exec.mock.calls[15].arguments[0], 'git push origin --delete v1.2.4');
|
|
349
349
|
});
|
|
350
350
|
|
|
351
|
+
test('should skip rollback when push fails but package is already published', async t => {
|
|
352
|
+
childProcess.execSync('git init', execOpts);
|
|
353
|
+
childProcess.execSync(`git remote add origin file://foo`, execOpts);
|
|
354
|
+
sh.exec(`git remote update`, execOpts);
|
|
355
|
+
const version = '1.2.3';
|
|
356
|
+
gitAdd(`{"version":"${version}"}`, 'package.json', 'Add package.json');
|
|
357
|
+
const options = { git: { requireCleanWorkingDir: true, commit: true, tag: true, tagName: 'v${version}' } };
|
|
358
|
+
const gitClient = await factory(Git, { options });
|
|
359
|
+
const exec = t.mock.method(gitClient.shell, 'execFormattedCommand');
|
|
360
|
+
const warn = t.mock.method(gitClient.log, 'warn');
|
|
361
|
+
sh.exec(`git push`, execOpts);
|
|
362
|
+
sh.exec(`git checkout HEAD~1`, execOpts);
|
|
363
|
+
gitAdd('line', 'file', 'Add file');
|
|
364
|
+
|
|
365
|
+
await gitClient.init();
|
|
366
|
+
|
|
367
|
+
childProcess.execSync('npm --no-git-tag-version version patch', execOpts);
|
|
368
|
+
|
|
369
|
+
gitClient.bump('1.2.4');
|
|
370
|
+
await gitClient.beforeRelease();
|
|
371
|
+
await gitClient.stage('package.json');
|
|
372
|
+
await gitClient.commit({ message: 'Add this' });
|
|
373
|
+
await gitClient.tag();
|
|
374
|
+
|
|
375
|
+
gitClient.config.setContext({ isReleased: true });
|
|
376
|
+
|
|
377
|
+
await gitClient.push();
|
|
378
|
+
|
|
379
|
+
const execCalls = exec.mock.calls.map(c => c.arguments[0]);
|
|
380
|
+
assert.equal(execCalls.includes('git push origin --delete v1.2.4'), false);
|
|
381
|
+
assert(warn.mock.calls.some(c => /git push failed/.test(c.arguments[0])));
|
|
382
|
+
});
|
|
383
|
+
|
|
351
384
|
test('should not touch existing history when rolling back', async t => {
|
|
352
385
|
childProcess.execSync('git init', execOpts);
|
|
353
386
|
const version = '1.2.3';
|
package/test/log.js
CHANGED
|
@@ -24,6 +24,14 @@ describe('log', () => {
|
|
|
24
24
|
assert.equal(stripVTControlCharacters(stderr), 'ERROR foo\n');
|
|
25
25
|
});
|
|
26
26
|
|
|
27
|
+
test('should print info', () => {
|
|
28
|
+
const log = new Log();
|
|
29
|
+
mockStdIo.start();
|
|
30
|
+
log.info('foo');
|
|
31
|
+
const { stderr } = mockStdIo.end();
|
|
32
|
+
assert.equal(stripVTControlCharacters(stderr), 'foo\n');
|
|
33
|
+
});
|
|
34
|
+
|
|
27
35
|
test('should print a warning', () => {
|
|
28
36
|
const log = new Log();
|
|
29
37
|
mockStdIo.start();
|
package/test/npm.js
CHANGED
|
@@ -44,14 +44,22 @@ describe('npm', async () => {
|
|
|
44
44
|
|
|
45
45
|
test('should resolve default tag for pre-release', async t => {
|
|
46
46
|
const npmClient = await factory(npm);
|
|
47
|
-
t.mock.method(npmClient, '
|
|
47
|
+
t.mock.method(npmClient, 'getRegistryDistTags', () => ({}));
|
|
48
48
|
const tag = await npmClient.resolveTag('1.0.0-0');
|
|
49
49
|
assert.equal(tag, 'next');
|
|
50
50
|
});
|
|
51
51
|
|
|
52
|
-
test('should guess tag from registry for pre-release', async t => {
|
|
52
|
+
test('should guess tag from registry for pre-release matching current version', async t => {
|
|
53
53
|
const npmClient = await factory(npm);
|
|
54
|
-
|
|
54
|
+
npmClient.setContext({ latestVersion: '1.0.0-0' });
|
|
55
|
+
t.mock.method(npmClient, 'getRegistryDistTags', () => ({ latest: '0.9.0', alpha: '1.0.0-alpha.1', next: '1.0.0-0' }));
|
|
56
|
+
const tag = await npmClient.resolveTag('1.0.0-1');
|
|
57
|
+
assert.equal(tag, 'next');
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test('should guess first pre-release tag from registry when no version match', async t => {
|
|
61
|
+
const npmClient = await factory(npm);
|
|
62
|
+
t.mock.method(npmClient, 'getRegistryDistTags', () => ({ latest: '0.9.0', alpha: '1.0.0-alpha.1' }));
|
|
55
63
|
const tag = await npmClient.resolveTag('1.0.0-0');
|
|
56
64
|
assert.equal(tag, 'alpha');
|
|
57
65
|
});
|
|
@@ -112,17 +120,15 @@ describe('npm', async () => {
|
|
|
112
120
|
const exec = t.mock.method(npmClient.shell, 'exec', command => {
|
|
113
121
|
if (command === 'npm whoami --registry registry.example.org') return Promise.resolve('john');
|
|
114
122
|
const re = /npm access (list collaborators --json|ls-collaborators) release-it --registry registry.example.org/;
|
|
115
|
-
if (re.test
|
|
123
|
+
if (re.test(command)) return Promise.resolve(JSON.stringify({ john: ['write'] }));
|
|
116
124
|
return Promise.resolve();
|
|
117
125
|
});
|
|
118
126
|
|
|
119
127
|
await runTasks(npmClient);
|
|
120
|
-
|
|
121
|
-
assert.
|
|
122
|
-
assert.
|
|
123
|
-
|
|
124
|
-
/npm show release-it@[a-z]+ version --registry registry\.example\.org/
|
|
125
|
-
);
|
|
128
|
+
const commands = exec.mock.calls.map(c => c.arguments[0]);
|
|
129
|
+
assert(commands.includes('npm ping --registry registry.example.org'));
|
|
130
|
+
assert(commands.includes('npm whoami --registry registry.example.org'));
|
|
131
|
+
assert(commands.some(c => /npm show release-it@[a-z]+ version --registry registry\.example\.org/.test(c)));
|
|
126
132
|
});
|
|
127
133
|
|
|
128
134
|
test('should not throw when executing tasks', async t => {
|
|
@@ -130,7 +136,7 @@ describe('npm', async () => {
|
|
|
130
136
|
t.mock.method(npmClient.shell, 'exec', command => {
|
|
131
137
|
if (command === 'npm whoami') return Promise.resolve('john');
|
|
132
138
|
const re = /npm access (list collaborators --json|ls-collaborators) release-it/;
|
|
133
|
-
if (re.test
|
|
139
|
+
if (re.test(command)) return Promise.resolve(JSON.stringify({ john: ['write'] }));
|
|
134
140
|
return Promise.resolve();
|
|
135
141
|
});
|
|
136
142
|
await assert.doesNotReject(runTasks(npmClient));
|
package/test/prompt.js
CHANGED
|
@@ -10,33 +10,28 @@ import { factory } from './util/index.js';
|
|
|
10
10
|
|
|
11
11
|
const prompts = { git, github, gitlab, npm };
|
|
12
12
|
|
|
13
|
-
const yes = (
|
|
14
|
-
const no = (
|
|
13
|
+
const yes = () => Promise.resolve(true);
|
|
14
|
+
const no = () => Promise.resolve(false);
|
|
15
15
|
|
|
16
16
|
test('should not create prompt if disabled', async t => {
|
|
17
17
|
const task = t.mock.fn();
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
const prompt = await factory(Prompt, { container: { inquirer } });
|
|
18
|
+
const createPrompt = t.mock.fn(yes);
|
|
19
|
+
const prompt = await factory(Prompt, { container: { createPrompt } });
|
|
21
20
|
prompt.register(prompts.git);
|
|
22
21
|
await prompt.show({ enabled: false, prompt: 'push', task });
|
|
23
|
-
assert.equal(
|
|
22
|
+
assert.equal(createPrompt.mock.callCount(), 0);
|
|
24
23
|
assert.equal(task.mock.callCount(), 0);
|
|
25
24
|
});
|
|
26
25
|
|
|
27
26
|
test('should create prompt', async t => {
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
const prompt = await factory(Prompt, { container: { inquirer } });
|
|
27
|
+
const createPrompt = t.mock.fn(yes);
|
|
28
|
+
const prompt = await factory(Prompt, { container: { createPrompt } });
|
|
31
29
|
prompt.register(prompts.git);
|
|
32
30
|
await prompt.show({ prompt: 'push' });
|
|
33
|
-
assert.equal(
|
|
34
|
-
assert.
|
|
35
|
-
|
|
31
|
+
assert.equal(createPrompt.mock.callCount(), 1);
|
|
32
|
+
assert.equal(createPrompt.mock.calls[0].arguments[0], 'confirm');
|
|
33
|
+
assert.deepEqual(createPrompt.mock.calls[0].arguments[1], {
|
|
36
34
|
message: 'Push?',
|
|
37
|
-
name: 'push',
|
|
38
|
-
choices: false,
|
|
39
|
-
transformer: undefined,
|
|
40
35
|
default: true
|
|
41
36
|
});
|
|
42
37
|
});
|
|
@@ -51,7 +46,7 @@ test('should create prompt', async t => {
|
|
|
51
46
|
['npm', 'otp', 'Please enter OTP for npm:']
|
|
52
47
|
].map(async ([namespace, prompt, message]) => {
|
|
53
48
|
test(`should create prompt and render template message (${namespace}.${prompt})`, async t => {
|
|
54
|
-
const
|
|
49
|
+
const createPrompt = t.mock.fn(yes);
|
|
55
50
|
const config = new Config({
|
|
56
51
|
isPreRelease: true,
|
|
57
52
|
git: { tagName: 'v${version}' },
|
|
@@ -59,34 +54,31 @@ test('should create prompt', async t => {
|
|
|
59
54
|
});
|
|
60
55
|
await config.init();
|
|
61
56
|
config.setContext({ version: '1.0.0', tagName: '1.0.0' });
|
|
62
|
-
const
|
|
63
|
-
const p = await factory(Prompt, { container: { inquirer } });
|
|
57
|
+
const p = await factory(Prompt, { container: { createPrompt } });
|
|
64
58
|
p.register(prompts[namespace], namespace);
|
|
65
59
|
await p.show({ namespace, prompt, context: config.getContext() });
|
|
66
|
-
assert.equal(
|
|
67
|
-
assert.equal(
|
|
60
|
+
assert.equal(createPrompt.mock.callCount(), 1);
|
|
61
|
+
assert.equal(createPrompt.mock.calls[0].arguments[1].message, message);
|
|
68
62
|
});
|
|
69
63
|
});
|
|
70
64
|
|
|
71
65
|
test('should execute task after positive answer', async t => {
|
|
72
66
|
const task = t.mock.fn();
|
|
73
|
-
const
|
|
74
|
-
const
|
|
75
|
-
const prompt = await factory(Prompt, { container: { inquirer } });
|
|
67
|
+
const createPrompt = t.mock.fn(yes);
|
|
68
|
+
const prompt = await factory(Prompt, { container: { createPrompt } });
|
|
76
69
|
prompt.register(prompts.git);
|
|
77
70
|
await prompt.show({ prompt: 'push', task });
|
|
78
|
-
assert.equal(
|
|
71
|
+
assert.equal(createPrompt.mock.callCount(), 1);
|
|
79
72
|
assert.equal(task.mock.callCount(), 1);
|
|
80
73
|
assert.equal(task.mock.calls[0].arguments[0], true);
|
|
81
74
|
});
|
|
82
75
|
|
|
83
76
|
test('should not execute task after negative answer', async t => {
|
|
84
77
|
const task = t.mock.fn();
|
|
85
|
-
const
|
|
86
|
-
const
|
|
87
|
-
const prompt = await factory(Prompt, { container: { inquirer } });
|
|
78
|
+
const createPrompt = t.mock.fn(no);
|
|
79
|
+
const prompt = await factory(Prompt, { container: { createPrompt } });
|
|
88
80
|
prompt.register(prompts.git);
|
|
89
81
|
await prompt.show({ prompt: 'push', task });
|
|
90
|
-
assert.equal(
|
|
82
|
+
assert.equal(createPrompt.mock.callCount(), 1);
|
|
91
83
|
assert.equal(task.mock.callCount(), 0);
|
|
92
84
|
});
|
|
@@ -25,7 +25,7 @@ describe('tasks.interactive', () => {
|
|
|
25
25
|
|
|
26
26
|
afterEach(() => {
|
|
27
27
|
mocker.clearAll();
|
|
28
|
-
|
|
28
|
+
createPrompt.mock.resetCalls();
|
|
29
29
|
log.resetCalls();
|
|
30
30
|
});
|
|
31
31
|
|
|
@@ -54,17 +54,18 @@ describe('tasks.interactive', () => {
|
|
|
54
54
|
const log = new LogStub();
|
|
55
55
|
const spinner = new SpinnerStub();
|
|
56
56
|
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
const createPrompt = mock.fn((type, options) => {
|
|
58
|
+
if (type === 'list') return options.choices[0].value;
|
|
59
|
+
if (type === 'input') return '0.0.1';
|
|
60
|
+
return true;
|
|
60
61
|
});
|
|
61
62
|
|
|
62
|
-
const
|
|
63
|
+
const defaultCreatePrompt = createPrompt;
|
|
63
64
|
|
|
64
|
-
const getContainer = (options,
|
|
65
|
+
const getContainer = (options, promptFn = defaultCreatePrompt) => {
|
|
65
66
|
const config = new Config(Object.assign({}, testConfig, options));
|
|
66
67
|
const shell = new ShellStub({ container: { log, config } });
|
|
67
|
-
const prompt = new Prompt({ container: {
|
|
68
|
+
const prompt = new Prompt({ container: { createPrompt: promptFn } });
|
|
68
69
|
return { log, spinner, config, shell, prompt };
|
|
69
70
|
};
|
|
70
71
|
|
|
@@ -112,7 +113,7 @@ describe('tasks.interactive', () => {
|
|
|
112
113
|
});
|
|
113
114
|
|
|
114
115
|
const config = {
|
|
115
|
-
$schema: 'https://unpkg.com/release-it@
|
|
116
|
+
$schema: 'https://unpkg.com/release-it@20/schema/release-it.json',
|
|
116
117
|
extends: 'github:release-it/release-it-configuration',
|
|
117
118
|
config: true
|
|
118
119
|
};
|
|
@@ -136,7 +137,7 @@ describe('tasks.interactive', () => {
|
|
|
136
137
|
renameSync('.git', 'foo');
|
|
137
138
|
|
|
138
139
|
const config = {
|
|
139
|
-
$schema: 'https://unpkg.com/release-it@
|
|
140
|
+
$schema: 'https://unpkg.com/release-it@20/schema/release-it.json',
|
|
140
141
|
extends: false
|
|
141
142
|
};
|
|
142
143
|
|
|
@@ -181,8 +182,7 @@ describe('tasks.interactive', () => {
|
|
|
181
182
|
childProcess.execSync('git tag 1.0.0', execOpts);
|
|
182
183
|
|
|
183
184
|
const hooks = getHooks(['version', 'git', 'github', 'gitlab', 'npm']);
|
|
184
|
-
const
|
|
185
|
-
const inquirer = { prompt };
|
|
185
|
+
const rejectAll = mock.fn(() => false);
|
|
186
186
|
|
|
187
187
|
const container = getContainer(
|
|
188
188
|
{
|
|
@@ -192,7 +192,7 @@ describe('tasks.interactive', () => {
|
|
|
192
192
|
gitlab: { release: true, skipChecks: true },
|
|
193
193
|
npm: { publish: true, skipChecks: true }
|
|
194
194
|
},
|
|
195
|
-
|
|
195
|
+
rejectAll
|
|
196
196
|
);
|
|
197
197
|
|
|
198
198
|
const exec = t.mock.method(container.shell, 'execFormattedCommand');
|
|
@@ -268,7 +268,7 @@ describe('tasks.interactive', () => {
|
|
|
268
268
|
test('should show only version prompt', async () => {
|
|
269
269
|
const config = { ci: false, 'only-version': true };
|
|
270
270
|
await runTasks({}, getContainer(config));
|
|
271
|
-
assert.equal(
|
|
272
|
-
assert.equal(
|
|
271
|
+
assert.equal(createPrompt.mock.callCount(), 1);
|
|
272
|
+
assert.equal(createPrompt.mock.calls[0].arguments[0], 'list');
|
|
273
273
|
});
|
|
274
274
|
});
|
package/test/tasks.js
CHANGED
|
@@ -34,7 +34,7 @@ describe('tasks', () => {
|
|
|
34
34
|
'https://gitlab.com/api/v4'
|
|
35
35
|
]);
|
|
36
36
|
|
|
37
|
-
const npmMajorVersion = semver.major(process.env.npm_config_user_agent
|
|
37
|
+
const npmMajorVersion = semver.major(process.env.npm_config_user_agent?.match(/npm\/([^ ]+)/)?.[1] ?? '10.0.0');
|
|
38
38
|
|
|
39
39
|
const testConfig = {
|
|
40
40
|
ci: true,
|