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 CHANGED
@@ -44,7 +44,7 @@ npm install -D release-it
44
44
  "release": "release-it"
45
45
  },
46
46
  "devDependencies": {
47
- "release-it": "^19.0.0"
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@19/schema/release-it.json",
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 Inquirer.js inside custom hook scripts might cause issues (since release-it also uses this itself).
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 v19, supporting Node.js 20 and up:
356
+ The latest major version is v20, supporting Node.js 20 and up:
357
357
 
358
- | release-it | Node.js |
359
- | :--------: | :-----: |
360
- | v19 | v20 |
361
- | v18 | v20 |
362
- | v17 | v18 |
363
- | v16 | v16 |
364
- | v15 | v14 |
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
@@ -24,7 +24,7 @@ class Logger {
24
24
  }
25
25
 
26
26
  info(...args) {
27
- console.error(styleText('grey', args.join(' ')));
27
+ console.error(styleText('gray', args.join(' ')));
28
28
  }
29
29
 
30
30
  warn(...args) {
@@ -22,7 +22,7 @@ const plugins = {
22
22
  };
23
23
 
24
24
  const load = async pluginName => {
25
- let plugin = null;
25
+ let plugin;
26
26
  try {
27
27
  const module = await import(pluginName);
28
28
  plugin = module.default;
@@ -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 => {
@@ -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
- getRegistryPreReleaseTags() {
190
+ getRegistryDistTags() {
191
191
  return this.exec(`npm view ${this.getName()} dist-tags --json`, { options: getOptions() }).then(
192
192
  output => {
193
193
  try {
194
- const tags = JSON.parse(output);
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 [tag] = await this.getRegistryPreReleaseTags();
230
- if (tag) {
231
- return tag;
232
- } else {
233
- this.log.warn(`Unable to get pre-release tag(s) from npm registry. Using "${DEFAULT_TAG_PRERELEASE}".`);
234
- return DEFAULT_TAG_PRERELEASE;
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 inquirer from 'inquirer';
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 = (container.inquirer || inquirer).prompt;
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 = Object.assign({}, prompt, {
19
- name: promptName,
20
- message: prompt.message(context),
21
- choices: 'choices' in prompt && prompt.choices(context),
22
- transformer: 'transformer' in prompt ? prompt.transformer(context) : undefined
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 answers = await this.createPrompt([options]);
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' ? answers[promptName] : true;
34
+ const doExecute = prompt.type === 'confirm' ? answer : true;
28
35
 
29
- return doExecute && task ? await task(answers[promptName]) : false;
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": "19.2.4",
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.3.1",
87
- "eta": "4.5.0",
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": "10.2.0",
95
- "ora": "9.0.0",
96
- "os-name": "6.1.0",
97
- "proxy-agent": "6.5.0",
98
- "semver": "7.7.3",
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": "6.23.0",
100
+ "undici": "7.24.5",
101
101
  "url-join": "5.0.0",
102
102
  "wildcard-match": "5.1.4",
103
- "yargs-parser": "21.1.1"
103
+ "yargs-parser": "22.0.0"
104
104
  },
105
105
  "devDependencies": {
106
- "@eslint/js": "9.39.2",
106
+ "@eslint/js": "10.0.1",
107
107
  "@octokit/request-error": "7.1.0",
108
108
  "@types/node": "24.10.9",
109
- "eslint": "9.39.2",
110
- "eslint-plugin-import-x": "4.16.1",
111
- "globals": "16.5.0",
112
- "installed-check": "9.3.0",
113
- "knip": "5.82.1",
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.0",
116
+ "prettier": "3.8.1",
117
117
  "remark-cli": "12.0.1",
118
- "remark-preset-webpro": "2.1.0",
119
- "tar": "7.5.4",
120
- "typescript": "5.9.3"
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.12.0 || >=22.0.0"
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, 'getRegistryPreReleaseTags', () => []);
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
- t.mock.method(npmClient, 'getRegistryPreReleaseTags', () => ['alpha']);
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.command) return Promise.resolve(JSON.stringify({ john: ['write'] }));
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
- assert.equal(exec.mock.calls[0].arguments[0], 'npm ping --registry registry.example.org');
121
- assert.equal(exec.mock.calls[1].arguments[0], 'npm whoami --registry registry.example.org');
122
- assert.match(
123
- exec.mock.calls[2].arguments[0],
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.command) return Promise.resolve(JSON.stringify({ john: ['write'] }));
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 = ([options]) => Promise.resolve({ [options.name]: true });
14
- const no = ([options]) => Promise.resolve({ [options.name]: false });
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 promptMock = t.mock.fn(yes);
19
- const inquirer = { prompt: promptMock };
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(promptMock.mock.callCount(), 0);
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 promptMock = t.mock.fn(yes);
29
- const inquirer = { prompt: promptMock };
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(promptMock.mock.callCount(), 1);
34
- assert.deepEqual(promptMock.mock.calls[0].arguments[0][0], {
35
- type: 'confirm',
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 promptMock = t.mock.fn(yes);
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 inquirer = { prompt: promptMock };
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(promptMock.mock.callCount(), 1);
67
- assert.equal(promptMock.mock.calls[0].arguments[0][0].message, message);
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 promptMock = t.mock.fn(yes);
74
- const inquirer = { prompt: promptMock };
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(promptMock.mock.callCount(), 1);
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 promptMock = t.mock.fn(no);
86
- const inquirer = { prompt: promptMock };
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(promptMock.mock.callCount(), 1);
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
- prompt.mock.resetCalls();
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 prompt = mock.fn(([options]) => {
58
- const answer = options.type === 'list' ? options.choices[0].value : options.name === 'version' ? '0.0.1' : true;
59
- return { [options.name]: answer };
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 defaultInquirer = { prompt };
63
+ const defaultCreatePrompt = createPrompt;
63
64
 
64
- const getContainer = (options, inquirer = defaultInquirer) => {
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: { inquirer } });
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@19/schema/release-it.json',
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@19/schema/release-it.json',
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 prompt = mock.fn(([options]) => ({ [options.name]: false }));
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
- inquirer
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(prompt.mock.callCount(), 1);
272
- assert.equal(prompt.mock.calls[0].arguments[0][0].name, 'incrementList');
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.match(/npm\/([^ ]+)/)[1]);
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,