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

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
@@ -156,19 +156,18 @@ remote.
156
156
 
157
157
  ## GitHub Releases
158
158
 
159
- The "Releases" tab on GitHub projects links to a page to store the changelog cq. release notes. To add
159
+ GitHub projects can have releases attached to Git tags, containing release notes and assets. There are two ways to add
160
160
  [GitHub releases](https://help.github.com/articles/creating-releases) in your release-it flow:
161
161
 
162
- - Configure `github.release: true`
163
- - Obtain a [personal access token](https://github.com/settings/tokens/new?scopes=repo&description=release-it)
164
- (release-it only needs "repo" access; no "admin" or other scopes).
165
- - Make sure the token is [available as an environment variable](./docs/environment-variables.md).
162
+ 1. Automated (requires a `GITHUB_TOKEN`)
163
+ 2. Manual (using the GitHub web interface with pre-populated fields)
166
164
 
167
165
  → See [GitHub Releases](./docs/github-releases.md) for more details.
168
166
 
169
167
  ## GitLab Releases
170
168
 
171
- [GitLab releases](https://docs.gitlab.com/ce/user/project/releases/) work just like GitHub releases:
169
+ GitLab projects can have releases attached to Git tags, containing release notes and assets. To automate
170
+ [GitLab releases](https://docs.gitlab.com/ce/user/project/releases/):
172
171
 
173
172
  - Configure `gitlab.release: true`
174
173
  - Obtain a [personal access token](https://gitlab.com/profile/personal_access_tokens) (release-it only needs the "api"
@@ -322,7 +321,7 @@ While mostly used as a CLI tool, release-it can be used as a dependency to integ
322
321
  - [blockchain/blockchain-wallet-v4-frontend](https://github.com/blockchain/blockchain-wallet-v4-frontend)
323
322
  - [callstack/linaria](https://github.com/callstack/linaria)
324
323
  - [ember-cli/ember-cli](https://github.com/ember-cli/ember-cli)
325
- [react-native-paper](https://github.com/callstack/react-native-paper)
324
+ - [react-native-paper](https://github.com/callstack/react-native-paper)
326
325
  - [js-cookie/js-cookie](https://github.com/js-cookie/js-cookie)
327
326
  - [mirumee/saleor](https://github.com/mirumee/saleor)
328
327
  - [mozilla/readability](https://github.com/mozilla/readability)
@@ -40,7 +40,8 @@
40
40
  "host": null,
41
41
  "timeout": 0,
42
42
  "proxy": null,
43
- "skipChecks": false
43
+ "skipChecks": false,
44
+ "web": false
44
45
  },
45
46
  "gitlab": {
46
47
  "release": false,
package/lib/index.js CHANGED
@@ -65,7 +65,7 @@ const runTasks = async (opts, di) => {
65
65
  const { increment, isPreRelease, preReleaseId } = options.version;
66
66
 
67
67
  const name = await reduceUntil(plugins, plugin => plugin.getName());
68
- const latestVersion = await reduceUntil(plugins, plugin => plugin.getLatestVersion());
68
+ const latestVersion = (await reduceUntil(plugins, plugin => plugin.getLatestVersion())) || '0.0.0';
69
69
  const changelog = await reduceUntil(plugins, plugin => plugin.getChangelog(latestVersion));
70
70
 
71
71
  const incrementBase = { latestVersion, increment, isPreRelease, preReleaseId };
@@ -99,7 +99,7 @@ class GitBase extends Plugin {
99
99
  const sha = await this.exec(`git rev-list ${latestTag || '--skip=1'} --tags --max-count=1`, {
100
100
  options
101
101
  });
102
- return this.exec(`git describe --tags --abbrev=0 ${sha}^`, { options }).catch(() => null);
102
+ return this.exec(`git describe --tags --abbrev=0 "${sha}^"`, { options }).catch(() => null);
103
103
  }
104
104
  }
105
105
 
@@ -1,6 +1,6 @@
1
1
  import { EOL } from 'os';
2
2
  import _ from 'lodash';
3
- import findUp from 'find-up';
3
+ import { execa } from 'execa';
4
4
  import { format, e } from '../../util.js';
5
5
  import GitBase from '../GitBase.js';
6
6
  import prompts from './prompts.js';
@@ -12,6 +12,12 @@ const fixArgs = args => (args ? (typeof args === 'string' ? args.split(' ') : ar
12
12
 
13
13
  const docs = 'https://git.io/release-it-git';
14
14
 
15
+ const isGitRepo = () =>
16
+ execa('git', ['rev-parse', '--git-dir']).then(
17
+ () => true,
18
+ () => false
19
+ );
20
+
15
21
  class Git extends GitBase {
16
22
  constructor(...args) {
17
23
  super(...args);
@@ -19,7 +25,7 @@ class Git extends GitBase {
19
25
  }
20
26
 
21
27
  static async isEnabled(options) {
22
- return options !== false && (await findUp('.git', { type: 'directory' }));
28
+ return options !== false && (await isGitRepo());
23
29
  }
24
30
 
25
31
  async init() {
@@ -1,10 +1,12 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
+ import open from 'open';
3
4
  import { Octokit } from '@octokit/rest';
4
- import globby from 'globby';
5
+ import { globby } from 'globby';
5
6
  import mime from 'mime-types';
6
7
  import _ from 'lodash';
7
8
  import retry from 'async-retry';
9
+ import newGithubReleaseUrl from 'new-github-release-url';
8
10
  import { format, parseVersion, readJSON, e } from '../../util.js';
9
11
  import Release from '../GitRelease.js';
10
12
  import prompts from './prompts.js';
@@ -21,7 +23,7 @@ const parseErrormsg = err => {
21
23
  let msg = err;
22
24
  if (err instanceof Error) {
23
25
  const { status, message } = err;
24
- const { headers } = err.response;
26
+ const headers = err.response ? err.response.headers : {};
25
27
  msg = `${_.get(headers, 'status', status)} (${message})`;
26
28
  }
27
29
  return msg;
@@ -36,13 +38,18 @@ class GitHub extends Release {
36
38
  async init() {
37
39
  await super.init();
38
40
 
39
- const { skipChecks, tokenRef, update } = this.options;
41
+ const { skipChecks, tokenRef, web, update } = this.options;
40
42
 
41
- if (!skipChecks) {
42
- if (!this.token) {
43
- throw e(`Environment variable "${tokenRef}" is required for GitHub releases.`, docs);
43
+ if (!this.token || web) {
44
+ if (!web) {
45
+ this.log.warn(`Environment variable "${tokenRef}" is required for automated GitHub Releases.`);
46
+ this.log.warn('Falling back to web-based GitHub Release.');
44
47
  }
48
+ this.setContext({ isWeb: true });
49
+ return;
50
+ }
45
51
 
52
+ if (!skipChecks) {
46
53
  // If we're running on GitHub Actions, we can skip the authentication and
47
54
  // collaborator checks. Ref: https://bit.ly/2vsyRzu
48
55
  if (process.env.GITHUB_ACTIONS) {
@@ -108,13 +115,16 @@ class GitHub extends Release {
108
115
 
109
116
  async release() {
110
117
  const { assets } = this.options;
111
- const { isUpdate } = this.getContext();
118
+ const { isWeb, isUpdate } = this.getContext();
112
119
  const { isCI } = this.config;
113
120
 
114
121
  const type = isUpdate ? 'update' : 'create';
115
122
  const publishMethod = `${type}Release`;
116
123
 
117
- if (isCI) {
124
+ if (isWeb) {
125
+ const task = () => this.createWebRelease();
126
+ return this.step({ task, label: 'Generating link to GitHub Release web interface', prompt: 'release' });
127
+ } else if (isCI) {
118
128
  await this.step({ task: () => this[publishMethod](), label: `GitHub ${type} release` });
119
129
  return this.step({ enabled: assets, task: () => this.uploadAssets(), label: 'GitHub upload assets' });
120
130
  } else {
@@ -285,6 +295,34 @@ class GitHub extends Release {
285
295
  return `https://${host}/${repository}/releases/tag/${tagName}`;
286
296
  }
287
297
 
298
+ generateWebUrl() {
299
+ const host = this.options.host || this.getContext('repo.host');
300
+ const isGitHub = host === 'github.com';
301
+
302
+ const options = this.getOctokitReleaseOptions();
303
+ const url = newGithubReleaseUrl({
304
+ user: options.owner,
305
+ repo: options.repo,
306
+ tag: options.tag_name,
307
+ isPrerelease: options.prerelease,
308
+ title: options.name,
309
+ body: options.body
310
+ });
311
+ return isGitHub ? url : url.replace('github.com', host);
312
+ }
313
+
314
+ async createWebRelease() {
315
+ const { isCI } = this.config;
316
+ const { tagName } = this.config.getContext();
317
+ const url = this.generateWebUrl();
318
+ if (isCI) {
319
+ this.setContext({ isReleased: true, releaseUrl: url });
320
+ } else {
321
+ await open(url);
322
+ this.setContext({ isReleased: true, releaseUrl: this.getReleaseUrlFallback(tagName) });
323
+ }
324
+ }
325
+
288
326
  updateRelease() {
289
327
  const { isDryRun } = this.config;
290
328
  const release_id = this.getContext('releaseId');
@@ -1,7 +1,7 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
3
  import got from 'got';
4
- import globby from 'globby';
4
+ import { globby } from 'globby';
5
5
  import FormData from 'form-data';
6
6
  import _ from 'lodash';
7
7
  import Release from '../GitRelease.js';
@@ -53,10 +53,6 @@ class Version extends Plugin {
53
53
  this.registerPrompts(prompts);
54
54
  }
55
55
 
56
- getLatestVersion() {
57
- return '0.0.0';
58
- }
59
-
60
56
  getIncrement(options) {
61
57
  return options.increment;
62
58
  }
package/lib/shell.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import sh from 'shelljs';
2
- import execa from 'execa';
2
+ import { execa } from 'execa';
3
3
  import _debug from 'debug';
4
4
  import { format } from './util.js';
5
5
 
package/lib/spinner.js CHANGED
@@ -1,4 +1,4 @@
1
- import ora from 'ora';
1
+ import { oraPromise } from 'ora';
2
2
  import { format } from './util.js';
3
3
 
4
4
  const noop = Promise.resolve();
@@ -6,7 +6,7 @@ const noop = Promise.resolve();
6
6
  class Spinner {
7
7
  constructor({ container = {} } = {}) {
8
8
  this.config = container.config;
9
- this.ora = container.ora || ora;
9
+ this.ora = container.ora || oraPromise;
10
10
  }
11
11
  show({ enabled = true, task, label, external = false, context }) {
12
12
  if (!enabled) return noop;
@@ -19,7 +19,7 @@ class Spinner {
19
19
 
20
20
  if (!this.isSpinnerDisabled || (external && this.canForce)) {
21
21
  const text = format(label, context);
22
- this.ora.promise(awaitTask, text);
22
+ this.ora(awaitTask, text);
23
23
  }
24
24
 
25
25
  return awaitTask;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "release-it",
3
- "version": "15.0.0-esm.2",
3
+ "version": "15.0.0-esm.3",
4
4
  "description": "Generic CLI tool to automate versioning and package publishing related tasks.",
5
5
  "keywords": [
6
6
  "build",
@@ -62,24 +62,25 @@
62
62
  "license": "MIT",
63
63
  "dependencies": {
64
64
  "@iarna/toml": "2.2.5",
65
- "@octokit/rest": "18.6.7",
66
- "async-retry": "1.3.1",
67
- "chalk": "4.1.1",
68
- "cosmiconfig": "7.0.0",
69
- "debug": "4.3.2",
65
+ "@octokit/rest": "18.12.0",
66
+ "async-retry": "1.3.3",
67
+ "chalk": "4.1.2",
68
+ "cosmiconfig": "7.0.1",
69
+ "debug": "4.3.3",
70
70
  "deprecated-obj": "2.0.0",
71
- "execa": "5.1.1",
72
- "find-up": "5.0.0",
71
+ "execa": "6.0.0",
73
72
  "form-data": "4.0.0",
74
- "git-url-parse": "11.5.0",
75
- "globby": "11.0.4",
76
- "got": "11.8.2",
77
- "inquirer": "8.1.1",
78
- "is-ci": "3.0.0",
73
+ "git-url-parse": "11.6.0",
74
+ "globby": "12.0.2",
75
+ "got": "11.8.3",
76
+ "inquirer": "8.2.0",
77
+ "is-ci": "3.0.1",
79
78
  "lodash": "4.17.21",
80
- "mime-types": "2.1.31",
81
- "ora": "5.4.1",
82
- "os-name": "4.0.0",
79
+ "mime-types": "2.1.34",
80
+ "new-github-release-url": "2.0.0",
81
+ "open": "8.4.0",
82
+ "ora": "6.0.1",
83
+ "os-name": "5.0.1",
83
84
  "parse-json": "5.2.0",
84
85
  "semver": "7.3.5",
85
86
  "shelljs": "0.8.4",
@@ -87,25 +88,25 @@
87
88
  "url-join": "4.0.1",
88
89
  "uuid": "8.3.2",
89
90
  "yaml": "1.10.2",
90
- "yargs-parser": "20.2.9"
91
+ "yargs-parser": "21.0.0"
91
92
  },
92
93
  "devDependencies": {
93
94
  "@octokit/request-error": "2.1.0",
94
95
  "ava": "3.15.0",
95
- "codecov": "3.8.2",
96
- "eslint": "7.30.0",
96
+ "codecov": "3.8.3",
97
+ "eslint": "8.3.0",
97
98
  "eslint-config-prettier": "8.3.0",
98
- "eslint-plugin-ava": "12.0.0",
99
- "eslint-plugin-import": "2.23.4",
100
- "eslint-plugin-prettier": "3.4.0",
99
+ "eslint-plugin-ava": "13.1.0",
100
+ "eslint-plugin-import": "2.25.3",
101
+ "eslint-plugin-prettier": "4.0.0",
101
102
  "markdown-toc": "1.2.0",
102
- "mock-fs": "5.0.0",
103
+ "mock-fs": "5.1.2",
103
104
  "mock-stdio": "1.0.3",
104
- "nock": "13.1.1",
105
+ "nock": "13.2.1",
105
106
  "nyc": "15.1.0",
106
- "prettier": "2.3.2",
107
- "sinon": "11.1.1",
108
- "strip-ansi": "6.0.0"
107
+ "prettier": "2.5.0",
108
+ "sinon": "12.0.1",
109
+ "strip-ansi": "7.0.1"
109
110
  },
110
111
  "engines": {
111
112
  "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
package/test/config.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import test from 'ava';
2
2
  import mock from 'mock-fs';
3
+ import isCI from 'is-ci';
3
4
  import Config from '../lib/config.js';
4
5
  import { readJSON } from '../lib/util.js';
5
6
 
@@ -44,8 +45,7 @@ test('should set CI mode', t => {
44
45
  t.is(config.isCI, true);
45
46
  });
46
47
 
47
- test('should detect CI mode', async t => {
48
- const { default: isCI } = await import('is-ci');
48
+ test('should detect CI mode', t => {
49
49
  const config = new Config();
50
50
  t.is(config.options.ci, isCI);
51
51
  t.is(config.isCI, isCI);
package/test/github.js CHANGED
@@ -18,15 +18,11 @@ const host = 'github.com';
18
18
  const git = { changelog: null };
19
19
  const requestErrorOptions = { request: { url: '', headers: {} }, response: { headers: {} } };
20
20
 
21
- test.serial('should validate token', async t => {
21
+ test.serial('should check token and perform checks', async t => {
22
22
  const tokenRef = 'MY_GITHUB_TOKEN';
23
23
  const options = { github: { release: true, tokenRef, pushRepo } };
24
24
  const github = factory(GitHub, { options });
25
- delete process.env[tokenRef];
26
25
 
27
- await t.throwsAsync(github.init(), {
28
- message: /^Environment variable "MY_GITHUB_TOKEN" is required for GitHub releases/
29
- });
30
26
  process.env[tokenRef] = '123'; // eslint-disable-line require-atomic-updates
31
27
 
32
28
  interceptAuthentication();
@@ -34,6 +30,18 @@ test.serial('should validate token', async t => {
34
30
  await t.notThrowsAsync(github.init());
35
31
  });
36
32
 
33
+ test.serial('should check token and warn', async t => {
34
+ const tokenRef = 'MY_GITHUB_TOKEN';
35
+ const options = { github: { release: true, tokenRef, pushRepo } };
36
+ const github = factory(GitHub, { options });
37
+ delete process.env[tokenRef];
38
+
39
+ await t.notThrowsAsync(github.init());
40
+
41
+ t.is(github.log.warn.args[0][0], 'Environment variable "MY_GITHUB_TOKEN" is required for automated GitHub Releases.');
42
+ t.is(github.log.warn.args[1][0], 'Falling back to web-based GitHub Release.');
43
+ });
44
+
37
45
  test('should release and upload assets', async t => {
38
46
  const options = {
39
47
  git,
@@ -48,6 +56,7 @@ test('should release and upload assets', async t => {
48
56
  };
49
57
  const github = factory(GitHub, { options });
50
58
  const exec = sinon.stub(github.shell, 'exec').callThrough();
59
+ exec.withArgs('git log --pretty=format:"* %s (%h)" ${from}...${to}').resolves('');
51
60
  exec.withArgs('git describe --tags --match=* --abbrev=0').resolves('2.0.1');
52
61
 
53
62
  interceptAuthentication();
@@ -77,6 +86,7 @@ test('should create a pre-release and draft release notes', async t => {
77
86
  };
78
87
  const github = factory(GitHub, { options });
79
88
  const exec = sinon.stub(github.shell, 'exec').callThrough();
89
+ exec.withArgs('git log --pretty=format:"* %s (%h)" ${from}...${to}').resolves('');
80
90
  exec.withArgs('git describe --tags --match=* --abbrev=0').resolves('2.0.1');
81
91
 
82
92
  interceptAuthentication();
@@ -108,9 +118,10 @@ test('should update release and upload assets', async t => {
108
118
  };
109
119
  const github = factory(GitHub, { options });
110
120
  const exec = sinon.stub(github.shell, 'exec').callThrough();
121
+ exec.withArgs('git log --pretty=format:"* %s (%h)" ${from}...${to}').resolves('');
111
122
  exec.withArgs('git describe --tags --match=* --abbrev=0').resolves('2.0.1');
112
- exec.withArgs('git rev-list 2.0.1 --tags --max-count=1').resolves('71f1812');
113
- exec.withArgs('git describe --tags --match=* --abbrev=0 71f1812').resolves('2.0.1');
123
+ exec.withArgs('git rev-list 2.0.1 --tags --max-count=1').resolves('a123456');
124
+ exec.withArgs('git describe --tags --abbrev=0 "a123456^"').resolves('2.0.1');
114
125
 
115
126
  interceptAuthentication();
116
127
  interceptCollaborator();
@@ -141,9 +152,10 @@ test('should create new release for unreleased tag', async t => {
141
152
  };
142
153
  const github = factory(GitHub, { options });
143
154
  const exec = sinon.stub(github.shell, 'exec').callThrough();
155
+ exec.withArgs('git log --pretty=format:"* %s (%h)" ${from}...${to}').resolves('');
144
156
  exec.withArgs('git describe --tags --match=* --abbrev=0').resolves('2.0.1');
145
- exec.withArgs('git rev-list 2.0.1 --tags --max-count=1').resolves('71f1812');
146
- exec.withArgs('git describe --tags --match=* --abbrev=0 71f1812').resolves('2.0.1');
157
+ exec.withArgs('git rev-list 2.0.1 --tags --max-count=1').resolves('b123456');
158
+ exec.withArgs('git describe --tags --abbrev=0 "b123456^"').resolves('2.0.1');
147
159
 
148
160
  interceptAuthentication();
149
161
  interceptCollaborator();
@@ -194,6 +206,7 @@ test('should release to alternative host and proxy', async t => {
194
206
  };
195
207
  const github = factory(GitHub, { options });
196
208
  const exec = sinon.stub(github.shell, 'exec').callThrough();
209
+ exec.withArgs('git log --pretty=format:"* %s (%h)" ${from}...${to}').resolves('');
197
210
  exec.withArgs('git describe --tags --match=* --abbrev=0').resolves('1.0.0');
198
211
 
199
212
  await runTasks(github);
@@ -210,6 +223,7 @@ test('should release to git.pushRepo', async t => {
210
223
  const options = { git: { pushRepo: 'upstream', changelog: null }, github: { tokenRef, skipChecks: true } };
211
224
  const github = factory(GitHub, { options });
212
225
  const exec = sinon.stub(github.shell, 'exec').callThrough();
226
+ exec.withArgs('git log --pretty=format:"* %s (%h)" ${from}...${to}').resolves('');
213
227
  exec.withArgs('git describe --tags --match=* --abbrev=0').resolves('1.0.0');
214
228
  exec.withArgs('git remote get-url upstream').resolves('https://my-custom-host.org/user/repo');
215
229
 
@@ -308,6 +322,7 @@ test('should not call octokit client in dry run', async t => {
308
322
  const github = factory(GitHub, { options });
309
323
  const spy = sinon.spy(github, 'client', ['get']);
310
324
  const exec = sinon.stub(github.shell, 'exec').callThrough();
325
+ exec.withArgs('git log --pretty=format:"* %s (%h)" ${from}...${to}').resolves('');
311
326
  exec.withArgs('git describe --tags --match=* --abbrev=0').resolves('v1.0.0');
312
327
 
313
328
  await runTasks(github);
@@ -327,3 +342,56 @@ test('should skip checks', async t => {
327
342
  const github = factory(GitHub, { options });
328
343
  await t.notThrowsAsync(github.init());
329
344
  });
345
+
346
+ test('should generate GitHub web release url', async t => {
347
+ const options = {
348
+ github: {
349
+ pushRepo,
350
+ release: true,
351
+ web: true,
352
+ releaseName: 'Release ${tagName}',
353
+ releaseNotes: 'echo Custom notes'
354
+ }
355
+ };
356
+ const github = factory(GitHub, { options });
357
+ const exec = sinon.stub(github.shell, 'exec').callThrough();
358
+ exec.withArgs('git log --pretty=format:"* %s (%h)" ${from}...${to}').resolves('');
359
+ exec.withArgs('git describe --tags --match=* --abbrev=0').resolves('2.0.1');
360
+
361
+ await runTasks(github);
362
+
363
+ const { isReleased, releaseUrl } = github.getContext();
364
+ t.true(isReleased);
365
+ t.is(
366
+ releaseUrl,
367
+ 'https://github.com/user/repo/releases/new?tag=2.0.2&title=Release+2.0.2&body=Custom+notes&prerelease=false'
368
+ );
369
+ exec.restore();
370
+ });
371
+
372
+ test('should generate GitHub web release url for enterprise host', async t => {
373
+ const options = {
374
+ github: {
375
+ pushRepo: 'git://my-custom-host.org:user/repo',
376
+ release: true,
377
+ web: true,
378
+ host: 'my-custom-host.org',
379
+ releaseName: 'The Launch',
380
+ releaseNotes: 'echo It happened'
381
+ }
382
+ };
383
+ const github = factory(GitHub, { options });
384
+ const exec = sinon.stub(github.shell, 'exec').callThrough();
385
+ exec.withArgs('git log --pretty=format:"* %s (%h)" ${from}...${to}').resolves('');
386
+ exec.withArgs('git describe --tags --match=* --abbrev=0').resolves('2.0.1');
387
+
388
+ await runTasks(github);
389
+
390
+ const { isReleased, releaseUrl } = github.getContext();
391
+ t.true(isReleased);
392
+ t.is(
393
+ releaseUrl,
394
+ 'https://my-custom-host.org/user/repo/releases/new?tag=2.0.2&title=The+Launch&body=It+happened&prerelease=false'
395
+ );
396
+ exec.restore();
397
+ });
package/test/plugins.js CHANGED
@@ -131,7 +131,7 @@ test.serial('should disable core plugins', async t => {
131
131
  t.deepEqual(result, {
132
132
  changelog: undefined,
133
133
  name: undefined,
134
- latestVersion: undefined,
134
+ latestVersion: '0.0.0',
135
135
  version: undefined
136
136
  });
137
137
  });
package/test/spinner.js CHANGED
@@ -4,9 +4,7 @@ import Spinner from '../lib/spinner.js';
4
4
  import Config from '../lib/config.js';
5
5
 
6
6
  test.beforeEach(t => {
7
- t.context.ora = {
8
- promise: sinon.spy()
9
- };
7
+ t.context.ora = sinon.spy();
10
8
  });
11
9
 
12
10
  const getConfig = options => {
@@ -24,7 +22,7 @@ test('should not show spinner and not execute task if disabled', async t => {
24
22
  const spinner = new Spinner({ container: { ora } });
25
23
  await spinner.show({ enabled: false, task });
26
24
  t.is(task.callCount, 0);
27
- t.is(ora.promise.callCount, 0);
25
+ t.is(ora.callCount, 0);
28
26
  });
29
27
 
30
28
  test('should show spinner and run task by default', async t => {
@@ -35,9 +33,9 @@ test('should show spinner and run task by default', async t => {
35
33
  const spinner = new Spinner({ container: { ora, config } });
36
34
  await spinner.show({ task, label });
37
35
  t.is(task.callCount, 1);
38
- t.is(ora.promise.callCount, 1);
39
- t.is(ora.promise.firstCall.args[0], task.firstCall.returnValue);
40
- t.is(ora.promise.firstCall.args[1], label);
36
+ t.is(ora.callCount, 1);
37
+ t.is(ora.firstCall.args[0], task.firstCall.returnValue);
38
+ t.is(ora.firstCall.args[1], label);
41
39
  });
42
40
 
43
41
  test('should run task, but not show spinner if interactive', async t => {
@@ -47,7 +45,7 @@ test('should run task, but not show spinner if interactive', async t => {
47
45
  const spinner = new Spinner({ container: { ora, config } });
48
46
  await spinner.show({ task });
49
47
  t.is(task.callCount, 1);
50
- t.is(ora.promise.callCount, 0);
48
+ t.is(ora.callCount, 0);
51
49
  });
52
50
 
53
51
  test('should run task and show spinner if interactive, but external', async t => {
@@ -57,5 +55,5 @@ test('should run task and show spinner if interactive, but external', async t =>
57
55
  const spinner = new Spinner({ container: { ora, config } });
58
56
  await spinner.show({ task, external: true });
59
57
  t.is(task.callCount, 1);
60
- t.is(ora.promise.callCount, 1);
58
+ t.is(ora.callCount, 1);
61
59
  });
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
  test.serial('should run all hooks', async t => {
402
443
  gitAdd(`{"name":"hooked","version":"1.0.0","type":"module"}`, 'package.json', 'Add package.json');
@@ -56,7 +56,7 @@ export let runTasks = async plugin => {
56
56
 
57
57
  const name = (await plugin.getName()) || '__test__';
58
58
  const latestVersion = (await plugin.getLatestVersion()) || '1.0.0';
59
- const changelog = (await plugin.getChangelog(latestVersion)) || null;
59
+ const changelog = (await plugin.getChangelog()) || null;
60
60
  const increment = getIncrement(plugin, { latestVersion });
61
61
 
62
62
  plugin.config.setContext({ name, latestVersion, latestTag: latestVersion, changelog });
package/test/version.js CHANGED
@@ -149,20 +149,20 @@ test('should run tasks without errors', async t => {
149
149
 
150
150
  t.is(getIncrement.callCount, 1);
151
151
  t.deepEqual(getIncrement.firstCall.args[0], {
152
- latestVersion: '0.0.0',
152
+ latestVersion: '1.0.0',
153
153
  increment: 'minor',
154
154
  isPreRelease: false,
155
155
  preReleaseId: null
156
156
  });
157
157
  t.is(getIncrementedVersionCI.callCount, 1);
158
- t.deepEqual(getIncrementedVersionCI.firstCall.args[0], { latestVersion: '0.0.0', increment: 'minor' });
159
- t.is(await incrementVersion.firstCall.returnValue, '0.1.0');
158
+ t.deepEqual(getIncrementedVersionCI.firstCall.args[0], { latestVersion: '1.0.0', increment: 'minor' });
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: '0.0.0', increment: 'minor' });
162
- t.is(incrementVersion.firstCall.returnValue, '0.1.0');
161
+ t.deepEqual(incrementVersion.firstCall.args[0], { latestVersion: '1.0.0', increment: 'minor' });
162
+ t.is(incrementVersion.firstCall.returnValue, '1.1.0');
163
163
  const { latestVersion, version, isPreRelease, preReleaseId } = v.config.getContext();
164
- t.is(latestVersion, '0.0.0');
165
- t.is(version, '0.1.0');
164
+ t.is(latestVersion, '1.0.0');
165
+ t.is(version, '1.1.0');
166
166
  t.is(isPreRelease, false);
167
167
  t.is(preReleaseId, null);
168
168
  });