release-it 15.5.1 → 15.6.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 +1 -2
- package/config/release-it.json +1 -0
- package/lib/plugin/GitBase.js +2 -1
- package/lib/plugin/GitRelease.js +1 -1
- package/lib/plugin/gitlab/GitLab.js +2 -2
- package/lib/plugin/npm/npm.js +29 -20
- package/package.json +17 -18
- package/test/git.init.js +17 -0
- package/test/npm.js +32 -11
- package/test/tasks.js +11 -5
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
|
-
- [
|
|
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/config/release-it.json
CHANGED
package/lib/plugin/GitBase.js
CHANGED
|
@@ -93,7 +93,8 @@ class GitBase extends Plugin {
|
|
|
93
93
|
getLatestTagName() {
|
|
94
94
|
const context = Object.assign({}, this.config.getContext(), { version: '*' });
|
|
95
95
|
const match = format(this.options.tagMatch || this.options.tagName || '${version}', context);
|
|
96
|
-
|
|
96
|
+
const exclude = this.options.tagExclude ? ` --exclude=${format(this.options.tagExclude, context)}` : '';
|
|
97
|
+
return this.exec(`git describe --tags --match=${match} --abbrev=0${exclude}`, { options }).then(
|
|
97
98
|
stdout => stdout || null,
|
|
98
99
|
() => null
|
|
99
100
|
);
|
package/lib/plugin/GitRelease.js
CHANGED
|
@@ -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', 'tagMatch', 'pushRepo', 'changelog']);
|
|
15
|
+
const gitOptions = _.pick(git, ['tagExclude', 'tagName', 'tagMatch', 'pushRepo', 'changelog']);
|
|
16
16
|
return _.defaults(baseOptions, gitOptions);
|
|
17
17
|
}
|
|
18
18
|
|
|
@@ -2,7 +2,7 @@ import fs from 'node:fs';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import got from 'got';
|
|
4
4
|
import { globby } from 'globby';
|
|
5
|
-
import FormData from '
|
|
5
|
+
import { FormData, fileFromSync } from 'node-fetch';
|
|
6
6
|
import allSettled from 'promise.allsettled';
|
|
7
7
|
import _ from 'lodash';
|
|
8
8
|
import Release from '../GitRelease.js';
|
|
@@ -232,7 +232,7 @@ class GitLab extends Release {
|
|
|
232
232
|
const endpoint = `projects/${id}/uploads`;
|
|
233
233
|
|
|
234
234
|
const body = new FormData();
|
|
235
|
-
body.
|
|
235
|
+
body.set('file', fileFromSync(filePath));
|
|
236
236
|
const options = { body };
|
|
237
237
|
|
|
238
238
|
try {
|
package/lib/plugin/npm/npm.js
CHANGED
|
@@ -132,34 +132,43 @@ class npm extends Plugin {
|
|
|
132
132
|
);
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
-
isCollaborator() {
|
|
135
|
+
async isCollaborator() {
|
|
136
136
|
const registry = this.getRegistry();
|
|
137
137
|
const registryArg = registry ? ` --registry ${registry}` : '';
|
|
138
138
|
const name = this.getName();
|
|
139
139
|
const { username } = this.getContext();
|
|
140
140
|
if (username === undefined) return true;
|
|
141
141
|
if (username === null) return false;
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
142
|
+
|
|
143
|
+
try {
|
|
144
|
+
let npmVersion = await this.exec('npm --version', { options });
|
|
145
|
+
|
|
146
|
+
let accessCommand;
|
|
147
|
+
if (semver.gt(npmVersion, '9.0.0')) {
|
|
148
|
+
accessCommand = 'npm access list collaborators --json';
|
|
149
|
+
} else {
|
|
150
|
+
accessCommand = 'npm access ls-collaborators';
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const output = await this.exec(`${accessCommand} ${name}${registryArg}`, { options });
|
|
154
|
+
|
|
155
|
+
try {
|
|
156
|
+
const collaborators = JSON.parse(output);
|
|
157
|
+
const permissions = collaborators[username];
|
|
158
|
+
return permissions && permissions.includes('write');
|
|
159
|
+
} catch (err) {
|
|
154
160
|
this.debug(err);
|
|
155
|
-
|
|
156
|
-
this.log.warn('Ignoring response from unsupported `npm access` command.');
|
|
157
|
-
} else {
|
|
158
|
-
this.log.warn(`Unable to verify if user ${username} is a collaborator for ${name}.`);
|
|
159
|
-
}
|
|
160
|
-
return true;
|
|
161
|
+
return false;
|
|
161
162
|
}
|
|
162
|
-
)
|
|
163
|
+
} catch (err) {
|
|
164
|
+
this.debug(err);
|
|
165
|
+
if (/code E400/.test(err)) {
|
|
166
|
+
this.log.warn('Ignoring response from unsupported `npm access` command.');
|
|
167
|
+
} else {
|
|
168
|
+
this.log.warn(`Unable to verify if user ${username} is a collaborator for ${name}.`);
|
|
169
|
+
}
|
|
170
|
+
return true;
|
|
171
|
+
}
|
|
163
172
|
}
|
|
164
173
|
|
|
165
174
|
async getLatestRegistryVersion() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "release-it",
|
|
3
|
-
"version": "15.
|
|
3
|
+
"version": "15.6.1",
|
|
4
4
|
"description": "Generic CLI tool to automate versioning and package publishing related tasks.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"build",
|
|
@@ -60,14 +60,13 @@
|
|
|
60
60
|
"license": "MIT",
|
|
61
61
|
"dependencies": {
|
|
62
62
|
"@iarna/toml": "2.2.5",
|
|
63
|
-
"@octokit/rest": "19.0.
|
|
63
|
+
"@octokit/rest": "19.0.7",
|
|
64
64
|
"async-retry": "1.3.3",
|
|
65
|
-
"chalk": "5.
|
|
66
|
-
"cosmiconfig": "8.
|
|
67
|
-
"execa": "
|
|
68
|
-
"form-data": "4.0.0",
|
|
65
|
+
"chalk": "5.2.0",
|
|
66
|
+
"cosmiconfig": "8.1.0",
|
|
67
|
+
"execa": "7.0.0",
|
|
69
68
|
"git-url-parse": "13.1.0",
|
|
70
|
-
"globby": "13.1.
|
|
69
|
+
"globby": "13.1.3",
|
|
71
70
|
"got": "12.5.3",
|
|
72
71
|
"inquirer": "9.1.4",
|
|
73
72
|
"is-ci": "3.0.1",
|
|
@@ -75,9 +74,9 @@
|
|
|
75
74
|
"mime-types": "2.1.35",
|
|
76
75
|
"new-github-release-url": "2.0.0",
|
|
77
76
|
"node-fetch": "3.3.0",
|
|
78
|
-
"open": "8.4.
|
|
77
|
+
"open": "8.4.2",
|
|
79
78
|
"ora": "6.1.2",
|
|
80
|
-
"os-name": "5.0
|
|
79
|
+
"os-name": "5.1.0",
|
|
81
80
|
"promise.allsettled": "1.0.6",
|
|
82
81
|
"proxy-agent": "5.0.0",
|
|
83
82
|
"semver": "7.3.8",
|
|
@@ -88,19 +87,19 @@
|
|
|
88
87
|
"yargs-parser": "21.1.1"
|
|
89
88
|
},
|
|
90
89
|
"devDependencies": {
|
|
91
|
-
"@octokit/request-error": "3.0.
|
|
92
|
-
"ava": "5.
|
|
93
|
-
"eslint": "8.
|
|
94
|
-
"eslint-config-prettier": "8.
|
|
95
|
-
"eslint-plugin-ava": "
|
|
96
|
-
"eslint-plugin-import": "2.
|
|
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",
|
|
97
96
|
"eslint-plugin-prettier": "4.2.1",
|
|
98
97
|
"mock-fs": "5.2.0",
|
|
99
98
|
"mock-stdio": "1.0.3",
|
|
100
|
-
"nock": "13.
|
|
99
|
+
"nock": "13.3.0",
|
|
101
100
|
"nyc": "15.1.0",
|
|
102
|
-
"prettier": "2.8.
|
|
103
|
-
"sinon": "15.0.
|
|
101
|
+
"prettier": "2.8.4",
|
|
102
|
+
"sinon": "15.0.1",
|
|
104
103
|
"strip-ansi": "7.0.1"
|
|
105
104
|
},
|
|
106
105
|
"engines": {
|
package/test/git.init.js
CHANGED
|
@@ -167,6 +167,23 @@ test.serial('should get the latest tag based on tagMatch', async t => {
|
|
|
167
167
|
t.is(gitClient.config.getContext('latestTag'), '21.04.3');
|
|
168
168
|
});
|
|
169
169
|
|
|
170
|
+
test.serial('should get the latest tag based on tagExclude', async t => {
|
|
171
|
+
const shell = factory(Shell);
|
|
172
|
+
const gitClient = factory(Git, {
|
|
173
|
+
options: { git: { tagExclude: '*[-]*' } },
|
|
174
|
+
container: { shell }
|
|
175
|
+
});
|
|
176
|
+
sh.exec('git tag 1.0.0');
|
|
177
|
+
sh.exec('git commit --allow-empty -m "commit 1"');
|
|
178
|
+
sh.exec('git tag 1.0.1-rc.0');
|
|
179
|
+
sh.exec('git tag 1.0.1');
|
|
180
|
+
sh.exec('git commit --allow-empty -m "commit 2"');
|
|
181
|
+
sh.exec('git tag 1.1.0-rc.0');
|
|
182
|
+
sh.exec('git push --tags');
|
|
183
|
+
await gitClient.init();
|
|
184
|
+
t.is(gitClient.config.getContext('latestTag'), '1.0.1');
|
|
185
|
+
});
|
|
186
|
+
|
|
170
187
|
test.serial('should generate correct changelog', async t => {
|
|
171
188
|
const gitClient = factory(Git, { options: { git } });
|
|
172
189
|
sh.exec('git tag 1.0.0');
|
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(
|
|
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
|
|
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
|
|
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();
|
|
@@ -182,11 +186,24 @@ test('should throw if user is not authenticated', async t => {
|
|
|
182
186
|
exec.restore();
|
|
183
187
|
});
|
|
184
188
|
|
|
185
|
-
test('should throw if user is not a collaborator', async t => {
|
|
189
|
+
test('should throw if user is not a collaborator (v9)', async t => {
|
|
186
190
|
const npmClient = factory(npm);
|
|
187
191
|
const exec = sinon.stub(npmClient.shell, 'exec').resolves();
|
|
188
192
|
exec.withArgs('npm whoami').resolves('ada');
|
|
189
|
-
exec.withArgs('npm
|
|
193
|
+
exec.withArgs('npm --version').resolves('9.2.0');
|
|
194
|
+
exec.withArgs('npm access list collaborators --json release-it').resolves(JSON.stringify({ john: ['write'] }));
|
|
195
|
+
await t.throwsAsync(runTasks(npmClient), { message: /^User ada is not a collaborator for release-it/ });
|
|
196
|
+
exec.restore();
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
test('should throw if user is not a collaborator (v8)', async t => {
|
|
200
|
+
const npmClient = factory(npm);
|
|
201
|
+
const exec = sinon.stub(npmClient.shell, 'exec').resolves();
|
|
202
|
+
exec.withArgs('npm whoami').resolves('ada');
|
|
203
|
+
exec.withArgs('npm --version').resolves('8.2.0');
|
|
204
|
+
exec
|
|
205
|
+
.withArgs(/npm access (list collaborators --json|ls-collaborators) release-it/)
|
|
206
|
+
.resolves(JSON.stringify({ john: ['write'] }));
|
|
190
207
|
await t.throwsAsync(runTasks(npmClient), { message: /^User ada is not a collaborator for release-it/ });
|
|
191
208
|
exec.restore();
|
|
192
209
|
});
|
|
@@ -196,7 +213,7 @@ test('should not throw if user is not a collaborator on a new package', async t
|
|
|
196
213
|
const exec = sinon.stub(npmClient.shell, 'exec').resolves();
|
|
197
214
|
exec.withArgs('npm whoami').resolves('ada');
|
|
198
215
|
exec
|
|
199
|
-
.withArgs(
|
|
216
|
+
.withArgs(/npm access (list collaborators --json|ls-collaborators) release-it/)
|
|
200
217
|
.rejects(
|
|
201
218
|
new Error(
|
|
202
219
|
'npm ERR! code E404\nnpm ERR! 404 Not Found - GET https://registry.npmjs.org/-/package/release-it/collaborators?format=cli - File not found'
|
|
@@ -257,7 +274,9 @@ test('should publish', async t => {
|
|
|
257
274
|
const npmClient = factory(npm);
|
|
258
275
|
const exec = sinon.stub(npmClient.shell, 'exec').resolves();
|
|
259
276
|
exec.withArgs('npm whoami').resolves('john');
|
|
260
|
-
exec
|
|
277
|
+
exec
|
|
278
|
+
.withArgs(/npm access (list collaborators --json|ls-collaborators) release-it/)
|
|
279
|
+
.resolves(JSON.stringify({ john: ['write'] }));
|
|
261
280
|
await runTasks(npmClient);
|
|
262
281
|
t.is(exec.lastCall.args[0].trim(), 'npm publish . --tag latest');
|
|
263
282
|
exec.restore();
|
|
@@ -297,7 +316,7 @@ test('should publish to a different/scoped registry', async t => {
|
|
|
297
316
|
.resolves('john');
|
|
298
317
|
exec
|
|
299
318
|
.withArgs(
|
|
300
|
-
|
|
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\//
|
|
301
320
|
)
|
|
302
321
|
.resolves(JSON.stringify({ john: ['write'] }));
|
|
303
322
|
|
|
@@ -307,7 +326,7 @@ test('should publish to a different/scoped registry', async t => {
|
|
|
307
326
|
'npm ping --registry https://gitlab.com/api/v4/projects/my-scope%2Fmy-pkg/packages/npm/',
|
|
308
327
|
'npm whoami --registry https://gitlab.com/api/v4/projects/my-scope%2Fmy-pkg/packages/npm/',
|
|
309
328
|
'npm show @my-scope/my-pkg@latest version --registry https://gitlab.com/api/v4/projects/my-scope%2Fmy-pkg/packages/npm/',
|
|
310
|
-
'npm
|
|
329
|
+
'npm --version',
|
|
311
330
|
'npm version 1.0.1 --no-git-tag-version',
|
|
312
331
|
'npm publish . --tag latest'
|
|
313
332
|
]);
|
|
@@ -326,7 +345,9 @@ test('should not publish when `npm version` fails', async t => {
|
|
|
326
345
|
const npmClient = factory(npm, { options });
|
|
327
346
|
const exec = sinon.stub(npmClient.shell, 'exec').resolves();
|
|
328
347
|
exec.withArgs('npm whoami').resolves('john');
|
|
329
|
-
exec
|
|
348
|
+
exec
|
|
349
|
+
.withArgs(/npm access (list collaborators --json|ls-collaborators) @my-scope\/my-pkg/)
|
|
350
|
+
.resolves(JSON.stringify({ john: ['write'] }));
|
|
330
351
|
exec
|
|
331
352
|
.withArgs('npm version 1.0.1 --no-git-tag-version')
|
|
332
353
|
.rejects('npm ERR! Version not changed, might want --allow-same-version');
|
|
@@ -341,7 +362,7 @@ test('should not publish when `npm version` fails', async t => {
|
|
|
341
362
|
'npm ping',
|
|
342
363
|
'npm whoami',
|
|
343
364
|
'npm show @my-scope/my-pkg@latest version',
|
|
344
|
-
'npm
|
|
365
|
+
'npm --version',
|
|
345
366
|
'npm version 1.0.1 --no-git-tag-version'
|
|
346
367
|
]);
|
|
347
368
|
|
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
|
|
@@ -128,7 +131,7 @@ test.serial('should use pkg.version (in sub dir) w/o tagging repo', async t => {
|
|
|
128
131
|
const { stdout } = sh.exec('git describe --tags --match=* --abbrev=0');
|
|
129
132
|
t.is(stdout.trim(), '1.0.0');
|
|
130
133
|
const npmArgs = getArgs(exec.args, 'npm');
|
|
131
|
-
t.is(npmArgs[
|
|
134
|
+
t.is(npmArgs[5], 'npm version 1.3.0 --no-git-tag-version');
|
|
132
135
|
exec.restore();
|
|
133
136
|
});
|
|
134
137
|
|
|
@@ -174,7 +177,8 @@ test.serial('should release all the things (basic)', async t => {
|
|
|
174
177
|
'npm ping',
|
|
175
178
|
'npm whoami',
|
|
176
179
|
`npm show ${pkgName}@latest version`,
|
|
177
|
-
|
|
180
|
+
'npm --version',
|
|
181
|
+
`npm access ${npmMajorVersion >= 9 ? 'list collaborators --json' : 'ls-collaborators'} ${pkgName}`,
|
|
178
182
|
'npm version 1.0.1 --no-git-tag-version',
|
|
179
183
|
'npm publish . --tag latest'
|
|
180
184
|
]);
|
|
@@ -307,7 +311,8 @@ test.serial('should release all the things (pre-release, github, gitlab)', async
|
|
|
307
311
|
'npm ping',
|
|
308
312
|
'npm whoami',
|
|
309
313
|
`npm show ${pkgName}@latest version`,
|
|
310
|
-
|
|
314
|
+
'npm --version',
|
|
315
|
+
`npm access ${npmMajorVersion >= 9 ? 'list collaborators --json' : 'ls-collaborators'} ${pkgName}`,
|
|
311
316
|
'npm version 1.1.0-alpha.0 --no-git-tag-version',
|
|
312
317
|
'npm publish . --tag alpha'
|
|
313
318
|
]);
|
|
@@ -346,7 +351,8 @@ test.serial('should publish pre-release without pre-id with different npm.tag',
|
|
|
346
351
|
'npm ping',
|
|
347
352
|
'npm whoami',
|
|
348
353
|
`npm show ${pkgName}@latest version`,
|
|
349
|
-
|
|
354
|
+
'npm --version',
|
|
355
|
+
`npm access ${npmMajorVersion >= 9 ? 'list collaborators --json' : 'ls-collaborators'} ${pkgName}`,
|
|
350
356
|
'npm version 2.0.0-0 --no-git-tag-version',
|
|
351
357
|
'npm publish . --tag next'
|
|
352
358
|
]);
|
|
@@ -393,7 +399,7 @@ test.serial('should initially publish non-private scoped npm package privately',
|
|
|
393
399
|
await runTasks({}, container);
|
|
394
400
|
|
|
395
401
|
const npmArgs = getArgs(container.shell.exec.args, 'npm');
|
|
396
|
-
t.is(npmArgs[
|
|
402
|
+
t.is(npmArgs[6], 'npm publish . --tag latest');
|
|
397
403
|
exec.restore();
|
|
398
404
|
});
|
|
399
405
|
|