release-it 20.0.0-0 → 20.0.0

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
 
@@ -91,7 +91,7 @@ class npm extends Plugin {
91
91
  allowSameVersion && '--allow-same-version',
92
92
  ...fixArgs(versionArgs)
93
93
  ];
94
- const task = () => this.exec(`npm version ${args.filter(Boolean).join(' ')}`, { options: getOptions() });
94
+ const task = () => this.exec(`npm version ${args.filter(Boolean).join(' ')}`, { options: { env: getNpmEnv() } });
95
95
  return this.spinner.show({ task, label: 'npm version' });
96
96
  }
97
97
 
@@ -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,16 @@ 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(([tag, version]) => tag !== DEFAULT_TAG && version === latestVersion);
236
+ if (match) return match[0];
237
+
238
+ const [tag] = Object.keys(distTags).filter(tag => tag !== DEFAULT_TAG);
239
+ if (tag) return tag;
240
+
241
+ this.log.warn(`Unable to get pre-release tag(s) from npm registry. Using "${DEFAULT_TAG_PRERELEASE}".`);
242
+ return DEFAULT_TAG_PRERELEASE;
236
243
  }
237
244
 
238
245
  async resolveTag(version) {
package/lib/prompt.js CHANGED
@@ -27,9 +27,7 @@ class Prompt {
27
27
  if ('validate' in prompt) options.validate = prompt.validate;
28
28
  if ('pageSize' in prompt) options.pageSize = prompt.pageSize;
29
29
 
30
- const answer = await (this.createPrompt
31
- ? this.createPrompt(prompt.type, options)
32
- : types[prompt.type](options));
30
+ const answer = await (this.createPrompt ? this.createPrompt(prompt.type, options) : types[prompt.type](options));
33
31
 
34
32
  const doExecute = prompt.type === 'confirm' ? answer : true;
35
33
 
package/lib/util.js CHANGED
@@ -95,7 +95,7 @@ export const parseGitUrl = remoteUrl => {
95
95
  .replace(/\\+/g, '/'); // Replace forward with backslashes
96
96
  const parsedUrl = gitUrlParse(normalizedUrl);
97
97
  const { resource: host, name: project, protocol, href: remote } = parsedUrl;
98
- const owner = protocol === 'file' ? parsedUrl.owner.split('/').at(-1) : parsedUrl.owner; // Fix owner for file protocol
98
+ const owner = protocol === 'file' ? parsedUrl.owner.split('/').at(-1) : parsedUrl.owner?.replace(/^\/+/, ''); // Fix owner for file protocol
99
99
  const repository = `${owner}/${project}`;
100
100
  return { host, owner, project, protocol, remote, repository };
101
101
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "release-it",
3
- "version": "20.0.0-0",
3
+ "version": "20.0.0",
4
4
  "description": "Generic CLI tool to automate versioning and package publishing-related tasks.",
5
5
  "keywords": [
6
6
  "build",
package/test/npm.js CHANGED
@@ -44,14 +44,26 @@ 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', () => ({
56
+ latest: '0.9.0',
57
+ alpha: '1.0.0-alpha.1',
58
+ next: '1.0.0-0'
59
+ }));
60
+ const tag = await npmClient.resolveTag('1.0.0-1');
61
+ assert.equal(tag, 'next');
62
+ });
63
+
64
+ test('should guess first pre-release tag from registry when no version match', async t => {
65
+ const npmClient = await factory(npm);
66
+ t.mock.method(npmClient, 'getRegistryDistTags', () => ({ latest: '0.9.0', alpha: '1.0.0-alpha.1' }));
55
67
  const tag = await npmClient.resolveTag('1.0.0-0');
56
68
  assert.equal(tag, 'alpha');
57
69
  });
@@ -112,17 +124,15 @@ describe('npm', async () => {
112
124
  const exec = t.mock.method(npmClient.shell, 'exec', command => {
113
125
  if (command === 'npm whoami --registry registry.example.org') return Promise.resolve('john');
114
126
  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'] }));
127
+ if (re.test(command)) return Promise.resolve(JSON.stringify({ john: ['write'] }));
116
128
  return Promise.resolve();
117
129
  });
118
130
 
119
131
  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
- );
132
+ const commands = exec.mock.calls.map(c => c.arguments[0]);
133
+ assert(commands.includes('npm ping --registry registry.example.org'));
134
+ assert(commands.includes('npm whoami --registry registry.example.org'));
135
+ assert(commands.some(c => /npm show release-it@[a-z]+ version --registry registry\.example\.org/.test(c)));
126
136
  });
127
137
 
128
138
  test('should not throw when executing tasks', async t => {
@@ -130,7 +140,7 @@ describe('npm', async () => {
130
140
  t.mock.method(npmClient.shell, 'exec', command => {
131
141
  if (command === 'npm whoami') return Promise.resolve('john');
132
142
  const re = /npm access (list collaborators --json|ls-collaborators) release-it/;
133
- if (re.test.command) return Promise.resolve(JSON.stringify({ john: ['write'] }));
143
+ if (re.test(command)) return Promise.resolve(JSON.stringify({ john: ['write'] }));
134
144
  return Promise.resolve();
135
145
  });
136
146
  await assert.doesNotReject(runTasks(npmClient));
@@ -401,4 +411,16 @@ describe('npm', async () => {
401
411
  const versionArgs = getArgs(exec, 'npm version');
402
412
  assert.match(versionArgs[0], / --workspaces-update=false --allow-same-version/);
403
413
  });
414
+
415
+ test('should not bypass dry-run guard for `npm version`', async t => {
416
+ const options = { 'dry-run': true, npm: { skipChecks: true } };
417
+ const npmClient = await factory(npm, { options });
418
+ const exec = t.mock.method(npmClient.shell, 'exec', () => Promise.resolve());
419
+ await runTasks(npmClient);
420
+ const versionCall = exec.mock.calls.find(call =>
421
+ (typeof call.arguments[0] === 'string' ? call.arguments[0] : '').startsWith('npm version')
422
+ );
423
+ assert.ok(versionCall, 'expected `npm version` to be invoked');
424
+ assert.notEqual(versionCall.arguments[1]?.write, false);
425
+ });
404
426
  });
@@ -113,7 +113,7 @@ describe('tasks.interactive', () => {
113
113
  });
114
114
 
115
115
  const config = {
116
- $schema: 'https://unpkg.com/release-it@19/schema/release-it.json',
116
+ $schema: 'https://unpkg.com/release-it@20/schema/release-it.json',
117
117
  extends: 'github:release-it/release-it-configuration',
118
118
  config: true
119
119
  };
@@ -137,7 +137,7 @@ describe('tasks.interactive', () => {
137
137
  renameSync('.git', 'foo');
138
138
 
139
139
  const config = {
140
- $schema: 'https://unpkg.com/release-it@19/schema/release-it.json',
140
+ $schema: 'https://unpkg.com/release-it@20/schema/release-it.json',
141
141
  extends: false
142
142
  };
143
143