release-it 14.11.7 → 14.12.2

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
@@ -321,17 +321,18 @@ While mostly used as a CLI tool, release-it can be used as a dependency to integ
321
321
  - [blockchain/blockchain-wallet-v4-frontend](https://github.com/blockchain/blockchain-wallet-v4-frontend)
322
322
  - [callstack/linaria](https://github.com/callstack/linaria)
323
323
  - [ember-cli/ember-cli](https://github.com/ember-cli/ember-cli)
324
+ - [metalsmith/metalsmith](https://github.com/metalsmith/metalsmith)
324
325
  - [react-native-paper](https://github.com/callstack/react-native-paper)
325
326
  - [js-cookie/js-cookie](https://github.com/js-cookie/js-cookie)
326
327
  - [mirumee/saleor](https://github.com/mirumee/saleor)
327
328
  - [mozilla/readability](https://github.com/mozilla/readability)
328
- - [satya164/react-native-tab-view](https://github.com/satya164/react-native-tab-view)
329
+ - [redis/node-redis](https://github.com/redis/node-redis)
329
330
  - [shipshapecode/shepherd](https://github.com/shipshapecode/shepherd)
330
331
  - [swagger-api/swagger-ui](https://github.com/swagger-api/swagger-ui) +
331
332
  [swagger-editor](https://github.com/swagger-api/swagger-editor)
332
333
  - [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)
334
+ - [tabler/tabler](https://github.com/tabler/tabler) + [tabler-icons](https://github.com/tabler/tabler-icons)
335
+ - [youzan/vant](https://github.com/youzan/vant)
335
336
  - [Repositories that depend on release-it](https://github.com/release-it/release-it/network/dependents)
336
337
  - GitHub search for [filename:.release-it.json](https://github.com/search?q=filename%3A.release-it.json)
337
338
 
@@ -33,6 +33,7 @@
33
33
  "release": false,
34
34
  "releaseName": "Release ${version}",
35
35
  "releaseNotes": null,
36
+ "autoGenerate": false,
36
37
  "preRelease": false,
37
38
  "draft": false,
38
39
  "tokenRef": "GITHUB_TOKEN",
@@ -37,7 +37,7 @@ class GitHub extends Release {
37
37
  async init() {
38
38
  await super.init();
39
39
 
40
- const { skipChecks, tokenRef, web, update } = this.options;
40
+ const { skipChecks, tokenRef, web, update, assets } = this.options;
41
41
 
42
42
  if (!this.token || web) {
43
43
  if (!web) {
@@ -48,6 +48,10 @@ class GitHub extends Release {
48
48
  return;
49
49
  }
50
50
 
51
+ if (web && assets) {
52
+ this.log.warn('Assets are not included in web-based releases.');
53
+ }
54
+
51
55
  if (!skipChecks) {
52
56
  // If we're running on GitHub Actions, we can skip the authentication and
53
57
  // collaborator checks. Ref: https://bit.ly/2vsyRzu
@@ -187,12 +191,12 @@ class GitHub extends Release {
187
191
 
188
192
  getOctokitReleaseOptions(options = {}) {
189
193
  const { owner, project: repo } = this.getContext('repo');
190
- const { releaseName, draft = false, preRelease = false } = this.options;
194
+ const { releaseName, draft = false, preRelease = false, autoGenerate = false } = this.options;
191
195
  const { tagName } = this.config.getContext();
192
196
  const { version, releaseNotes } = this.getContext();
193
197
  const { isPreRelease } = parseVersion(version);
194
198
  const name = format(releaseName, this.config.getContext());
195
- const body = releaseNotes;
199
+ const body = autoGenerate ? '' : releaseNotes || '';
196
200
 
197
201
  return Object.assign(options, {
198
202
  owner,
@@ -201,7 +205,8 @@ class GitHub extends Release {
201
205
  name,
202
206
  body,
203
207
  draft,
204
- prerelease: isPreRelease || preRelease
208
+ prerelease: isPreRelease || preRelease,
209
+ generate_release_notes: autoGenerate
205
210
  });
206
211
  }
207
212
 
@@ -295,8 +300,11 @@ class GitHub extends Release {
295
300
  }
296
301
 
297
302
  generateWebUrl() {
303
+ const host = this.options.host || this.getContext('repo.host');
304
+ const isGitHub = host === 'github.com';
305
+
298
306
  const options = this.getOctokitReleaseOptions();
299
- return newGithubReleaseUrl({
307
+ const url = newGithubReleaseUrl({
300
308
  user: options.owner,
301
309
  repo: options.repo,
302
310
  tag: options.tag_name,
@@ -304,6 +312,7 @@ class GitHub extends Release {
304
312
  title: options.name,
305
313
  body: options.body
306
314
  });
315
+ return isGitHub ? url : url.replace('github.com', host);
307
316
  }
308
317
 
309
318
  async createWebRelease() {
@@ -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/tasks.js CHANGED
@@ -65,7 +65,7 @@ const runTasks = async (opts, di) => {
65
65
 
66
66
  const name = await reduceUntil(plugins, plugin => plugin.getName());
67
67
  const latestVersion = (await reduceUntil(plugins, plugin => plugin.getLatestVersion())) || '0.0.0';
68
- const changelog = await reduceUntil(plugins, plugin => plugin.getChangelog());
68
+ const changelog = await reduceUntil(plugins, plugin => plugin.getChangelog(latestVersion));
69
69
 
70
70
  const incrementBase = { latestVersion, increment, isPreRelease, preReleaseId };
71
71
 
@@ -77,24 +77,26 @@ const runTasks = async (opts, di) => {
77
77
  version = latestVersion;
78
78
  }
79
79
 
80
- if (config.isReleaseVersion) {
81
- log.log(version);
82
- process.exit(0);
83
- }
84
-
85
80
  config.setContext({ name, latestVersion, version, changelog });
86
81
 
87
82
  const action = config.isIncrement ? 'release' : 'update';
88
83
  const suffix = version && config.isIncrement ? `${latestVersion}...${version}` : `currently at ${latestVersion}`;
89
84
 
90
- log.obtrusive(`🚀 Let's ${action} ${name} (${suffix})`);
85
+ if (!config.isReleaseVersion) {
86
+ log.obtrusive(`🚀 Let's ${action} ${name} (${suffix})`);
91
87
 
92
- log.preview({ title: 'changelog', text: changelog });
88
+ log.preview({ title: 'changelog', text: changelog });
89
+ }
93
90
 
94
91
  if (config.isIncrement) {
95
92
  version = version || (await reduceUntil(plugins, plugin => plugin.getIncrementedVersion(incrementBase)));
96
93
  }
97
94
 
95
+ if (config.isReleaseVersion) {
96
+ console.log(version);
97
+ process.exit(0);
98
+ }
99
+
98
100
  config.setContext(parseVersion(version));
99
101
 
100
102
  if (config.isPromptOnlyVersion) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "release-it",
3
- "version": "14.11.7",
3
+ "version": "14.12.2",
4
4
  "description": "Generic CLI tool to automate versioning and package publishing related tasks.",
5
5
  "keywords": [
6
6
  "build",
@@ -58,22 +58,22 @@
58
58
  "license": "MIT",
59
59
  "dependencies": {
60
60
  "@iarna/toml": "2.2.5",
61
- "@octokit/rest": "18.10.0",
61
+ "@octokit/rest": "18.12.0",
62
62
  "async-retry": "1.3.3",
63
63
  "chalk": "4.1.2",
64
64
  "cosmiconfig": "7.0.1",
65
- "debug": "4.3.2",
65
+ "debug": "4.3.3",
66
66
  "deprecated-obj": "2.0.0",
67
67
  "execa": "5.1.1",
68
68
  "form-data": "4.0.0",
69
69
  "git-url-parse": "11.6.0",
70
70
  "globby": "11.0.4",
71
- "got": "11.8.2",
71
+ "got": "11.8.3",
72
72
  "import-cwd": "3.0.0",
73
- "inquirer": "8.1.5",
74
- "is-ci": "3.0.0",
73
+ "inquirer": "8.2.0",
74
+ "is-ci": "3.0.1",
75
75
  "lodash": "4.17.21",
76
- "mime-types": "2.1.32",
76
+ "mime-types": "2.1.34",
77
77
  "new-github-release-url": "1.0.0",
78
78
  "open": "7.4.2",
79
79
  "ora": "5.4.1",
@@ -91,19 +91,19 @@
91
91
  "@octokit/request-error": "2.1.0",
92
92
  "ava": "3.15.0",
93
93
  "codecov": "3.8.3",
94
- "eslint": "7.32.0",
94
+ "eslint": "8.6.0",
95
95
  "eslint-config-prettier": "8.3.0",
96
- "eslint-plugin-ava": "12.0.0",
97
- "eslint-plugin-import": "2.24.2",
98
- "eslint-plugin-prettier": "3.4.0",
96
+ "eslint-plugin-ava": "13.2.0",
97
+ "eslint-plugin-import": "2.25.4",
98
+ "eslint-plugin-prettier": "4.0.0",
99
99
  "markdown-toc": "1.2.0",
100
- "mock-fs": "5.1.0",
100
+ "mock-fs": "5.1.2",
101
101
  "mock-stdio": "1.0.3",
102
- "nock": "13.1.3",
102
+ "nock": "13.2.1",
103
103
  "nyc": "15.1.0",
104
- "prettier": "2.4.1",
104
+ "prettier": "2.5.1",
105
105
  "proxyquire": "2.1.3",
106
- "sinon": "11.1.2",
106
+ "sinon": "12.0.1",
107
107
  "strip-ansi": "6.0.0"
108
108
  },
109
109
  "engines": {
package/test/github.js CHANGED
@@ -15,7 +15,7 @@ const {
15
15
  const tokenRef = 'GITHUB_TOKEN';
16
16
  const pushRepo = 'git://github.com:user/repo';
17
17
  const host = 'github.com';
18
- const git = { changelog: null };
18
+ const git = { changelog: '' };
19
19
  const requestErrorOptions = { request: { url: '', headers: {} }, response: { headers: {} } };
20
20
 
21
21
  test.serial('should check token and perform checks', async t => {
@@ -89,7 +89,36 @@ test('should create a pre-release and draft release notes', async t => {
89
89
 
90
90
  interceptAuthentication();
91
91
  interceptCollaborator();
92
- interceptCreate({ body: { tag_name: '2.0.2', name: 'Release 2.0.2', body: null, prerelease: true, draft: true } });
92
+ interceptCreate({ body: { tag_name: '2.0.2', name: 'Release 2.0.2', body: '', prerelease: true, draft: true } });
93
+
94
+ await runTasks(github);
95
+
96
+ const { isReleased, releaseUrl } = github.getContext();
97
+ t.true(isReleased);
98
+ t.is(releaseUrl, 'https://github.com/user/repo/releases/tag/2.0.2');
99
+ exec.restore();
100
+ });
101
+
102
+ test('should create auto generated release notes', async t => {
103
+ const options = {
104
+ git,
105
+ github: {
106
+ pushRepo,
107
+ tokenRef,
108
+ release: true,
109
+ releaseName: 'Release ${tagName}',
110
+ autoGenerate: true
111
+ }
112
+ };
113
+ const github = factory(GitHub, { options });
114
+ const exec = sinon.stub(github.shell, 'exec').callThrough();
115
+ exec.withArgs('git describe --tags --match=* --abbrev=0').resolves('2.0.1');
116
+
117
+ interceptAuthentication();
118
+ interceptCollaborator();
119
+ interceptCreate({
120
+ body: { tag_name: '2.0.2', name: 'Release 2.0.2', draft: false, prerelease: false, generate_release_notes: true }
121
+ });
93
122
 
94
123
  await runTasks(github);
95
124
 
@@ -215,7 +244,7 @@ test('should release to alternative host and proxy', async t => {
215
244
  test('should release to git.pushRepo', async t => {
216
245
  const remote = { api: 'https://my-custom-host.org/api/v3', host: 'my-custom-host.org' };
217
246
  interceptCreate(Object.assign({ body: { tag_name: '1.0.1' } }, remote));
218
- const options = { git: { pushRepo: 'upstream', changelog: null }, github: { tokenRef, skipChecks: true } };
247
+ const options = { git: { pushRepo: 'upstream', changelog: '' }, github: { tokenRef, skipChecks: true } };
219
248
  const github = factory(GitHub, { options });
220
249
  const exec = sinon.stub(github.shell, 'exec').callThrough();
221
250
  exec.withArgs('git describe --tags --match=* --abbrev=0').resolves('1.0.0');
@@ -353,3 +382,30 @@ test('should generate GitHub web release url', async t => {
353
382
  );
354
383
  exec.restore();
355
384
  });
385
+
386
+ test('should generate GitHub web release url for enterprise host', async t => {
387
+ const options = {
388
+ git,
389
+ github: {
390
+ pushRepo: 'git://my-custom-host.org:user/repo',
391
+ release: true,
392
+ web: true,
393
+ host: 'my-custom-host.org',
394
+ releaseName: 'The Launch',
395
+ releaseNotes: 'echo It happened'
396
+ }
397
+ };
398
+ const github = factory(GitHub, { options });
399
+ const exec = sinon.stub(github.shell, 'exec').callThrough();
400
+ exec.withArgs('git describe --tags --match=* --abbrev=0').resolves('2.0.1');
401
+
402
+ await runTasks(github);
403
+
404
+ const { isReleased, releaseUrl } = github.getContext();
405
+ t.true(isReleased);
406
+ t.is(
407
+ releaseUrl,
408
+ 'https://my-custom-host.org/user/repo/releases/new?tag=2.0.2&title=The+Launch&body=It+happened&prerelease=false'
409
+ );
410
+ exec.restore();
411
+ });
@@ -1,16 +1,19 @@
1
1
  const nock = require('nock');
2
2
 
3
- const interceptAuthentication = ({ api = 'https://api.github.com', username = 'john' } = {}) =>
3
+ const interceptAuthentication = ({ api = 'https://api.github.com', username = 'john' } = {}) => {
4
4
  nock(api).get('/user').reply(200, {
5
5
  login: username
6
6
  });
7
+ };
7
8
 
8
9
  const interceptCollaborator = ({
9
10
  api = 'https://api.github.com',
10
11
  owner = 'user',
11
12
  project = 'repo',
12
13
  username = 'john'
13
- } = {}) => nock(api).get(`/repos/${owner}/${project}/collaborators/${username}`).reply(204);
14
+ } = {}) => {
15
+ nock(api).get(`/repos/${owner}/${project}/collaborators/${username}`).reply(204);
16
+ };
14
17
 
15
18
  const interceptListReleases = ({
16
19
  host = 'github.com',
@@ -18,7 +21,7 @@ const interceptListReleases = ({
18
21
  owner = 'user',
19
22
  project = 'repo',
20
23
  tag_name
21
- } = {}) =>
24
+ } = {}) => {
22
25
  nock(api)
23
26
  .get(`/repos/${owner}/${project}/releases?per_page=1&page=1`)
24
27
  .reply(200, [
@@ -34,16 +37,24 @@ const interceptListReleases = ({
34
37
  prerelease: false
35
38
  }
36
39
  ]);
40
+ };
37
41
 
38
42
  const interceptCreate = ({
39
43
  api = 'https://api.github.com',
40
44
  host = 'github.com',
41
45
  owner = 'user',
42
46
  project = 'repo',
43
- body: { tag_name, name = '', body = null, prerelease = false, draft = false }
44
- } = {}) =>
47
+ body: { tag_name, name = '', body = '', prerelease = false, draft = false, generate_release_notes = false }
48
+ } = {}) => {
45
49
  nock(api)
46
- .post(`/repos/${owner}/${project}/releases`, { tag_name, name, body, prerelease, draft })
50
+ .post(`/repos/${owner}/${project}/releases`, {
51
+ tag_name,
52
+ name,
53
+ body,
54
+ prerelease,
55
+ draft,
56
+ generate_release_notes
57
+ })
47
58
  .reply(() => {
48
59
  const id = 1;
49
60
  const responseBody = {
@@ -53,21 +64,23 @@ const interceptCreate = ({
53
64
  body,
54
65
  prerelease,
55
66
  draft,
67
+ generate_release_notes,
56
68
  upload_url: `https://uploads.${host}/repos/${owner}/${project}/releases/${id}/assets{?name,label}`,
57
69
  html_url: `https://${host}/${owner}/${project}/releases/tag/${tag_name}`
58
70
  };
59
71
  return [200, responseBody, { location: `${api}/repos/${owner}/${project}/releases/${id}` }];
60
72
  });
73
+ };
61
74
 
62
75
  const interceptUpdate = ({
63
76
  host = 'github.com',
64
77
  api = 'https://api.github.com',
65
78
  owner = 'user',
66
79
  project = 'repo',
67
- body: { tag_name, name = '', body = null, prerelease = false, draft = false }
68
- } = {}) =>
80
+ body: { tag_name, name = '', body = '', prerelease = false, draft = false, generate_release_notes = false }
81
+ } = {}) => {
69
82
  nock(api)
70
- .patch(`/repos/${owner}/${project}/releases/1`, { tag_name, name, body, draft, prerelease })
83
+ .patch(`/repos/${owner}/${project}/releases/1`, { tag_name, name, body, draft, prerelease, generate_release_notes })
71
84
  .reply(200, {
72
85
  id: 1,
73
86
  tag_name,
@@ -75,9 +88,11 @@ const interceptUpdate = ({
75
88
  body,
76
89
  prerelease,
77
90
  draft,
91
+ generate_release_notes,
78
92
  upload_url: `https://uploads.${host}/repos/${owner}/${project}/releases/1/assets{?name,label}`,
79
93
  html_url: `https://${host}/${owner}/${project}/releases/tag/${tag_name}`
80
94
  });
95
+ };
81
96
 
82
97
  const interceptAsset = ({
83
98
  api = 'https://api.github.com',
@@ -86,7 +101,7 @@ const interceptAsset = ({
86
101
  project = 'repo',
87
102
  tagName,
88
103
  body = {}
89
- } = {}) =>
104
+ } = {}) => {
90
105
  nock(`https://uploads.${host}`)
91
106
  .post(`/repos/${owner}/${project}/releases/1/assets`, body)
92
107
  .query(true)
@@ -103,6 +118,7 @@ const interceptAsset = ({
103
118
  browser_download_url: `https://${host}/${owner}/${project}/releases/download/${tagName}/${name}`
104
119
  };
105
120
  });
121
+ };
106
122
 
107
123
  module.exports = {
108
124
  interceptAuthentication,
@@ -30,23 +30,14 @@ module.exports.factory = (Definition, { namespace, options = {}, container = {}
30
30
  });
31
31
  };
32
32
 
33
- const getIncrement = (plugin, { latestVersion }) => {
34
- return (
35
- plugin.getIncrement({
36
- latestVersion,
37
- increment: plugin.options.increment,
38
- isPreRelease: false,
39
- preReleaseId: null
40
- }) ||
41
- plugin.getContext('increment') ||
42
- plugin.config.getContext('increment')
43
- );
44
- };
33
+ const getIncrement = plugin =>
34
+ plugin.getIncrement(plugin.options) || plugin.getContext('increment') || plugin.config.getContext('increment');
45
35
 
46
- const getVersion = async (plugin, { latestVersion, increment }) => {
36
+ const getVersion = async (plugin, options) => {
37
+ const { latestVersion, increment } = options;
47
38
  return (
48
- (await plugin.getIncrementedVersionCI({ latestVersion, increment })) ||
49
- (await plugin.getIncrementedVersion({ latestVersion, increment })) ||
39
+ (await plugin.getIncrementedVersionCI(options)) ||
40
+ (await plugin.getIncrementedVersion(options)) ||
50
41
  (increment !== false ? semver.inc(latestVersion, increment || 'patch') : latestVersion)
51
42
  );
52
43
  };
@@ -56,12 +47,15 @@ module.exports.runTasks = async plugin => {
56
47
 
57
48
  const name = (await plugin.getName()) || '__test__';
58
49
  const latestVersion = (await plugin.getLatestVersion()) || '1.0.0';
59
- const changelog = (await plugin.getChangelog()) || null;
60
- const increment = getIncrement(plugin, { latestVersion });
50
+ const changelog = (await plugin.getChangelog(latestVersion)) || null;
51
+ const increment = getIncrement(plugin);
61
52
 
62
53
  plugin.config.setContext({ name, latestVersion, latestTag: latestVersion, changelog });
63
54
 
64
- const version = await getVersion(plugin, { latestVersion, increment });
55
+ const { preRelease } = plugin.config.options;
56
+ const isPreRelease = Boolean(preRelease);
57
+ const preReleaseId = typeof preRelease === 'string' ? preRelease : null;
58
+ const version = await getVersion(plugin, { latestVersion, increment, isPreRelease, preReleaseId });
65
59
 
66
60
  plugin.config.setContext(parseVersion(version));
67
61
 
package/test/version.js CHANGED
@@ -148,17 +148,22 @@ test('should run tasks without errors', async t => {
148
148
  await runTasks(v);
149
149
 
150
150
  t.is(getIncrement.callCount, 1);
151
- t.deepEqual(getIncrement.firstCall.args[0], {
151
+ t.deepEqual(getIncrement.firstCall.args[0], { increment: 'minor' });
152
+ t.is(getIncrementedVersionCI.callCount, 1);
153
+ t.deepEqual(getIncrementedVersionCI.firstCall.args[0], {
152
154
  latestVersion: '1.0.0',
153
155
  increment: 'minor',
154
156
  isPreRelease: false,
155
157
  preReleaseId: null
156
158
  });
157
- t.is(getIncrementedVersionCI.callCount, 1);
158
- t.deepEqual(getIncrementedVersionCI.firstCall.args[0], { latestVersion: '1.0.0', increment: 'minor' });
159
159
  t.is(await incrementVersion.firstCall.returnValue, '1.1.0');
160
160
  t.is(incrementVersion.callCount, 1);
161
- t.deepEqual(incrementVersion.firstCall.args[0], { latestVersion: '1.0.0', increment: 'minor' });
161
+ t.deepEqual(incrementVersion.firstCall.args[0], {
162
+ latestVersion: '1.0.0',
163
+ increment: 'minor',
164
+ isPreRelease: false,
165
+ preReleaseId: null
166
+ });
162
167
  t.is(incrementVersion.firstCall.returnValue, '1.1.0');
163
168
  const { latestVersion, version, isPreRelease, preReleaseId } = v.config.getContext();
164
169
  t.is(latestVersion, '1.0.0');