release-it 15.6.0 → 15.7.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
@@ -340,9 +340,8 @@ While mostly used as a CLI tool, release-it can be used as a dependency to integ
340
340
 
341
341
  ## Example projects using release-it
342
342
 
343
- - [antonmedv/fx](https://github.com/antonmedv/fx)
343
+ - [axios/axios](https://github.com/axios/axios)
344
344
  - [blockchain/blockchain-wallet-v4-frontend](https://github.com/blockchain/blockchain-wallet-v4-frontend)
345
- - [callstack/linaria](https://github.com/callstack/linaria)
346
345
  - [callstack/react-native-paper](https://github.com/callstack/react-native-paper)
347
346
  - [ember-cli/ember-cli](https://github.com/ember-cli/ember-cli)
348
347
  - [js-cookie/js-cookie](https://github.com/js-cookie/js-cookie)
package/bin/release-it.js CHANGED
@@ -38,5 +38,5 @@ const options = parseCliArguments([].slice.call(process.argv, 2));
38
38
  updater({ pkg: pkg }).notify();
39
39
  release(options).then(
40
40
  () => process.exit(0),
41
- () => process.exit(1)
41
+ ({ code }) => process.exit(Number.isInteger(code) ? code : 1)
42
42
  );
@@ -6,6 +6,8 @@
6
6
  "requireBranch": false,
7
7
  "requireUpstream": true,
8
8
  "requireCommits": false,
9
+ "requireCommitsFail": true,
10
+ "commitsPath": "",
9
11
  "addUntrackedFiles": false,
10
12
  "commit": true,
11
13
  "commitMessage": "Release ${version}",
@@ -46,8 +46,8 @@ class Git extends GitBase {
46
46
  if (this.options.requireUpstream && !(await this.hasUpstreamBranch())) {
47
47
  throw e(`No upstream configured for current branch.${EOL}Please set an upstream branch.`, docs);
48
48
  }
49
- if (this.options.requireCommits && (await this.getCommitsSinceLatestTag()) === 0) {
50
- throw e(`There are no commits since the latest tag.`, docs);
49
+ if (this.options.requireCommits && (await this.getCommitsSinceLatestTag(this.options.commitsPath)) === 0) {
50
+ throw e(`There are no commits since the latest tag.`, docs, this.options.requireCommitsFail);
51
51
  }
52
52
  }
53
53
 
@@ -120,10 +120,10 @@ class Git extends GitBase {
120
120
  );
121
121
  }
122
122
 
123
- async getCommitsSinceLatestTag() {
123
+ async getCommitsSinceLatestTag(commitsPath = '') {
124
124
  const latestTagName = await this.getLatestTagName();
125
125
  const ref = latestTagName ? `${latestTagName}..HEAD` : 'HEAD';
126
- return this.exec(`git rev-list ${ref} --count`, { options }).then(Number);
126
+ return this.exec(`git rev-list ${ref} --count ${commitsPath}`, { options }).then(Number);
127
127
  }
128
128
 
129
129
  async getUpstreamArgs(pushRepo) {
package/lib/util.js CHANGED
@@ -89,7 +89,11 @@ const parseVersion = raw => {
89
89
  };
90
90
  };
91
91
 
92
- const e = (message, docs) => new Error(docs ? `${message}${EOL}Documentation: ${docs}${EOL}` : message);
92
+ const e = (message, docs, fail = true) => {
93
+ const error = new Error(docs ? `${message}${EOL}Documentation: ${docs}${EOL}` : message);
94
+ error.code = fail ? 1 : 0;
95
+ return error;
96
+ };
93
97
 
94
98
  export {
95
99
  getSystemInfo,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "release-it",
3
- "version": "15.6.0",
3
+ "version": "15.7.0",
4
4
  "description": "Generic CLI tool to automate versioning and package publishing related tasks.",
5
5
  "keywords": [
6
6
  "build",
@@ -60,13 +60,13 @@
60
60
  "license": "MIT",
61
61
  "dependencies": {
62
62
  "@iarna/toml": "2.2.5",
63
- "@octokit/rest": "19.0.5",
63
+ "@octokit/rest": "19.0.7",
64
64
  "async-retry": "1.3.3",
65
- "chalk": "5.1.2",
66
- "cosmiconfig": "8.0.0",
67
- "execa": "6.1.0",
65
+ "chalk": "5.2.0",
66
+ "cosmiconfig": "8.1.0",
67
+ "execa": "7.0.0",
68
68
  "git-url-parse": "13.1.0",
69
- "globby": "13.1.2",
69
+ "globby": "13.1.3",
70
70
  "got": "12.5.3",
71
71
  "inquirer": "9.1.4",
72
72
  "is-ci": "3.0.1",
@@ -74,9 +74,9 @@
74
74
  "mime-types": "2.1.35",
75
75
  "new-github-release-url": "2.0.0",
76
76
  "node-fetch": "3.3.0",
77
- "open": "8.4.0",
77
+ "open": "8.4.2",
78
78
  "ora": "6.1.2",
79
- "os-name": "5.0.1",
79
+ "os-name": "5.1.0",
80
80
  "promise.allsettled": "1.0.6",
81
81
  "proxy-agent": "5.0.0",
82
82
  "semver": "7.3.8",
@@ -87,19 +87,19 @@
87
87
  "yargs-parser": "21.1.1"
88
88
  },
89
89
  "devDependencies": {
90
- "@octokit/request-error": "3.0.2",
91
- "ava": "5.1.0",
92
- "eslint": "8.28.0",
93
- "eslint-config-prettier": "8.5.0",
94
- "eslint-plugin-ava": "13.2.0",
95
- "eslint-plugin-import": "2.26.0",
90
+ "@octokit/request-error": "3.0.3",
91
+ "ava": "5.2.0",
92
+ "eslint": "8.35.0",
93
+ "eslint-config-prettier": "8.6.0",
94
+ "eslint-plugin-ava": "14.0.0",
95
+ "eslint-plugin-import": "2.27.5",
96
96
  "eslint-plugin-prettier": "4.2.1",
97
97
  "mock-fs": "5.2.0",
98
98
  "mock-stdio": "1.0.3",
99
- "nock": "13.2.9",
99
+ "nock": "13.3.0",
100
100
  "nyc": "15.1.0",
101
- "prettier": "2.8.0",
102
- "sinon": "15.0.0",
101
+ "prettier": "2.8.4",
102
+ "sinon": "15.0.1",
103
103
  "strip-ansi": "7.0.1"
104
104
  },
105
105
  "engines": {
package/test/git.init.js CHANGED
@@ -72,6 +72,36 @@ test.serial('should not throw if there are commits', async t => {
72
72
  await t.notThrowsAsync(gitClient.init());
73
73
  });
74
74
 
75
+ test.serial('should fail (exit code 1) if there are no commits', async t => {
76
+ const options = { git: { requireCommits: true } };
77
+ const gitClient = factory(Git, { options });
78
+ sh.exec('git tag 1.0.0');
79
+ await t.throwsAsync(gitClient.init(), { code: 1 });
80
+ });
81
+
82
+ test.serial('should not fail (exit code 0) if there are no commits', async t => {
83
+ const options = { git: { requireCommits: true, requireCommitsFail: false } };
84
+ const gitClient = factory(Git, { options });
85
+ sh.exec('git tag 1.0.0');
86
+ await t.throwsAsync(gitClient.init(), { code: 0 });
87
+ });
88
+
89
+ test.serial('should throw if there are no commits in specified path', async t => {
90
+ const options = { git: { requireCommits: true, commitsPath: 'dir' } };
91
+ const gitClient = factory(Git, { options });
92
+ sh.mkdir('dir');
93
+ sh.exec('git tag 1.0.0');
94
+ await t.throwsAsync(gitClient.init(), { message: /^There are no commits since the latest tag/ });
95
+ });
96
+
97
+ test.serial('should not throw if there are commits in specified path', async t => {
98
+ const options = { git: { requireCommits: true, commitsPath: 'dir' } };
99
+ const gitClient = factory(Git, { options });
100
+ sh.exec('git tag 1.0.0');
101
+ gitAdd('line', 'dir/file', 'Add file');
102
+ await t.notThrowsAsync(gitClient.init());
103
+ });
104
+
75
105
  test.serial('should not throw if there are no tags', async t => {
76
106
  const options = { git: { requireCommits: true } };
77
107
  const gitClient = factory(Git, { options });
package/test/npm.js CHANGED
@@ -108,7 +108,7 @@ test('should add registry to commands when specified', async t => {
108
108
  const exec = sinon.stub(npmClient.shell, 'exec').resolves();
109
109
  exec.withArgs('npm whoami --registry registry.example.org').resolves('john');
110
110
  exec
111
- .withArgs('npm access ls-collaborators release-it --registry registry.example.org')
111
+ .withArgs(/npm access (list collaborators --json|ls-collaborators) release-it --registry registry.example.org/)
112
112
  .resolves(JSON.stringify({ john: ['write'] }));
113
113
  await runTasks(npmClient);
114
114
  t.is(exec.args[0][0], 'npm ping --registry registry.example.org');
@@ -121,7 +121,9 @@ test('should not throw when executing tasks', async t => {
121
121
  const npmClient = factory(npm);
122
122
  const exec = sinon.stub(npmClient.shell, 'exec').resolves();
123
123
  exec.withArgs('npm whoami').resolves('john');
124
- exec.withArgs('npm access ls-collaborators release-it').resolves(JSON.stringify({ john: ['write'] }));
124
+ exec
125
+ .withArgs(/npm access (list collaborators --json|ls-collaborators) release-it/)
126
+ .resolves(JSON.stringify({ john: ['write'] }));
125
127
  await t.notThrowsAsync(runTasks(npmClient));
126
128
  exec.restore();
127
129
  });
@@ -168,7 +170,9 @@ test('should not throw if npm returns 404 for unsupported ping', async t => {
168
170
  const pingError = 'npm ERR! <title>404 - No content for path /-/ping</title>';
169
171
  exec.withArgs('npm ping').rejects(new Error(pingError));
170
172
  exec.withArgs('npm whoami').resolves('john');
171
- exec.withArgs('npm access ls-collaborators release-it').resolves(JSON.stringify({ john: ['write'] }));
173
+ exec
174
+ .withArgs(/npm access (list collaborators --json|ls-collaborators) release-it/)
175
+ .resolves(JSON.stringify({ john: ['write'] }));
172
176
  await runTasks(npmClient);
173
177
  t.is(exec.lastCall.args[0].trim(), 'npm publish . --tag latest');
174
178
  exec.restore();
@@ -197,7 +201,9 @@ test('should throw if user is not a collaborator (v8)', async t => {
197
201
  const exec = sinon.stub(npmClient.shell, 'exec').resolves();
198
202
  exec.withArgs('npm whoami').resolves('ada');
199
203
  exec.withArgs('npm --version').resolves('8.2.0');
200
- exec.withArgs('npm access ls-collaborators release-it').resolves(JSON.stringify({ john: ['write'] }));
204
+ exec
205
+ .withArgs(/npm access (list collaborators --json|ls-collaborators) release-it/)
206
+ .resolves(JSON.stringify({ john: ['write'] }));
201
207
  await t.throwsAsync(runTasks(npmClient), { message: /^User ada is not a collaborator for release-it/ });
202
208
  exec.restore();
203
209
  });
@@ -207,7 +213,7 @@ test('should not throw if user is not a collaborator on a new package', async t
207
213
  const exec = sinon.stub(npmClient.shell, 'exec').resolves();
208
214
  exec.withArgs('npm whoami').resolves('ada');
209
215
  exec
210
- .withArgs('npm access ls-collaborators release-it')
216
+ .withArgs(/npm access (list collaborators --json|ls-collaborators) release-it/)
211
217
  .rejects(
212
218
  new Error(
213
219
  'npm ERR! code E404\nnpm ERR! 404 Not Found - GET https://registry.npmjs.org/-/package/release-it/collaborators?format=cli - File not found'
@@ -268,7 +274,9 @@ test('should publish', async t => {
268
274
  const npmClient = factory(npm);
269
275
  const exec = sinon.stub(npmClient.shell, 'exec').resolves();
270
276
  exec.withArgs('npm whoami').resolves('john');
271
- exec.withArgs('npm access ls-collaborators release-it').resolves(JSON.stringify({ john: ['write'] }));
277
+ exec
278
+ .withArgs(/npm access (list collaborators --json|ls-collaborators) release-it/)
279
+ .resolves(JSON.stringify({ john: ['write'] }));
272
280
  await runTasks(npmClient);
273
281
  t.is(exec.lastCall.args[0].trim(), 'npm publish . --tag latest');
274
282
  exec.restore();
@@ -308,7 +316,7 @@ test('should publish to a different/scoped registry', async t => {
308
316
  .resolves('john');
309
317
  exec
310
318
  .withArgs(
311
- 'npm access ls-collaborators @my-scope/my-pkg --registry https://gitlab.com/api/v4/projects/my-scope%2Fmy-pkg/packages/npm/'
319
+ /npm access (list collaborators --json|ls-collaborators) @my-scope\/my-pkg --registry https:\/\/gitlab\.com\/api\/v4\/projects\/my-scope%2Fmy-pkg\/packages\/npm\//
312
320
  )
313
321
  .resolves(JSON.stringify({ john: ['write'] }));
314
322
 
@@ -337,7 +345,9 @@ test('should not publish when `npm version` fails', async t => {
337
345
  const npmClient = factory(npm, { options });
338
346
  const exec = sinon.stub(npmClient.shell, 'exec').resolves();
339
347
  exec.withArgs('npm whoami').resolves('john');
340
- exec.withArgs('npm access ls-collaborators @my-scope/my-pkg').resolves(JSON.stringify({ john: ['write'] }));
348
+ exec
349
+ .withArgs(/npm access (list collaborators --json|ls-collaborators) @my-scope\/my-pkg/)
350
+ .resolves(JSON.stringify({ john: ['write'] }));
341
351
  exec
342
352
  .withArgs('npm version 1.0.1 --no-git-tag-version')
343
353
  .rejects('npm ERR! Version not changed, might want --allow-same-version');
@@ -30,7 +30,7 @@ const interceptListReleases = ({
30
30
  upload_url: `https://uploads.${host}/repos/${owner}/${project}/releases/1/assets{?name,label}`,
31
31
  html_url: `https://${host}/${owner}/${project}/releases/tag/${tag_name}`,
32
32
  tag_name,
33
- target_commitish: 'master',
33
+ target_commitish: 'main',
34
34
  name: `Release ${tag_name}`,
35
35
  body: 'Description of the release',
36
36
  draft: false,
package/test/tasks.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import path from 'node:path';
2
2
  import test from 'ava';
3
+ import semver from 'semver';
3
4
  import sh from 'shelljs';
4
5
  import _ from 'lodash';
5
6
  import sinon from 'sinon';
@@ -28,6 +29,8 @@ const noop = Promise.resolve();
28
29
 
29
30
  const sandbox = sinon.createSandbox();
30
31
 
32
+ const npmMajorVersion = semver.major(process.env.npm_config_user_agent.match(/npm\/([^ ]+)/)[1]);
33
+
31
34
  const testConfig = {
32
35
  ci: true,
33
36
  config: false
@@ -48,6 +51,10 @@ const getContainer = options => {
48
51
  };
49
52
  };
50
53
 
54
+ test.before(t => {
55
+ t.timeout(90 * 1000);
56
+ });
57
+
51
58
  test.serial.beforeEach(t => {
52
59
  const bare = mkTmpDir();
53
60
  const target = mkTmpDir();
@@ -175,7 +182,7 @@ test.serial('should release all the things (basic)', async t => {
175
182
  'npm whoami',
176
183
  `npm show ${pkgName}@latest version`,
177
184
  'npm --version',
178
- `npm access ls-collaborators ${pkgName}`,
185
+ `npm access ${npmMajorVersion >= 9 ? 'list collaborators --json' : 'ls-collaborators'} ${pkgName}`,
179
186
  'npm version 1.0.1 --no-git-tag-version',
180
187
  'npm publish . --tag latest'
181
188
  ]);
@@ -309,7 +316,7 @@ test.serial('should release all the things (pre-release, github, gitlab)', async
309
316
  'npm whoami',
310
317
  `npm show ${pkgName}@latest version`,
311
318
  'npm --version',
312
- `npm access ls-collaborators ${pkgName}`,
319
+ `npm access ${npmMajorVersion >= 9 ? 'list collaborators --json' : 'ls-collaborators'} ${pkgName}`,
313
320
  'npm version 1.1.0-alpha.0 --no-git-tag-version',
314
321
  'npm publish . --tag alpha'
315
322
  ]);
@@ -349,7 +356,7 @@ test.serial('should publish pre-release without pre-id with different npm.tag',
349
356
  'npm whoami',
350
357
  `npm show ${pkgName}@latest version`,
351
358
  'npm --version',
352
- `npm access ls-collaborators ${pkgName}`,
359
+ `npm access ${npmMajorVersion >= 9 ? 'list collaborators --json' : 'ls-collaborators'} ${pkgName}`,
353
360
  'npm version 2.0.0-0 --no-git-tag-version',
354
361
  'npm publish . --tag next'
355
362
  ]);
@@ -10,9 +10,14 @@ const mkTmpDir = () => {
10
10
 
11
11
  const readFile = file => fs.promises.readFile(path.resolve(file), 'utf8');
12
12
 
13
- const gitAdd = (content, file, message) => {
14
- sh.ShellString(content).toEnd(file);
15
- sh.exec(`git add ${file}`);
13
+ const gitAdd = (content, filePath, message) => {
14
+ const pathSegments = filePath.split('/').filter(Boolean);
15
+ pathSegments.pop();
16
+ if (pathSegments.length) {
17
+ sh.mkdir('-p', pathSegments.join('/'));
18
+ }
19
+ sh.ShellString(content).toEnd(filePath);
20
+ sh.exec(`git add ${filePath}`);
16
21
  const { stdout } = sh.exec(`git commit -m "${message}"`);
17
22
  const match = stdout.match(/\[.+([a-z0-9]{7})\]/);
18
23
  return match ? match[1] : null;