release-it 17.8.2 → 17.10.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
@@ -328,34 +328,35 @@ release-it programmatically][54] for example code.
328
328
  - [Halo][59]
329
329
  - [hosts][60]
330
330
  - [js-cookie][61]
331
- - [Madge][62]
332
- - [Metalsmith][63]
333
- - [Node-Redis][64]
334
- - [React Native Paper][65]
335
- - [Readability.js][66]
336
- - [Redux][67]
337
- - [Saleor][68]
338
- - [Semantic UI React][69]
339
- - [Shepherd][70]
340
- - [Tabler][71] + [tabler-icons][72]
341
- - Swagger ([swagger-ui][73] + [swagger-editor][74])
342
- - [Repositories that depend on release-it][75]
343
- - GitHub search for [path:\*\*/.release-it.json][76]
331
+ - [jQuery][62]
332
+ - [Madge][63]
333
+ - [Metalsmith][64]
334
+ - [Node-Redis][65]
335
+ - [React Native Paper][66]
336
+ - [Readability.js][67]
337
+ - [Redux][68]
338
+ - [Saleor][69]
339
+ - [Semantic UI React][70]
340
+ - [Shepherd][71]
341
+ - [Tabler][72] + [tabler-icons][73]
342
+ - Swagger ([swagger-ui][74] + [swagger-editor][75])
343
+ - [Repositories that depend on release-it][76]
344
+ - GitHub search for [path:\*\*/.release-it.json][77]
344
345
 
345
346
  ## Legacy Node.js
346
347
 
347
348
  The latest major version is v17, supporting Node.js 18 and up (as Node.js v16 is EOL). The previous major version was
348
- v16, supporting Node.js 16. Use release-it v15 for environments running Node.js v14. Also see [CHANGELOG.md][77].
349
+ v16, supporting Node.js 16. Use release-it v15 for environments running Node.js v14. Also see [CHANGELOG.md][78].
349
350
 
350
351
  ## Links
351
352
 
352
- - See [CHANGELOG.md][77] for major/breaking updates, and [releases][78] for a detailed version history.
353
- - To **contribute**, please read [CONTRIBUTING.md][79] first.
354
- - Please [open an issue][80] if anything is missing or unclear in this documentation.
353
+ - See [CHANGELOG.md][78] for major/breaking updates, and [releases][79] for a detailed version history.
354
+ - To **contribute**, please read [CONTRIBUTING.md][80] first.
355
+ - Please [open an issue][81] if anything is missing or unclear in this documentation.
355
356
 
356
357
  ## License
357
358
 
358
- [MIT][81]
359
+ [MIT][82]
359
360
 
360
361
  Are you using release-it at work? Please consider [sponsoring me][14]!
361
362
 
@@ -420,23 +421,24 @@ Are you using release-it at work? Please consider [sponsoring me][14]!
420
421
  [59]: https://github.com/halo-dev/halo
421
422
  [60]: https://github.com/StevenBlack/hosts
422
423
  [61]: https://github.com/js-cookie/js-cookie
423
- [62]: https://github.com/pahen/madge
424
- [63]: https://github.com/metalsmith/metalsmith
425
- [64]: https://github.com/redis/node-redis
426
- [65]: https://github.com/callstack/react-native-paper
427
- [66]: https://github.com/mozilla/readability
428
- [67]: https://github.com/reduxjs/redux
429
- [68]: https://github.com/saleor/saleor
430
- [69]: https://github.com/Semantic-Org/Semantic-UI-React
431
- [70]: https://github.com/shipshapecode/shepherd
432
- [71]: https://github.com/tabler/tabler
433
- [72]: https://github.com/tabler/tabler-icons
434
- [73]: https://github.com/swagger-api/swagger-ui
435
- [74]: https://github.com/swagger-api/swagger-editor
436
- [75]: https://github.com/release-it/release-it/network/dependents
437
- [76]: https://github.com/search?q=path%3A**%2F.release-it.json&type=code
438
- [77]: ./CHANGELOG.md
439
- [78]: https://github.com/release-it/release-it/releases
440
- [79]: ./.github/CONTRIBUTING.md
441
- [80]: https://github.com/release-it/release-it/issues/new
442
- [81]: ./LICENSE
424
+ [62]: https://github.com/jquery/jquery
425
+ [63]: https://github.com/pahen/madge
426
+ [64]: https://github.com/metalsmith/metalsmith
427
+ [65]: https://github.com/redis/node-redis
428
+ [66]: https://github.com/callstack/react-native-paper
429
+ [67]: https://github.com/mozilla/readability
430
+ [68]: https://github.com/reduxjs/redux
431
+ [69]: https://github.com/saleor/saleor
432
+ [70]: https://github.com/Semantic-Org/Semantic-UI-React
433
+ [71]: https://github.com/shipshapecode/shepherd
434
+ [72]: https://github.com/tabler/tabler
435
+ [73]: https://github.com/tabler/tabler-icons
436
+ [74]: https://github.com/swagger-api/swagger-ui
437
+ [75]: https://github.com/swagger-api/swagger-editor
438
+ [76]: https://github.com/release-it/release-it/network/dependents
439
+ [77]: https://github.com/search?q=path%3A**%2F.release-it.json&type=code
440
+ [78]: ./CHANGELOG.md
441
+ [79]: https://github.com/release-it/release-it/releases
442
+ [80]: ./.github/CONTRIBUTING.md
443
+ [81]: https://github.com/release-it/release-it/issues/new
444
+ [82]: ./LICENSE
@@ -165,6 +165,7 @@ class GitLab extends Release {
165
165
  const url = `${baseUrl}/${endpoint}${options.searchParams ? `?${new URLSearchParams(options.searchParams)}` : ''}`;
166
166
  const headers = {
167
167
  'user-agent': 'webpro/release-it',
168
+ 'Content-Type': typeof options.json !== 'undefined' ? 'application/json' : 'text/plain',
168
169
  [tokenHeader]: this.token
169
170
  };
170
171
  const requestOptions = {
@@ -173,28 +174,40 @@ class GitLab extends Release {
173
174
  ...this.certificateAuthorityOption
174
175
  };
175
176
 
176
- const response = await fetch(
177
- url,
178
- options.json || options.body
179
- ? {
180
- ...requestOptions,
181
- body: options.json ? JSON.stringify(options.json) : options.body
182
- }
183
- : requestOptions
184
- );
185
- const body = await response.json();
186
- this.debug(body);
187
- return body;
177
+ try {
178
+ const response = await fetch(
179
+ url,
180
+ options.json || options.body
181
+ ? {
182
+ ...requestOptions,
183
+ body: options.json ? JSON.stringify(options.json) : options.body
184
+ }
185
+ : requestOptions
186
+ );
187
+
188
+ if (!response.ok) {
189
+ const body = await response.json();
190
+ throw new Error(body.error);
191
+ }
192
+
193
+ const body = await response.json();
194
+ this.debug(body);
195
+ return body;
196
+ } catch (err) {
197
+ this.debug(err);
198
+ throw err;
199
+ }
188
200
  }
189
201
 
190
202
  async createRelease() {
191
203
  const { releaseName } = this.options;
192
- const { tagName } = this.config.getContext();
204
+ const { tagName, branchName, git: { tagAnnotation } = {} } = this.config.getContext();
193
205
  const { id, releaseNotes, repo, origin } = this.getContext();
194
206
  const { isDryRun } = this.config;
195
207
  const name = format(releaseName, this.config.getContext());
208
+ const tagMessage = format(tagAnnotation, this.config.getContext());
196
209
  const description = releaseNotes || '-';
197
- const releaseUrl = `${origin}/${repo.repository}/-/releases`;
210
+ const releaseUrl = `${origin}/${repo.repository}/-/releases/${tagName}`;
198
211
  const releaseMilestones = this.getReleaseMilestones();
199
212
 
200
213
  this.log.exec(`gitlab releases#createRelease "${name}" (${tagName})`, { isDryRun });
@@ -208,7 +221,9 @@ class GitLab extends Release {
208
221
  const options = {
209
222
  json: {
210
223
  name,
224
+ ref: branchName,
211
225
  tag_name: tagName,
226
+ tag_message: tagMessage,
212
227
  description
213
228
  }
214
229
  };
@@ -224,10 +239,11 @@ class GitLab extends Release {
224
239
  }
225
240
 
226
241
  try {
227
- await this.request(endpoint, options);
242
+ const body = await this.request(endpoint, options);
243
+ const releaseUrlSelf = body._links?.self ?? releaseUrl;
228
244
  this.log.verbose('gitlab releases#createRelease: done');
229
- this.setContext({ isReleased: true, releaseUrl });
230
- this.config.setContext({ isReleased: true, releaseUrl });
245
+ this.setContext({ isReleased: true, releaseUrl: releaseUrlSelf });
246
+ this.config.setContext({ isReleased: true, releaseUrl: releaseUrlSelf });
231
247
  return true;
232
248
  } catch (err) {
233
249
  this.debug(err);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "release-it",
3
- "version": "17.8.2",
3
+ "version": "17.10.0",
4
4
  "description": "Generic CLI tool to automate versioning and package publishing-related tasks.",
5
5
  "keywords": [
6
6
  "build",
@@ -116,10 +116,10 @@
116
116
  "eslint-plugin-import-x": "4.3.1",
117
117
  "eslint-plugin-prettier": "5.2.1",
118
118
  "fs-monkey": "1.0.6",
119
- "globals": "15.10.0",
119
+ "globals": "15.11.0",
120
120
  "installed-check": "9.3.0",
121
- "knip": "5.31.0",
122
- "memfs": "4.12.0",
121
+ "knip": "5.33.3",
122
+ "memfs": "4.14.0",
123
123
  "mock-stdio": "1.0.3",
124
124
  "nock": "14.0.0-beta.8",
125
125
  "prettier": "3.3.3",
@@ -127,7 +127,7 @@
127
127
  "remark-preset-webpro": "1.1.1",
128
128
  "sinon": "19.0.2",
129
129
  "strip-ansi": "7.1.0",
130
- "typescript": "5.6.2"
130
+ "typescript": "5.6.3"
131
131
  },
132
132
  "overrides": {
133
133
  "pac-resolver": "7.0.1",
package/test/gitlab.js CHANGED
@@ -2,6 +2,7 @@ import fs from 'node:fs';
2
2
  import test from 'ava';
3
3
  import sinon from 'sinon';
4
4
  import nock from 'nock';
5
+ import Git from '../lib/plugin/git/Git.js';
5
6
  import GitLab from '../lib/plugin/gitlab/GitLab.js';
6
7
  import { factory, runTasks } from './util/index.js';
7
8
  import {
@@ -63,6 +64,9 @@ test.serial('should upload assets and release', async t => {
63
64
  const gitlab = factory(GitLab, { options });
64
65
  sinon.stub(gitlab, 'getLatestVersion').resolves('2.0.0');
65
66
 
67
+ const git = factory(Git);
68
+ const ref = (await git.getBranchName()) ?? 'HEAD';
69
+
66
70
  interceptUser();
67
71
  interceptCollaborator();
68
72
  interceptMilestones({
@@ -89,7 +93,9 @@ test.serial('should upload assets and release', async t => {
89
93
  interceptPublish({
90
94
  body: {
91
95
  name: 'Release 2.0.1',
96
+ ref,
92
97
  tag_name: '2.0.1',
98
+ tag_message: 'Release 2.0.1',
93
99
  description: 'Custom notes',
94
100
  assets: {
95
101
  links: [
@@ -108,7 +114,7 @@ test.serial('should upload assets and release', async t => {
108
114
  t.is(gitlab.assets[0].url, `${pushRepo}/uploads/7e8bec1fe27cc46a4bc6a91b9e82a07c/file-v2.0.1.txt`);
109
115
  const { isReleased, releaseUrl } = gitlab.getContext();
110
116
  t.true(isReleased);
111
- t.is(releaseUrl, `${pushRepo}/-/releases`);
117
+ t.is(releaseUrl, `${pushRepo}/-/releases/2.0.1`);
112
118
  });
113
119
 
114
120
  test.serial('should upload assets with ID-based URLs too', async t => {
@@ -205,7 +211,7 @@ test.serial('should release to sub-grouped repo', async t => {
205
211
 
206
212
  const { isReleased, releaseUrl } = gitlab.getContext();
207
213
  t.true(isReleased);
208
- t.is(releaseUrl, 'https://gitlab.com/group/sub-group/repo/-/releases');
214
+ t.regex(releaseUrl, /https:\/\/gitlab.com\/group\/sub-group\/repo\/-\/releases\//);
209
215
  });
210
216
 
211
217
  test.serial('should throw for unauthenticated user', async t => {
@@ -259,7 +265,7 @@ test('should not make requests in dry run', async t => {
259
265
  t.is(gitlab.log.exec.args[2][0], 'gitlab releases#uploadAssets');
260
266
  t.is(gitlab.log.exec.args[3][0], 'gitlab releases#createRelease "R" (1.0.1)');
261
267
  t.true(isReleased);
262
- t.is(releaseUrl, `${pushRepo}/-/releases`);
268
+ t.is(releaseUrl, `${pushRepo}/-/releases/1.0.1`);
263
269
  });
264
270
 
265
271
  test('should skip checks', async t => {
@@ -12,7 +12,13 @@ export let interceptCollaborator = (
12
12
  .reply(200, { id: userId, username: owner, access_level: 30 });
13
13
 
14
14
  export let interceptPublish = ({ host = 'https://gitlab.com', owner = 'user', project = 'repo', body } = {}, options) =>
15
- nock(host, options).post(`/api/v4/projects/${owner}%2F${project}/releases`, body).reply(200, {});
15
+ nock(host, options)
16
+ .post(`/api/v4/projects/${owner}%2F${project}/releases`, body)
17
+ .reply(200, {
18
+ _links: {
19
+ self: `https://gitlab.com/${owner}/${project}/-/releases/${body?.tag_name ?? '1.0.0'}`
20
+ }
21
+ });
16
22
 
17
23
  export let interceptMilestones = (
18
24
  { host = 'https://gitlab.com', owner = 'user', project = 'repo', query = {}, milestones = [] } = {},
@@ -34,12 +40,15 @@ export let interceptAsset = ({ host = 'https://gitlab.com', owner = 'user', proj
34
40
  nock(host)
35
41
  .post(`/api/v4/projects/${owner}%2F${project}/uploads`)
36
42
  .query(true)
37
- .reply(200, function (_, requestBody) {
43
+ .reply(200, (_, requestBody) => {
38
44
  const [, name] = requestBody.match(/filename="([^"]+)/);
39
45
  return {
40
46
  alt: name,
41
47
  url: `/uploads/7e8bec1fe27cc46a4bc6a91b9e82a07c/${name}`,
42
48
  full_path: `/-/project/1234/uploads/7e8bec1fe27cc46a4bc6a91b9e82a07c/${name}`,
43
- markdown: `[${name}](/uploads/7e8bec1fe27cc46a4bc6a91b9e82a07c/${name})`
49
+ markdown: `[${name}](/uploads/7e8bec1fe27cc46a4bc6a91b9e82a07c/${name})`,
50
+ _links: {
51
+ self: `https://gitlab.com/${owner}/${project}/-/releases/${name}`
52
+ }
44
53
  };
45
54
  });
@@ -8,10 +8,12 @@ import Spinner from '../lib/spinner.js';
8
8
  import Prompt from '../lib/prompt.js';
9
9
  import Config from '../lib/config.js';
10
10
  import runTasks from '../lib/index.js';
11
+ import Git from '../lib/plugin/git/Git.js';
11
12
  import { mkTmpDir, gitAdd } from './util/helpers.js';
12
13
  import ShellStub from './stub/shell.js';
13
14
  import { interceptPublish as interceptGitLabPublish } from './stub/gitlab.js';
14
15
  import { interceptCreate as interceptGitHubCreate } from './stub/github.js';
16
+ import { factory } from './util/index.js';
15
17
 
16
18
  const noop = Promise.resolve();
17
19
 
@@ -160,6 +162,9 @@ test.serial('should run "after:*:release" plugin hooks', async t => {
160
162
  sh.exec('git tag 1.0.0');
161
163
  const sha = gitAdd('line', 'file', 'More file');
162
164
 
165
+ const git = factory(Git);
166
+ const ref = (await git.getBranchName()) ?? 'HEAD';
167
+
163
168
  interceptGitHubCreate({
164
169
  owner,
165
170
  project,
@@ -171,7 +176,9 @@ test.serial('should run "after:*:release" plugin hooks', async t => {
171
176
  project,
172
177
  body: {
173
178
  name: 'Release 1.1.0',
179
+ ref,
174
180
  tag_name: '1.1.0',
181
+ tag_message: 'Release 1.1.0',
175
182
  description: `* More file (${sha})`
176
183
  }
177
184
  });
package/test/tasks.js CHANGED
@@ -8,6 +8,7 @@ import Log from '../lib/log.js';
8
8
  import Spinner from '../lib/spinner.js';
9
9
  import Config from '../lib/config.js';
10
10
  import runTasks from '../lib/index.js';
11
+ import Git from '../lib/plugin/git/Git.js';
11
12
  import { mkTmpDir, gitAdd, getArgs } from './util/helpers.js';
12
13
  import ShellStub from './stub/shell.js';
13
14
  import {
@@ -22,6 +23,7 @@ import {
22
23
  interceptCreate as interceptGitHubCreate,
23
24
  interceptAsset as interceptGitHubAsset
24
25
  } from './stub/github.js';
26
+ import { factory } from './util/index.js';
25
27
 
26
28
  const rootDir = new URL('..', import.meta.url);
27
29
 
@@ -247,6 +249,8 @@ test.serial('should release all the things (pre-release, github, gitlab)', async
247
249
  sh.exec('git tag v1.0.0');
248
250
  const sha = gitAdd('line', 'file', 'More file');
249
251
  sh.exec('git push --follow-tags');
252
+ const git = factory(Git);
253
+ const ref = (await git.getBranchName()) ?? 'HEAD';
250
254
 
251
255
  interceptGitHubAuthentication();
252
256
  interceptGitHubCollaborator({ owner, project });
@@ -270,7 +274,9 @@ test.serial('should release all the things (pre-release, github, gitlab)', async
270
274
  project,
271
275
  body: {
272
276
  name: 'Release 1.1.0-alpha.0',
277
+ ref,
273
278
  tag_name: 'v1.1.0-alpha.0',
279
+ tag_message: `${owner} ${owner}/${project} ${project}`,
274
280
  description: `Notes for ${pkgName}: ${sha}`,
275
281
  assets: {
276
282
  links: [
@@ -333,7 +339,7 @@ test.serial('should release all the things (pre-release, github, gitlab)', async
333
339
  t.true(log.obtrusive.firstCall.args[0].endsWith(`release ${pkgName} (1.0.0...1.1.0-alpha.0)`));
334
340
  t.true(log.log.firstCall.args[0].endsWith(`https://www.npmjs.com/package/${pkgName}`));
335
341
  t.true(log.log.secondCall.args[0].endsWith(`https://github.com/${owner}/${project}/releases/tag/v1.1.0-alpha.0`));
336
- t.true(log.log.args[3][0].endsWith(`${project}/-/releases`));
342
+ t.true(log.log.thirdCall.args[0].endsWith(`${project}/-/releases/v1.1.0-alpha.0`));
337
343
  t.regex(log.log.lastCall.args[0], /Done \(in [0-9]+s\.\)/);
338
344
 
339
345
  exec.restore();
@@ -365,7 +371,7 @@ test.serial('should publish pre-release without pre-id with different npm.tag',
365
371
  t.is(stdout.trim(), 'v2.0.0-0');
366
372
  t.true(log.obtrusive.firstCall.args[0].endsWith(`release ${pkgName} (1.0.0...2.0.0-0)`));
367
373
  t.true(log.log.firstCall.args[0].endsWith(`https://www.npmjs.com/package/${pkgName}`));
368
- t.regex(log.log.args[1][0], /Done \(in [0-9]+s\.\)/);
374
+ t.regex(log.log.lastCall.args[0], /Done \(in [0-9]+s\.\)/);
369
375
 
370
376
  exec.restore();
371
377
  });
@@ -385,7 +391,7 @@ test.serial('should handle private package correctly, bump lockfile', async t =>
385
391
  t.deepEqual(npmArgs, ['npm version 1.0.1 --no-git-tag-version']);
386
392
  t.true(log.obtrusive.firstCall.args[0].endsWith(`release ${pkgName} (1.0.0...1.0.1)`));
387
393
  t.is(log.warn.length, 0);
388
- t.regex(log.log.args[0][0], /Done \(in [0-9]+s\.\)/);
394
+ t.regex(log.log.firstCall.args[0], /Done \(in [0-9]+s\.\)/);
389
395
 
390
396
  exec.restore();
391
397
  });