release-it 14.11.7-caret.0 → 14.12.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
@@ -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
- [react-native-paper](https://github.com/callstack/react-native-paper)
324
+ - [metalsmith/metalsmith](https://github.com/metalsmith/metalsmith)
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",
@@ -22,7 +22,7 @@ const parseErrormsg = err => {
22
22
  let msg = err;
23
23
  if (err instanceof Error) {
24
24
  const { status, message } = err;
25
- const { headers } = err.response;
25
+ const headers = err.response ? err.response.headers : {};
26
26
  msg = `${_.get(headers, 'status', status)} (${message})`;
27
27
  }
28
28
  return msg;
@@ -187,12 +187,12 @@ class GitHub extends Release {
187
187
 
188
188
  getOctokitReleaseOptions(options = {}) {
189
189
  const { owner, project: repo } = this.getContext('repo');
190
- const { releaseName, draft = false, preRelease = false } = this.options;
190
+ const { releaseName, draft = false, preRelease = false, autoGenerate = false } = this.options;
191
191
  const { tagName } = this.config.getContext();
192
192
  const { version, releaseNotes } = this.getContext();
193
193
  const { isPreRelease } = parseVersion(version);
194
194
  const name = format(releaseName, this.config.getContext());
195
- const body = releaseNotes;
195
+ const body = autoGenerate ? null : releaseNotes;
196
196
 
197
197
  return Object.assign(options, {
198
198
  owner,
@@ -201,7 +201,8 @@ class GitHub extends Release {
201
201
  name,
202
202
  body,
203
203
  draft,
204
- prerelease: isPreRelease || preRelease
204
+ prerelease: isPreRelease || preRelease,
205
+ generate_release_notes: autoGenerate
205
206
  });
206
207
  }
207
208
 
@@ -295,8 +296,11 @@ class GitHub extends Release {
295
296
  }
296
297
 
297
298
  generateWebUrl() {
299
+ const host = this.options.host || this.getContext('repo.host');
300
+ const isGitHub = host === 'github.com';
301
+
298
302
  const options = this.getOctokitReleaseOptions();
299
- return newGithubReleaseUrl({
303
+ const url = newGithubReleaseUrl({
300
304
  user: options.owner,
301
305
  repo: options.repo,
302
306
  tag: options.tag_name,
@@ -304,6 +308,7 @@ class GitHub extends Release {
304
308
  title: options.name,
305
309
  body: options.body
306
310
  });
311
+ return isGitHub ? url : url.replace('github.com', host);
307
312
  }
308
313
 
309
314
  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
@@ -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-caret.0",
3
+ "version": "14.12.1",
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
@@ -99,6 +99,35 @@ test('should create a pre-release and draft release notes', async t => {
99
99
  exec.restore();
100
100
  });
101
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
+ });
122
+
123
+ await runTasks(github);
124
+
125
+ const { isReleased, releaseUrl } = github.getContext();
126
+ t.true(isReleased);
127
+ t.is(releaseUrl, 'https://github.com/user/repo/releases/tag/2.0.2');
128
+ exec.restore();
129
+ });
130
+
102
131
  test('should update release and upload assets', async t => {
103
132
  const asset = 'file1';
104
133
  const options = {
@@ -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
+ });
@@ -40,10 +40,17 @@ const interceptCreate = ({
40
40
  host = 'github.com',
41
41
  owner = 'user',
42
42
  project = 'repo',
43
- body: { tag_name, name = '', body = null, prerelease = false, draft = false }
43
+ body: { tag_name, name = '', body = null, prerelease = false, draft = false, generate_release_notes = false }
44
44
  } = {}) =>
45
45
  nock(api)
46
- .post(`/repos/${owner}/${project}/releases`, { tag_name, name, body, prerelease, draft })
46
+ .post(`/repos/${owner}/${project}/releases`, {
47
+ tag_name,
48
+ name,
49
+ body,
50
+ prerelease,
51
+ draft,
52
+ generate_release_notes
53
+ })
47
54
  .reply(() => {
48
55
  const id = 1;
49
56
  const responseBody = {
@@ -53,6 +60,7 @@ const interceptCreate = ({
53
60
  body,
54
61
  prerelease,
55
62
  draft,
63
+ generate_release_notes,
56
64
  upload_url: `https://uploads.${host}/repos/${owner}/${project}/releases/${id}/assets{?name,label}`,
57
65
  html_url: `https://${host}/${owner}/${project}/releases/tag/${tag_name}`
58
66
  };
@@ -64,10 +72,10 @@ const interceptUpdate = ({
64
72
  api = 'https://api.github.com',
65
73
  owner = 'user',
66
74
  project = 'repo',
67
- body: { tag_name, name = '', body = null, prerelease = false, draft = false }
75
+ body: { tag_name, name = '', body = null, prerelease = false, draft = false, generate_release_notes = false }
68
76
  } = {}) =>
69
77
  nock(api)
70
- .patch(`/repos/${owner}/${project}/releases/1`, { tag_name, name, body, draft, prerelease })
78
+ .patch(`/repos/${owner}/${project}/releases/1`, { tag_name, name, body, draft, prerelease, generate_release_notes })
71
79
  .reply(200, {
72
80
  id: 1,
73
81
  tag_name,
@@ -75,6 +83,7 @@ const interceptUpdate = ({
75
83
  body,
76
84
  prerelease,
77
85
  draft,
86
+ generate_release_notes,
78
87
  upload_url: `https://uploads.${host}/repos/${owner}/${project}/releases/1/assets{?name,label}`,
79
88
  html_url: `https://${host}/${owner}/${project}/releases/tag/${tag_name}`
80
89
  });
package/test/tasks.js CHANGED
@@ -397,6 +397,47 @@ test.serial('should propagate errors', async t => {
397
397
  t.is(log.error.callCount, 1);
398
398
  });
399
399
 
400
+ test.serial('should use custom changelog command with context', async t => {
401
+ const { bare } = t.context;
402
+ const project = path.basename(bare);
403
+ const owner = path.basename(path.dirname(bare));
404
+ sh.exec('git tag v1.0.0');
405
+ gitAdd('line', 'file', 'More file');
406
+
407
+ interceptGitHubAuthentication();
408
+ interceptGitHubCollaborator({ owner, project });
409
+ interceptGitHubCreate({
410
+ owner,
411
+ project,
412
+ body: {
413
+ tag_name: 'v1.1.0',
414
+ name: 'Release 1.1.0',
415
+ body: 'custom-changelog-generator --from=v1.0.0 --to=v1.1.0',
416
+ draft: false,
417
+ prerelease: false
418
+ }
419
+ });
420
+
421
+ const container = getContainer({
422
+ increment: 'minor',
423
+ github: {
424
+ release: true,
425
+ releaseNotes: 'echo custom-changelog-generator --from=${latestTag} --to=${tagName}',
426
+ pushRepo: `https://github.com/${owner}/${project}`
427
+ }
428
+ });
429
+
430
+ const exec = sinon.spy(container.shell, 'execStringCommand');
431
+
432
+ await runTasks({}, container);
433
+
434
+ const command = exec.args.find(([command]) => command.includes('custom-changelog-generator'));
435
+
436
+ t.is(command[0], 'echo custom-changelog-generator --from=v1.0.0 --to=v1.1.0');
437
+
438
+ exec.restore();
439
+ });
440
+
400
441
  {
401
442
  class MyPlugin extends Plugin {}
402
443
  const statics = { isEnabled: () => true, disablePlugin: () => null };
@@ -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
  };
@@ -57,11 +48,14 @@ module.exports.runTasks = async plugin => {
57
48
  const name = (await plugin.getName()) || '__test__';
58
49
  const latestVersion = (await plugin.getLatestVersion()) || '1.0.0';
59
50
  const changelog = (await plugin.getChangelog(latestVersion)) || null;
60
- const increment = getIncrement(plugin, { latestVersion });
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');