release-it 19.0.0-next.2 → 19.0.0-next.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 +1 -1
- package/lib/log.js +5 -5
- package/lib/plugin/gitlab/GitLab.js +7 -3
- package/lib/plugin/version/Version.js +6 -4
- package/package.json +6 -9
- package/test/config.js +2 -6
- package/test/github.js +7 -9
- package/test/gitlab.js +11 -12
- package/test/stub/gitlab.js +6 -4
- package/test/tasks.interactive.js +6 -8
- package/test/tasks.js +6 -8
- package/test/util/mock.js +11 -0
package/README.md
CHANGED
|
@@ -400,7 +400,7 @@ Are you using release-it at work? Please consider [sponsoring me][14]!
|
|
|
400
400
|
[29]: ./docs/git.md
|
|
401
401
|
[30]: https://docs.github.com/en/repositories/releasing-projects-on-github/about-releases
|
|
402
402
|
[31]: ./docs/github-releases.md
|
|
403
|
-
[32]: https://docs.gitlab.com/
|
|
403
|
+
[32]: https://docs.gitlab.com/api/releases/
|
|
404
404
|
[33]: https://gitlab.com/profile/personal_access_tokens
|
|
405
405
|
[34]: ./docs/environment-variables.md
|
|
406
406
|
[35]: ./docs/gitlab-releases.md
|
package/lib/log.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { EOL } from 'node:os';
|
|
2
|
-
import
|
|
2
|
+
import { styleText } from 'node:util';
|
|
3
3
|
import { isObjectLoose } from '@phun-ky/typeof';
|
|
4
4
|
import { upperFirst } from './util.js';
|
|
5
5
|
|
|
@@ -20,15 +20,15 @@ class Logger {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
error(...args) {
|
|
23
|
-
console.error(
|
|
23
|
+
console.error([styleText('red', 'ERROR'), ...args].join(' '));
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
info(...args) {
|
|
27
|
-
console.error(
|
|
27
|
+
console.error(styleText('grey', args.join(' ')));
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
warn(...args) {
|
|
31
|
-
console.error(
|
|
31
|
+
console.error([styleText('yellow', 'WARNING'), ...args].join(' '));
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
verbose(...args) {
|
|
@@ -58,7 +58,7 @@ class Logger {
|
|
|
58
58
|
|
|
59
59
|
preview({ title, text }) {
|
|
60
60
|
if (text) {
|
|
61
|
-
const header =
|
|
61
|
+
const header = styleText('bold', upperFirst(title));
|
|
62
62
|
const body = text.replace(new RegExp(EOL + EOL, 'g'), EOL);
|
|
63
63
|
this.obtrusive(`${header}:${EOL}${body}`);
|
|
64
64
|
} else {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
-
import fs
|
|
2
|
+
import fs from 'node:fs'; // import fs here so it can be stubbed in tests
|
|
3
|
+
import { readFile } from 'node:fs/promises';
|
|
3
4
|
import { globby } from 'globby';
|
|
4
5
|
import { Agent } from 'undici';
|
|
5
6
|
import Release from '../GitRelease.js';
|
|
@@ -264,14 +265,17 @@ class GitLab extends Release {
|
|
|
264
265
|
const name = path.basename(filePath);
|
|
265
266
|
const { useIdsForUrls, useGenericPackageRepositoryForAssets, genericPackageRepositoryName } = this.options;
|
|
266
267
|
const { id, origin, repo, version, baseUrl } = this.getContext();
|
|
268
|
+
|
|
267
269
|
const endpoint = useGenericPackageRepositoryForAssets
|
|
268
270
|
? `projects/${id}/packages/generic/${genericPackageRepositoryName}/${version}/${name}`
|
|
269
271
|
: `projects/${id}/uploads`;
|
|
272
|
+
|
|
270
273
|
if (useGenericPackageRepositoryForAssets) {
|
|
271
274
|
const options = {
|
|
272
275
|
method: 'PUT',
|
|
273
|
-
body: await
|
|
276
|
+
body: await readFile(filePath)
|
|
274
277
|
};
|
|
278
|
+
|
|
275
279
|
try {
|
|
276
280
|
const body = await this.request(endpoint, options);
|
|
277
281
|
if (!(body.message && body.message == '201 Created')) {
|
|
@@ -288,7 +292,7 @@ class GitLab extends Release {
|
|
|
288
292
|
}
|
|
289
293
|
} else {
|
|
290
294
|
const body = new FormData();
|
|
291
|
-
const rawData = await
|
|
295
|
+
const rawData = await readFile(filePath);
|
|
292
296
|
body.set('file', new Blob([rawData]), name);
|
|
293
297
|
const options = { body };
|
|
294
298
|
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
+
import { styleText } from 'node:util';
|
|
1
2
|
import semver from 'semver';
|
|
2
|
-
import chalk from 'chalk';
|
|
3
3
|
import Plugin from '../Plugin.js';
|
|
4
4
|
|
|
5
|
-
const { green, red, redBright } = chalk;
|
|
6
|
-
|
|
7
5
|
const RELEASE_TYPES = ['patch', 'minor', 'major'];
|
|
8
6
|
const PRERELEASE_TYPES = ['prepatch', 'preminor', 'premajor'];
|
|
9
7
|
const CONTINUATION_TYPES = ['prerelease', 'pre'];
|
|
@@ -30,7 +28,11 @@ const getIncrementChoices = context => {
|
|
|
30
28
|
};
|
|
31
29
|
|
|
32
30
|
const versionTransformer = context => input =>
|
|
33
|
-
semver.valid(input)
|
|
31
|
+
semver.valid(input)
|
|
32
|
+
? semver.gt(input, context.latestVersion)
|
|
33
|
+
? styleText('green', input)
|
|
34
|
+
: styleText('red', input)
|
|
35
|
+
: styleText(['red', 'bold'], input);
|
|
34
36
|
|
|
35
37
|
const prompts = {
|
|
36
38
|
incrementList: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "release-it",
|
|
3
|
-
"version": "19.0.0-next.
|
|
3
|
+
"version": "19.0.0-next.3",
|
|
4
4
|
"description": "Generic CLI tool to automate versioning and package publishing-related tasks.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"build",
|
|
@@ -83,7 +83,6 @@
|
|
|
83
83
|
"@octokit/rest": "21.1.1",
|
|
84
84
|
"@phun-ky/typeof": "1.2.3",
|
|
85
85
|
"async-retry": "1.3.3",
|
|
86
|
-
"chalk": "5.4.1",
|
|
87
86
|
"ci-info": "^4.2.0",
|
|
88
87
|
"cosmiconfig": "9.0.0",
|
|
89
88
|
"eta": "3.5.0",
|
|
@@ -94,14 +93,14 @@
|
|
|
94
93
|
"issue-parser": "7.0.1",
|
|
95
94
|
"lodash.get": "4.4.2",
|
|
96
95
|
"lodash.merge": "4.6.2",
|
|
97
|
-
"mime-types": "
|
|
96
|
+
"mime-types": "3.0.1",
|
|
98
97
|
"new-github-release-url": "2.0.0",
|
|
99
98
|
"open": "10.1.0",
|
|
100
99
|
"ora": "8.2.0",
|
|
101
100
|
"os-name": "6.0.0",
|
|
102
101
|
"proxy-agent": "6.5.0",
|
|
103
102
|
"semver": "7.7.1",
|
|
104
|
-
"undici": "6.21.
|
|
103
|
+
"undici": "6.21.2",
|
|
105
104
|
"update-notifier": "7.3.1",
|
|
106
105
|
"url-join": "5.0.0",
|
|
107
106
|
"wildcard-match": "5.1.4",
|
|
@@ -112,14 +111,12 @@
|
|
|
112
111
|
"@eslint/eslintrc": "3.3.1",
|
|
113
112
|
"@eslint/js": "9.23.0",
|
|
114
113
|
"@octokit/request-error": "6.1.7",
|
|
115
|
-
"@types/node": "20.17.
|
|
114
|
+
"@types/node": "20.17.28",
|
|
116
115
|
"eslint": "9.23.0",
|
|
117
|
-
"eslint-
|
|
118
|
-
"eslint-plugin-import-x": "4.9.3",
|
|
119
|
-
"eslint-plugin-prettier": "5.2.5",
|
|
116
|
+
"eslint-plugin-import-x": "4.9.4",
|
|
120
117
|
"globals": "16.0.0",
|
|
121
118
|
"installed-check": "9.3.0",
|
|
122
|
-
"knip": "5.46.
|
|
119
|
+
"knip": "5.46.3",
|
|
123
120
|
"mentoss": "0.9.0",
|
|
124
121
|
"mock-stdio": "1.0.3",
|
|
125
122
|
"prettier": "3.5.3",
|
package/test/config.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import test, { describe, before, after, afterEach } from 'node:test';
|
|
2
2
|
import assert from 'node:assert/strict';
|
|
3
3
|
import { isCI } from 'ci-info';
|
|
4
|
-
import { MockServer, FetchMocker } from 'mentoss';
|
|
5
4
|
import Config, { getRemoteConfiguration } from '../lib/config.js';
|
|
6
5
|
import { readJSON } from '../lib/util.js';
|
|
6
|
+
import { mockFetch } from './util/mock.js';
|
|
7
7
|
|
|
8
8
|
const defaultConfig = readJSON(new URL('../config/release-it.json', import.meta.url));
|
|
9
9
|
const projectConfig = readJSON(new URL('../.release-it.json', import.meta.url));
|
|
@@ -165,11 +165,7 @@ describe('config', () => {
|
|
|
165
165
|
});
|
|
166
166
|
|
|
167
167
|
describe('fetch extended configuration', () => {
|
|
168
|
-
const server =
|
|
169
|
-
|
|
170
|
-
const mocker = new FetchMocker({
|
|
171
|
-
servers: [server]
|
|
172
|
-
});
|
|
168
|
+
const [mocker, server] = mockFetch('https://raw.githubusercontent.com');
|
|
173
169
|
|
|
174
170
|
before(() => {
|
|
175
171
|
mocker.mockGlobal();
|
package/test/github.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import test, { describe, before, after, afterEach } from 'node:test';
|
|
2
2
|
import assert from 'node:assert/strict';
|
|
3
3
|
import { RequestError } from '@octokit/request-error';
|
|
4
|
-
import { MockServer, FetchMocker } from 'mentoss';
|
|
5
4
|
import GitHub from '../lib/plugin/github/GitHub.js';
|
|
6
5
|
import { getSearchQueries } from '../lib/plugin/github/util.js';
|
|
7
6
|
import { factory, runTasks } from './util/index.js';
|
|
@@ -13,6 +12,7 @@ import {
|
|
|
13
12
|
interceptUpdate,
|
|
14
13
|
interceptAsset
|
|
15
14
|
} from './stub/github.js';
|
|
15
|
+
import { mockFetch } from './util/mock.js';
|
|
16
16
|
|
|
17
17
|
describe('github', () => {
|
|
18
18
|
const tokenRef = 'GITHUB_TOKEN';
|
|
@@ -21,14 +21,12 @@ describe('github', () => {
|
|
|
21
21
|
const git = { changelog: '' };
|
|
22
22
|
const requestErrorOptions = { request: { url: '', headers: {} }, response: { headers: {} } };
|
|
23
23
|
|
|
24
|
-
const api =
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
servers: [api, assets, example, custom]
|
|
31
|
-
});
|
|
24
|
+
const [mocker, api, assets, example, custom] = mockFetch([
|
|
25
|
+
'https://api.github.com',
|
|
26
|
+
'https://uploads.github.com',
|
|
27
|
+
'https://github.example.org/api/v3',
|
|
28
|
+
'https://custom.example.org/api/v3'
|
|
29
|
+
]);
|
|
32
30
|
|
|
33
31
|
before(() => {
|
|
34
32
|
mocker.mockGlobal();
|
package/test/gitlab.js
CHANGED
|
@@ -2,7 +2,6 @@ import fs from 'node:fs';
|
|
|
2
2
|
import test, { before, after, afterEach, beforeEach, describe } from 'node:test';
|
|
3
3
|
import assert from 'node:assert/strict';
|
|
4
4
|
import { Agent } from 'undici';
|
|
5
|
-
import { MockServer, FetchMocker } from 'mentoss';
|
|
6
5
|
import Git from '../lib/plugin/git/Git.js';
|
|
7
6
|
import GitLab from '../lib/plugin/gitlab/GitLab.js';
|
|
8
7
|
import { GitlabTestServer } from './util/https-server/server.js';
|
|
@@ -13,21 +12,21 @@ import {
|
|
|
13
12
|
interceptPublish,
|
|
14
13
|
interceptAsset,
|
|
15
14
|
interceptAssetGeneric,
|
|
16
|
-
interceptMilestones
|
|
15
|
+
interceptMilestones,
|
|
16
|
+
interceptMembers
|
|
17
17
|
} from './stub/gitlab.js';
|
|
18
|
+
import { mockFetch } from './util/mock.js';
|
|
18
19
|
|
|
19
20
|
describe('GitLab', () => {
|
|
20
21
|
const tokenHeader = 'Private-Token';
|
|
21
22
|
const tokenRef = 'GITLAB_TOKEN';
|
|
22
23
|
const certificateAuthorityFileRef = 'CI_SERVER_TLS_CA_FILE';
|
|
23
24
|
|
|
24
|
-
const api =
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
servers: [api, example, local]
|
|
30
|
-
});
|
|
25
|
+
const [mocker, api, example, local] = mockFetch([
|
|
26
|
+
'https://gitlab.com/api/v4',
|
|
27
|
+
'https://gitlab.example.org/api/v4',
|
|
28
|
+
'https://localhost:3000/api/v4'
|
|
29
|
+
]);
|
|
31
30
|
|
|
32
31
|
before(() => {
|
|
33
32
|
mocker.mockGlobal();
|
|
@@ -129,7 +128,7 @@ describe('GitLab', () => {
|
|
|
129
128
|
assert.equal(releaseUrl, `${pushRepo}/-/releases/2.0.1`);
|
|
130
129
|
});
|
|
131
130
|
|
|
132
|
-
test('should upload assets with ID-based URLs
|
|
131
|
+
test('should upload assets with ID-based URLs', async t => {
|
|
133
132
|
const host = 'https://gitlab.com';
|
|
134
133
|
const pushRepo = `${host}/user/repo`;
|
|
135
134
|
const options = {
|
|
@@ -266,7 +265,7 @@ describe('GitLab', () => {
|
|
|
266
265
|
const options = { gitlab: { tokenRef, pushRepo, host } };
|
|
267
266
|
const gitlab = factory(GitLab, { options });
|
|
268
267
|
|
|
269
|
-
api
|
|
268
|
+
interceptMembers(api, { owner: 'emma' });
|
|
270
269
|
interceptUser(api, { owner: 'john' });
|
|
271
270
|
|
|
272
271
|
await assert.rejects(runTasks(gitlab), /User john is not a collaborator for john\/repo/);
|
|
@@ -278,7 +277,7 @@ describe('GitLab', () => {
|
|
|
278
277
|
const options = { gitlab: { tokenRef, pushRepo, host } };
|
|
279
278
|
const gitlab = factory(GitLab, { options });
|
|
280
279
|
|
|
281
|
-
api
|
|
280
|
+
interceptMembers(api, { owner: 'john', access_level: 10 });
|
|
282
281
|
interceptUser(api, { owner: 'john' });
|
|
283
282
|
|
|
284
283
|
await assert.rejects(runTasks(gitlab), /User john is not a collaborator for john\/repo/);
|
package/test/stub/gitlab.js
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
export const interceptMembers = (server, { owner = 'emma' } = {}) => {
|
|
2
|
+
server.get(`/projects/john%2Frepo/members/all/1`, { status: 200, username: owner });
|
|
3
|
+
};
|
|
4
|
+
|
|
1
5
|
export const interceptUser = (server, { owner = 'user' } = {}, options = {}) => {
|
|
2
6
|
server.get({ url: '/user', ...options }, { status: 200, body: { id: 1, username: owner } });
|
|
3
7
|
};
|
|
@@ -52,10 +56,8 @@ export const interceptAsset = (server, { owner = 'user', project = 'repo' } = {}
|
|
|
52
56
|
url: `/projects/${owner}%2F${project}/uploads`
|
|
53
57
|
},
|
|
54
58
|
async request => {
|
|
55
|
-
const
|
|
56
|
-
const {
|
|
57
|
-
const bodyText = new TextDecoder().decode(value);
|
|
58
|
-
const [, name] = bodyText.match(/filename="([^"]+)"/);
|
|
59
|
+
const formData = await request.formData();
|
|
60
|
+
const { name } = formData.get('file');
|
|
59
61
|
return {
|
|
60
62
|
status: 200,
|
|
61
63
|
body: {
|
|
@@ -3,7 +3,6 @@ import { renameSync } from 'node:fs';
|
|
|
3
3
|
import childProcess from 'node:child_process';
|
|
4
4
|
import test, { afterEach, after, before, beforeEach, describe, mock } from 'node:test';
|
|
5
5
|
import assert from 'node:assert/strict';
|
|
6
|
-
import { MockServer, FetchMocker } from 'mentoss';
|
|
7
6
|
import Prompt from '../lib/prompt.js';
|
|
8
7
|
import Config from '../lib/config.js';
|
|
9
8
|
import runTasks from '../lib/index.js';
|
|
@@ -14,15 +13,14 @@ import ShellStub from './stub/shell.js';
|
|
|
14
13
|
import { interceptPublish as interceptGitLabPublish } from './stub/gitlab.js';
|
|
15
14
|
import { interceptCreate as interceptGitHubCreate } from './stub/github.js';
|
|
16
15
|
import { factory, LogStub, SpinnerStub } from './util/index.js';
|
|
16
|
+
import { mockFetch } from './util/mock.js';
|
|
17
17
|
|
|
18
18
|
describe('tasks.interactive', () => {
|
|
19
|
-
const github =
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
servers: [github, gitlab, githubusercontent]
|
|
25
|
-
});
|
|
19
|
+
const [mocker, github, gitlab, githubusercontent] = mockFetch([
|
|
20
|
+
'https://api.github.com',
|
|
21
|
+
'https://gitlab.com/api/v4',
|
|
22
|
+
'https://raw.githubusercontent.com'
|
|
23
|
+
]);
|
|
26
24
|
|
|
27
25
|
before(() => {
|
|
28
26
|
mocker.mockGlobal();
|
package/test/tasks.js
CHANGED
|
@@ -4,7 +4,6 @@ import { appendFileSync, mkdirSync, renameSync } from 'node:fs';
|
|
|
4
4
|
import test, { after, afterEach, before, beforeEach, describe } from 'node:test';
|
|
5
5
|
import assert from 'node:assert/strict';
|
|
6
6
|
import semver from 'semver';
|
|
7
|
-
import { MockServer, FetchMocker } from 'mentoss';
|
|
8
7
|
import Config from '../lib/config.js';
|
|
9
8
|
import runTasks from '../lib/index.js';
|
|
10
9
|
import Git from '../lib/plugin/git/Git.js';
|
|
@@ -24,17 +23,16 @@ import {
|
|
|
24
23
|
interceptAsset as interceptGitHubAsset
|
|
25
24
|
} from './stub/github.js';
|
|
26
25
|
import { factory, LogStub, SpinnerStub } from './util/index.js';
|
|
26
|
+
import { mockFetch } from './util/mock.js';
|
|
27
27
|
|
|
28
28
|
describe('tasks', () => {
|
|
29
29
|
const rootDir = new URL('..', import.meta.url);
|
|
30
30
|
|
|
31
|
-
const github =
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
servers: [github, assets, gitlab]
|
|
37
|
-
});
|
|
31
|
+
const [mocker, github, assets, gitlab] = mockFetch([
|
|
32
|
+
'https://api.github.com',
|
|
33
|
+
'https://uploads.github.com',
|
|
34
|
+
'https://gitlab.com/api/v4'
|
|
35
|
+
]);
|
|
38
36
|
|
|
39
37
|
const npmMajorVersion = semver.major(process.env.npm_config_user_agent.match(/npm\/([^ ]+)/)[1]);
|
|
40
38
|
|