release-it 15.0.0-esm.3 → 15.0.0-esm.6

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.
Files changed (49) hide show
  1. package/README.md +16 -9
  2. package/config/release-it.json +3 -0
  3. package/lib/config.js +7 -15
  4. package/lib/index.js +27 -33
  5. package/lib/log.js +1 -1
  6. package/lib/plugin/GitBase.js +1 -1
  7. package/lib/plugin/GitRelease.js +1 -1
  8. package/lib/plugin/Plugin.js +1 -1
  9. package/lib/plugin/factory.js +5 -5
  10. package/lib/plugin/git/Git.js +3 -2
  11. package/lib/plugin/github/GitHub.js +14 -8
  12. package/lib/plugin/gitlab/GitLab.js +68 -14
  13. package/lib/plugin/npm/npm.js +3 -2
  14. package/lib/plugin/version/Version.js +5 -1
  15. package/lib/shell.js +2 -2
  16. package/lib/util.js +2 -2
  17. package/package.json +25 -32
  18. package/test/config.js +19 -26
  19. package/test/git.init.js +32 -7
  20. package/test/git.js +5 -2
  21. package/test/github.js +42 -13
  22. package/test/gitlab.js +69 -18
  23. package/test/log.js +1 -1
  24. package/test/npm.js +12 -3
  25. package/test/plugins.js +33 -21
  26. package/test/spinner.js +1 -2
  27. package/test/stub/config/default/.release-it.json +5 -0
  28. package/test/stub/config/invalid-config-rc +1 -0
  29. package/test/stub/config/invalid-config-txt +2 -0
  30. package/test/stub/config/merge/.release-it.json +5 -0
  31. package/test/stub/config/merge/package.json +7 -0
  32. package/test/stub/config/toml/.release-it.toml +2 -0
  33. package/test/stub/config/yaml/.release-it.yaml +2 -0
  34. package/test/stub/config/yml/.release-it.yml +2 -0
  35. package/test/stub/github.js +26 -10
  36. package/test/stub/gitlab.js +15 -7
  37. package/test/stub/shell.js +2 -2
  38. package/test/tasks.interactive.js +2 -3
  39. package/test/tasks.js +3 -4
  40. package/test/util/helpers.js +6 -6
  41. package/test/util/index.js +14 -19
  42. package/test/utils.js +1 -1
  43. package/test/version.js +9 -4
  44. package/config/.codecov.yml +0 -5
  45. package/config/deprecated.json +0 -1
  46. package/lib/deprecated.js +0 -22
  47. package/lib/metrics.js +0 -76
  48. package/test/deprecated.js +0 -11
  49. package/test/metrics.js +0 -17
package/README.md CHANGED
@@ -19,7 +19,6 @@ system, and hooks to execute any command you need to test, build, and/or publish
19
19
 
20
20
  [![Action Status](https://github.com/release-it/release-it/workflows/Cross-OS%20Tests/badge.svg)](https://github.com/release-it/release-it/actions)
21
21
  [![npm version](https://badge.fury.io/js/release-it.svg)](https://www.npmjs.com/package/release-it)
22
- [![codecov](https://codecov.io/gh/release-it/release-it/branch/master/graph/badge.svg)](https://codecov.io/gh/release-it/release-it)
23
22
 
24
23
  ## Links
25
24
 
@@ -256,7 +255,7 @@ will run one after another. Some example release-it configuration:
256
255
  The variables can be found in the [default configuration](./config/release-it.json). Additionally, the following
257
256
  variables are exposed:
258
257
 
259
- ```
258
+ ```text
260
259
  version
261
260
  latestVersion
262
261
  changelog
@@ -272,6 +271,14 @@ Use `--verbose` to log the output of the commands.
272
271
  For the sake of verbosity, the full list of hooks is actually: `init`, `beforeBump`, `bump`, `beforeRelease`, `release`
273
272
  or `afterRelease`. However, hooks like `before:beforeRelease` look weird and are usually not useful in practice.
274
273
 
274
+ Note that arguments need to be quoted properly when used from the command line:
275
+
276
+ ```bash
277
+ release-it --'hooks.after:release="echo Successfully released ${name} v${version} to ${repo.repository}."'
278
+ ```
279
+
280
+ Using Inquirer.js inside custom hook scripts might cause issues (since release-it also uses this itself).
281
+
275
282
  ## Plugins
276
283
 
277
284
  Since v11, release-it can be extended in many, many ways. Here are some plugins:
@@ -299,14 +306,13 @@ Deprecated. Please see [distribution repository](./docs/recipes/distribution-rep
299
306
 
300
307
  ## Metrics
301
308
 
302
- Use `--disable-metrics` to opt-out of sending some anonymous statistical data to Google Analytics. For details, refer to
303
- [lib/metrics.js](./lib/metrics.js). Please consider to not opt-out: more data means more support for future development.
309
+ In release-it v15, anonymous metrics have been removed from the codebase and no data is sent or stored anywhere.
304
310
 
305
311
  ## Troubleshooting & debugging
306
312
 
307
313
  - With `release-it --verbose` (or `-V`), release-it prints the output of every user-defined [hook](#hooks).
308
314
  - With `release-it -VV`, release-it also prints the output of every internal command.
309
- - Use `DEBUG=release-it:* release-it [...]` to print configuration and more error details.
315
+ - Use `NODE_DEBUG=release-it:* release-it [...]` to print configuration and more error details.
310
316
 
311
317
  Use `verbose: 2` in a configuration file to have the equivalent of `-VV` on the command line.
312
318
 
@@ -321,17 +327,18 @@ While mostly used as a CLI tool, release-it can be used as a dependency to integ
321
327
  - [blockchain/blockchain-wallet-v4-frontend](https://github.com/blockchain/blockchain-wallet-v4-frontend)
322
328
  - [callstack/linaria](https://github.com/callstack/linaria)
323
329
  - [ember-cli/ember-cli](https://github.com/ember-cli/ember-cli)
330
+ - [metalsmith/metalsmith](https://github.com/metalsmith/metalsmith)
324
331
  - [react-native-paper](https://github.com/callstack/react-native-paper)
325
332
  - [js-cookie/js-cookie](https://github.com/js-cookie/js-cookie)
326
- - [mirumee/saleor](https://github.com/mirumee/saleor)
333
+ - [saleor/saleor](https://github.com/saleor/saleor)
327
334
  - [mozilla/readability](https://github.com/mozilla/readability)
328
- - [satya164/react-native-tab-view](https://github.com/satya164/react-native-tab-view)
335
+ - [redis/node-redis](https://github.com/redis/node-redis)
329
336
  - [shipshapecode/shepherd](https://github.com/shipshapecode/shepherd)
330
337
  - [swagger-api/swagger-ui](https://github.com/swagger-api/swagger-ui) +
331
338
  [swagger-editor](https://github.com/swagger-api/swagger-editor)
332
339
  - [StevenBlack/hosts](https://github.com/StevenBlack/hosts)
333
- - [tabler](https://github.com/tabler/tabler) + [tabler-icons](https://github.com/tabler/tabler-icons)
334
- - [youzan/vant](https://github.com/youzan/vant/search?q=release-it)
340
+ - [tabler/tabler](https://github.com/tabler/tabler) + [tabler-icons](https://github.com/tabler/tabler-icons)
341
+ - [youzan/vant](https://github.com/youzan/vant)
335
342
  - [Repositories that depend on release-it](https://github.com/release-it/release-it/network/dependents)
336
343
  - GitHub search for [filename:.release-it.json](https://github.com/search?q=filename%3A.release-it.json)
337
344
 
@@ -26,6 +26,7 @@
26
26
  "tag": null,
27
27
  "otp": null,
28
28
  "ignoreVersion": false,
29
+ "allowSameVersion": false,
29
30
  "skipChecks": false,
30
31
  "timeout": 10
31
32
  },
@@ -33,6 +34,7 @@
33
34
  "release": false,
34
35
  "releaseName": "Release ${version}",
35
36
  "releaseNotes": null,
37
+ "autoGenerate": false,
36
38
  "preRelease": false,
37
39
  "draft": false,
38
40
  "tokenRef": "GITHUB_TOKEN",
@@ -47,6 +49,7 @@
47
49
  "release": false,
48
50
  "releaseName": "Release ${version}",
49
51
  "releaseNotes": null,
52
+ "milestones": [],
50
53
  "tokenRef": "GITLAB_TOKEN",
51
54
  "tokenHeader": "Private-Token",
52
55
  "certificateAuthorityFile": null,
package/lib/config.js CHANGED
@@ -1,13 +1,11 @@
1
+ import util from 'node:util';
1
2
  import { cosmiconfigSync } from 'cosmiconfig';
2
- import parseJson from 'parse-json';
3
3
  import parseToml from '@iarna/toml/parse-string.js';
4
- import yaml from 'yaml';
5
4
  import _ from 'lodash';
6
5
  import isCI from 'is-ci';
7
- import _debug from 'debug';
8
6
  import { readJSON, getSystemInfo } from './util.js';
9
7
 
10
- const debug = _debug('release-it:config');
8
+ const debug = util.debug('release-it:config');
11
9
  const defaultConfig = readJSON(new URL('../config/release-it.json', import.meta.url));
12
10
 
13
11
  const searchPlaces = [
@@ -21,19 +19,17 @@ const searchPlaces = [
21
19
  ];
22
20
 
23
21
  const loaders = {
24
- '.json': (_, content) => parseJson(content),
25
- '.toml': (_, content) => parseToml(content),
26
- '.yaml': (_, content) => yaml.parse(content)
22
+ '.toml': (_, content) => parseToml(content)
27
23
  };
28
24
 
29
- const getLocalConfig = localConfigFile => {
25
+ const getLocalConfig = ({ file, dir = process.cwd() }) => {
30
26
  let localConfig = {};
31
- if (localConfigFile === false) return localConfig;
27
+ if (file === false) return localConfig;
32
28
  const explorer = cosmiconfigSync('release-it', {
33
29
  searchPlaces,
34
30
  loaders
35
31
  });
36
- const result = localConfigFile ? explorer.load(localConfigFile) : explorer.search();
32
+ const result = file ? explorer.load(file) : explorer.search(dir);
37
33
  if (result && typeof result.config === 'string') {
38
34
  throw new Error(`Invalid configuration file at ${result.filepath}`);
39
35
  }
@@ -44,7 +40,7 @@ const getLocalConfig = localConfigFile => {
44
40
  class Config {
45
41
  constructor(config = {}) {
46
42
  this.constructorConfig = config;
47
- this.localConfig = getLocalConfig(config.config);
43
+ this.localConfig = getLocalConfig({ file: config.config, dir: config.configDir });
48
44
  this.options = this.mergeOptions();
49
45
  this.options = this.expandPreReleaseShorthand(this.options);
50
46
  this.contextOptions = {};
@@ -123,10 +119,6 @@ class Config {
123
119
  get isReleaseVersion() {
124
120
  return Boolean(this.options['release-version']);
125
121
  }
126
-
127
- get isCollectMetrics() {
128
- return !this.options['disable-metrics'];
129
- }
130
122
  }
131
123
 
132
124
  export default Config;
package/lib/index.js CHANGED
@@ -5,9 +5,7 @@ import Config from './config.js';
5
5
  import Shell from './shell.js';
6
6
  import Prompt from './prompt.js';
7
7
  import Spinner from './spinner.js';
8
- import Metrics from './metrics.js';
9
8
  import { reduceUntil, parseVersion } from './util.js';
10
- import handleDeprecated from './deprecated.js';
11
9
  import Plugin from './plugin/Plugin.js';
12
10
 
13
11
  const runTasks = async (opts, di) => {
@@ -23,14 +21,11 @@ const runTasks = async (opts, di) => {
23
21
  container.log = container.log || new Logger({ isCI, isVerbose, verbosityLevel, isDryRun });
24
22
  container.spinner = container.spinner || new Spinner({ container, config });
25
23
  container.prompt = container.prompt || new Prompt({ container: { config } });
26
- container.metrics = new Metrics({ isEnabled: config.isCollectMetrics });
27
24
  container.shell = container.shell || new Shell({ container });
28
25
 
29
- const { log, metrics, shell, spinner } = container;
26
+ const { log, shell, spinner } = container;
30
27
 
31
- const options = handleDeprecated(config.getContext(), log);
32
-
33
- metrics.trackEvent('start', options);
28
+ const options = config.getContext();
34
29
 
35
30
  const { hooks } = options;
36
31
 
@@ -78,47 +73,49 @@ const runTasks = async (opts, di) => {
78
73
  version = latestVersion;
79
74
  }
80
75
 
81
- if (config.isReleaseVersion) {
82
- log.log(version);
83
- process.exit(0);
84
- }
85
-
86
76
  config.setContext({ name, latestVersion, version, changelog });
87
77
 
88
78
  const action = config.isIncrement ? 'release' : 'update';
89
79
  const suffix = version && config.isIncrement ? `${latestVersion}...${version}` : `currently at ${latestVersion}`;
90
80
 
91
- log.obtrusive(`🚀 Let's ${action} ${name} (${suffix})`);
81
+ if (!config.isReleaseVersion) {
82
+ log.obtrusive(`🚀 Let's ${action} ${name} (${suffix})`);
92
83
 
93
- log.preview({ title: 'changelog', text: changelog });
84
+ log.preview({ title: 'changelog', text: changelog });
85
+ }
94
86
 
95
87
  if (config.isIncrement) {
96
88
  version = version || (await reduceUntil(plugins, plugin => plugin.getIncrementedVersion(incrementBase)));
97
89
  }
98
90
 
99
- config.setContext(parseVersion(version));
100
-
101
- if (config.isPromptOnlyVersion) {
102
- config.setCI(true);
91
+ if (config.isReleaseVersion) {
92
+ console.log(version);
93
+ process.exit(0);
103
94
  }
104
95
 
105
- for (const hook of ['beforeBump', 'bump', 'beforeRelease']) {
106
- for (const plugin of plugins) {
107
- const args = hook === 'bump' ? [version] : [];
108
- await runLifeCycleHook(plugin, hook, ...args);
96
+ if (version) {
97
+ config.setContext(parseVersion(version));
98
+
99
+ if (config.isPromptOnlyVersion) {
100
+ config.setCI(true);
109
101
  }
110
- }
111
102
 
112
- plugins = [...internal, ...external];
103
+ for (const hook of ['beforeBump', 'bump', 'beforeRelease']) {
104
+ for (const plugin of plugins) {
105
+ const args = hook === 'bump' ? [version] : [];
106
+ await runLifeCycleHook(plugin, hook, ...args);
107
+ }
108
+ }
113
109
 
114
- for (const hook of ['release', 'afterRelease']) {
115
- for (const plugin of plugins) {
116
- await runLifeCycleHook(plugin, hook);
110
+ plugins = [...internal, ...external];
111
+
112
+ for (const hook of ['release', 'afterRelease']) {
113
+ for (const plugin of plugins) {
114
+ await runLifeCycleHook(plugin, hook);
115
+ }
117
116
  }
118
117
  }
119
118
 
120
- await metrics.trackEvent('end');
121
-
122
119
  log.log(`🏁 Done (in ${Math.floor(process.uptime())}s.)`);
123
120
 
124
121
  return {
@@ -128,10 +125,7 @@ const runTasks = async (opts, di) => {
128
125
  version
129
126
  };
130
127
  } catch (err) {
131
- const { log, metrics } = container;
132
- if (metrics) {
133
- await metrics.trackException(err);
134
- }
128
+ const { log } = container;
135
129
  log ? log.error(err.message || err) : console.error(err); // eslint-disable-line no-console
136
130
  throw err;
137
131
  }
package/lib/log.js CHANGED
@@ -1,4 +1,4 @@
1
- import { EOL } from 'os';
1
+ import { EOL } from 'node:os';
2
2
  import chalk from 'chalk';
3
3
  import _ from 'lodash';
4
4
 
@@ -1,4 +1,4 @@
1
- import { EOL } from 'os';
1
+ import { EOL } from 'node:os';
2
2
  import { format, parseGitUrl } from '../util.js';
3
3
  import Plugin from './Plugin.js';
4
4
 
@@ -12,7 +12,7 @@ class GitRelease extends GitBase {
12
12
  getInitialOptions(options) {
13
13
  const baseOptions = super.getInitialOptions(...arguments);
14
14
  const git = options.git || defaultConfig.git;
15
- const gitOptions = _.pick(git, ['tagName', 'pushRepo', 'changelog']);
15
+ const gitOptions = _.pick(git, ['tagName', 'tagMatch', 'pushRepo', 'changelog']);
16
16
  return _.defaults(baseOptions, gitOptions);
17
17
  }
18
18
 
@@ -1,4 +1,4 @@
1
- import debug from 'debug';
1
+ import { debug } from 'node:util';
2
2
  import _ from 'lodash';
3
3
 
4
4
  class Plugin {
@@ -1,15 +1,15 @@
1
- import url from 'url';
2
- import path from 'path';
3
- import { createRequire } from 'module';
1
+ import url from 'node:url';
2
+ import path from 'node:path';
3
+ import util from 'node:util';
4
+ import { createRequire } from 'node:module';
4
5
  import _ from 'lodash';
5
- import _debug from 'debug';
6
6
  import Version from './version/Version.js';
7
7
  import Git from './git/Git.js';
8
8
  import GitLab from './gitlab/GitLab.js';
9
9
  import GitHub from './github/GitHub.js';
10
10
  import npm from './npm/npm.js';
11
11
 
12
- const debug = _debug('release-it:plugins');
12
+ const debug = util.debug('release-it:plugins');
13
13
 
14
14
  const pluginNames = ['npm', 'git', 'github', 'gitlab', 'version'];
15
15
 
@@ -1,6 +1,7 @@
1
- import { EOL } from 'os';
1
+ import { EOL } from 'node:os';
2
2
  import _ from 'lodash';
3
3
  import { execa } from 'execa';
4
+ import matcher from 'wildcard-match';
4
5
  import { format, e } from '../../util.js';
5
6
  import GitBase from '../GitBase.js';
6
7
  import prompts from './prompts.js';
@@ -94,7 +95,7 @@ class Git extends GitBase {
94
95
  async isRequiredBranch() {
95
96
  const branch = await this.getBranchName();
96
97
  const requiredBranches = _.castArray(this.options.requireBranch);
97
- return requiredBranches.includes(branch);
98
+ return matcher(requiredBranches)(branch);
98
99
  }
99
100
 
100
101
  async hasUpstreamBranch() {
@@ -1,5 +1,5 @@
1
- import fs from 'fs';
2
- import path from 'path';
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
3
  import open from 'open';
4
4
  import { Octokit } from '@octokit/rest';
5
5
  import { globby } from 'globby';
@@ -7,6 +7,7 @@ import mime from 'mime-types';
7
7
  import _ from 'lodash';
8
8
  import retry from 'async-retry';
9
9
  import newGithubReleaseUrl from 'new-github-release-url';
10
+ import ProxyAgent from 'proxy-agent';
10
11
  import { format, parseVersion, readJSON, e } from '../../util.js';
11
12
  import Release from '../GitRelease.js';
12
13
  import prompts from './prompts.js';
@@ -38,7 +39,7 @@ class GitHub extends Release {
38
39
  async init() {
39
40
  await super.init();
40
41
 
41
- const { skipChecks, tokenRef, web, update } = this.options;
42
+ const { skipChecks, tokenRef, web, update, assets } = this.options;
42
43
 
43
44
  if (!this.token || web) {
44
45
  if (!web) {
@@ -49,6 +50,10 @@ class GitHub extends Release {
49
50
  return;
50
51
  }
51
52
 
53
+ if (web && assets) {
54
+ this.log.warn('Assets are not included in web-based releases.');
55
+ }
56
+
52
57
  if (!skipChecks) {
53
58
  // If we're running on GitHub Actions, we can skip the authentication and
54
59
  // collaborator checks. Ref: https://bit.ly/2vsyRzu
@@ -164,7 +169,7 @@ class GitHub extends Release {
164
169
  };
165
170
 
166
171
  if (proxy) {
167
- options.proxy = proxy;
172
+ options.request.agent = new ProxyAgent(proxy);
168
173
  }
169
174
 
170
175
  const client = new Octokit(options);
@@ -188,12 +193,12 @@ class GitHub extends Release {
188
193
 
189
194
  getOctokitReleaseOptions(options = {}) {
190
195
  const { owner, project: repo } = this.getContext('repo');
191
- const { releaseName, draft = false, preRelease = false } = this.options;
196
+ const { releaseName, draft = false, preRelease = false, autoGenerate = false } = this.options;
192
197
  const { tagName } = this.config.getContext();
193
- const { version, releaseNotes } = this.getContext();
198
+ const { version, releaseNotes, isUpdate } = this.getContext();
194
199
  const { isPreRelease } = parseVersion(version);
195
200
  const name = format(releaseName, this.config.getContext());
196
- const body = releaseNotes;
201
+ const body = autoGenerate ? (isUpdate ? null : '') : releaseNotes;
197
202
 
198
203
  return Object.assign(options, {
199
204
  owner,
@@ -202,7 +207,8 @@ class GitHub extends Release {
202
207
  name,
203
208
  body,
204
209
  draft,
205
- prerelease: isPreRelease || preRelease
210
+ prerelease: isPreRelease || preRelease,
211
+ generate_release_notes: autoGenerate
206
212
  });
207
213
  }
208
214
 
@@ -1,8 +1,9 @@
1
- import fs from 'fs';
2
- import path from 'path';
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
3
  import got from 'got';
4
4
  import { globby } from 'globby';
5
5
  import FormData from 'form-data';
6
+ import allSettled from 'promise.allsettled';
6
7
  import _ from 'lodash';
7
8
  import Release from '../GitRelease.js';
8
9
  import { format, e } from '../../util.js';
@@ -91,20 +92,68 @@ class GitLab extends Release {
91
92
  return access_level && access_level >= 30;
92
93
  } catch (err) {
93
94
  this.debug(err);
94
- if (err.name === 'HTTPError' && err.response.statusCode === 404) {
95
- // Using another endpoint, since "/projects/:id/members/all/:user_id" was introduced in v12.4
96
- const endpoint = `projects/${id}/members/${user.id}`;
97
- try {
98
- const { access_level } = await this.request(endpoint, { method: 'GET' });
99
- return access_level && access_level >= 30;
100
- } catch (err) {
101
- this.debug(err);
102
- return false;
95
+ return false;
96
+ }
97
+ }
98
+
99
+ async beforeRelease() {
100
+ await super.beforeRelease();
101
+ await this.checkReleaseMilestones();
102
+ }
103
+
104
+ async checkReleaseMilestones() {
105
+ if (this.options.skipChecks) return;
106
+
107
+ const releaseMilestones = this.getReleaseMilestones();
108
+ if (releaseMilestones.length < 1) {
109
+ return;
110
+ }
111
+
112
+ this.log.exec(`gitlab releases#checkReleaseMilestones`);
113
+
114
+ const { id } = this.getContext();
115
+ const endpoint = `projects/${id}/milestones`;
116
+ const requests = releaseMilestones.map(milestone => {
117
+ const options = {
118
+ method: 'GET',
119
+ searchParams: {
120
+ title: milestone,
121
+ include_parent_milestones: true
103
122
  }
104
- } else {
105
- return false;
106
- }
123
+ };
124
+ return this.request(endpoint, options).then(response => {
125
+ if (!Array.isArray(response)) {
126
+ const { baseUrl } = this.getContext();
127
+ throw new Error(
128
+ `Unexpected response from ${baseUrl}/${endpoint}. Expected an array but got: ${JSON.stringify(response)}`
129
+ );
130
+ }
131
+ if (response.length === 0) {
132
+ const error = new Error(`Milestone '${milestone}' does not exist.`);
133
+ this.log.warn(error.message);
134
+ throw error;
135
+ }
136
+ this.log.verbose(`gitlab releases#checkReleaseMilestones: milestone '${milestone}' exists`);
137
+ });
138
+ });
139
+ try {
140
+ await allSettled(requests).then(results => {
141
+ for (const result of results) {
142
+ if (result.status === 'rejected') {
143
+ throw e('Missing one or more milestones in GitLab. Creating a GitLab release will fail.', docs);
144
+ }
145
+ }
146
+ });
147
+ } catch (err) {
148
+ this.debug(err);
149
+ throw err;
107
150
  }
151
+ this.log.verbose('gitlab releases#checkReleaseMilestones: done');
152
+ }
153
+
154
+ getReleaseMilestones() {
155
+ const { milestones } = this.options;
156
+ return (milestones || []).map(milestone => format(milestone, this.config.getContext()));
108
157
  }
109
158
 
110
159
  async release() {
@@ -138,6 +187,7 @@ class GitLab extends Release {
138
187
  const name = format(releaseName, this.config.getContext());
139
188
  const description = releaseNotes || '-';
140
189
  const releaseUrl = `${origin}/${repo.repository}/-/releases`;
190
+ const releaseMilestones = this.getReleaseMilestones();
141
191
 
142
192
  this.log.exec(`gitlab releases#createRelease "${name}" (${tagName})`, { isDryRun });
143
193
 
@@ -161,6 +211,10 @@ class GitLab extends Release {
161
211
  };
162
212
  }
163
213
 
214
+ if (releaseMilestones.length) {
215
+ options.json.milestones = releaseMilestones;
216
+ }
217
+
164
218
  try {
165
219
  await this.request(endpoint, options);
166
220
  this.log.verbose('gitlab releases#createRelease: done');
@@ -1,4 +1,4 @@
1
- import path from 'path';
1
+ import path from 'node:path';
2
2
  import semver from 'semver';
3
3
  import urlJoin from 'url-join';
4
4
  import Plugin from '../Plugin.js';
@@ -82,7 +82,8 @@ class npm extends Plugin {
82
82
 
83
83
  if (!this.config.isIncrement) return false;
84
84
 
85
- const task = () => this.exec(`npm version ${version} --no-git-tag-version`);
85
+ const allowSameVersion = this.options.allowSameVersion ? ' --allow-same-version' : '';
86
+ const task = () => this.exec(`npm version ${version} --no-git-tag-version${allowSameVersion}`);
86
87
  return this.spinner.show({ task, label: 'npm version' });
87
88
  }
88
89
 
@@ -106,7 +106,11 @@ class Version extends Plugin {
106
106
  }
107
107
 
108
108
  if (this.config.isCI && !increment) {
109
- return semver.inc(latestVersion, 'patch');
109
+ if (isPreRelease) {
110
+ return semver.inc(latestVersion, 'prepatch', preReleaseId);
111
+ } else {
112
+ return semver.inc(latestVersion, 'patch');
113
+ }
110
114
  }
111
115
 
112
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
3
  import { execa } from 'execa';
3
- import _debug from 'debug';
4
4
  import { format } from './util.js';
5
5
 
6
- const debug = _debug('release-it:shell');
6
+ const debug = util.debug('release-it:shell');
7
7
 
8
8
  sh.config.silent = !debug.enabled;
9
9
 
package/lib/util.js CHANGED
@@ -1,5 +1,5 @@
1
- import fs from 'fs';
2
- import { EOL } from 'os';
1
+ import fs from 'node:fs';
2
+ import { EOL } from 'node:os';
3
3
  import _ from 'lodash';
4
4
  import gitUrlParse from 'git-url-parse';
5
5
  import semver from 'semver';