release-it 19.0.2 → 19.0.4
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/config/release-it.json +1 -1
- package/lib/config.js +1 -2
- package/lib/plugin/Plugin.js +1 -1
- package/lib/plugin/git/Git.js +8 -6
- package/lib/plugin/github/GitHub.js +1 -1
- package/lib/plugin/npm/npm.js +2 -1
- package/lib/shell.js +43 -13
- package/lib/util.js +25 -0
- package/package.json +16 -18
- package/schema/gitlab.json +1 -1
- package/test/utils.js +51 -1
- package/types/config.d.ts +1 -1
package/README.md
CHANGED
|
@@ -162,7 +162,7 @@ GitLab projects can have releases attached to Git tags, containing release notes
|
|
|
162
162
|
releases][32]:
|
|
163
163
|
|
|
164
164
|
- Configure `gitlab.release: true`
|
|
165
|
-
- Obtain a [personal access token][33] (release-it
|
|
165
|
+
- Obtain a [personal access token][33] (release-it needs the `api` and `self_rotate` scopes).
|
|
166
166
|
- Make sure the token is [available as an environment variable][34].
|
|
167
167
|
|
|
168
168
|
→ See [GitLab Releases][35] for more details.
|
package/config/release-it.json
CHANGED
package/lib/config.js
CHANGED
|
@@ -4,9 +4,8 @@ import { isCI } from 'ci-info';
|
|
|
4
4
|
import defaultsDeep from '@nodeutils/defaults-deep';
|
|
5
5
|
import { isObjectStrict } from '@phun-ky/typeof';
|
|
6
6
|
import merge from 'lodash.merge';
|
|
7
|
-
import get from 'lodash.get';
|
|
8
7
|
import { loadConfig as loadC12 } from 'c12';
|
|
9
|
-
import { getSystemInfo, readJSON } from './util.js';
|
|
8
|
+
import { get, getSystemInfo, readJSON } from './util.js';
|
|
10
9
|
|
|
11
10
|
const debug = util.debug('release-it:config');
|
|
12
11
|
const defaultConfig = readJSON(new URL('../config/release-it.json', import.meta.url));
|
package/lib/plugin/Plugin.js
CHANGED
package/lib/plugin/git/Git.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { EOL } from 'node:os';
|
|
2
|
-
import {
|
|
2
|
+
import { spawn } from 'node:child_process';
|
|
3
3
|
import matcher from 'wildcard-match';
|
|
4
4
|
import { format, e, fixArgs, once, castArray } from '../../util.js';
|
|
5
5
|
import GitBase from '../GitBase.js';
|
|
@@ -11,11 +11,13 @@ const options = { write: false };
|
|
|
11
11
|
|
|
12
12
|
const docs = 'https://git.io/release-it-git';
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
(
|
|
17
|
-
(
|
|
18
|
-
|
|
14
|
+
async function isGitRepo() {
|
|
15
|
+
return await new Promise(resolve => {
|
|
16
|
+
const process = spawn('git', ['rev-parse', '--git-dir']);
|
|
17
|
+
process.on('close', code => resolve(code === 0));
|
|
18
|
+
process.on('error', () => resolve(false));
|
|
19
|
+
});
|
|
20
|
+
}
|
|
19
21
|
|
|
20
22
|
class Git extends GitBase {
|
|
21
23
|
constructor(...args) {
|
package/lib/plugin/npm/npm.js
CHANGED
|
@@ -14,6 +14,7 @@ const DEFAULT_TAG = 'latest';
|
|
|
14
14
|
const DEFAULT_TAG_PRERELEASE = 'next';
|
|
15
15
|
const NPM_BASE_URL = 'https://www.npmjs.com';
|
|
16
16
|
const NPM_PUBLIC_PATH = '/package';
|
|
17
|
+
const DEFAULT_TIMEOUT = 10;
|
|
17
18
|
|
|
18
19
|
class npm extends Plugin {
|
|
19
20
|
static isEnabled(options) {
|
|
@@ -32,7 +33,7 @@ class npm extends Plugin {
|
|
|
32
33
|
|
|
33
34
|
const { publish, skipChecks } = this.options;
|
|
34
35
|
|
|
35
|
-
const timeout = Number(this.options.timeout) * 1000;
|
|
36
|
+
const timeout = Number(this.options.timeout ?? DEFAULT_TIMEOUT) * 1000;
|
|
36
37
|
|
|
37
38
|
if (publish === false || isPrivate) return;
|
|
38
39
|
|
package/lib/shell.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import util from 'node:util';
|
|
2
|
-
import
|
|
3
|
-
import { x } from 'tinyexec';
|
|
2
|
+
import { spawn, exec } from 'node:child_process';
|
|
4
3
|
import { format } from './util.js';
|
|
5
4
|
|
|
6
5
|
const debug = util.debug('release-it:shell');
|
|
@@ -53,7 +52,7 @@ class Shell {
|
|
|
53
52
|
|
|
54
53
|
execStringCommand(command, options, { isExternal }) {
|
|
55
54
|
return new Promise((resolve, reject) => {
|
|
56
|
-
const proc =
|
|
55
|
+
const proc = exec(command, (err, stdout, stderr) => {
|
|
57
56
|
stdout = stdout.toString().trimEnd();
|
|
58
57
|
const code = !err ? 0 : err === 'undefined' ? 1 : err.code;
|
|
59
58
|
debug({ command, options, code, stdout, stderr });
|
|
@@ -68,21 +67,52 @@ class Shell {
|
|
|
68
67
|
});
|
|
69
68
|
}
|
|
70
69
|
|
|
71
|
-
async execWithArguments(command, options, { isExternal }) {
|
|
70
|
+
async execWithArguments(command, options = {}, { isExternal } = {}) {
|
|
72
71
|
const [program, ...programArgs] = command;
|
|
73
72
|
|
|
74
73
|
try {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
74
|
+
return await new Promise((resolve, reject) => {
|
|
75
|
+
const proc = spawn(program, programArgs, {
|
|
76
|
+
// we want to capture all output from the process so the extra 2 pipe
|
|
77
|
+
stdio: ['inherit', 'pipe', 'pipe'],
|
|
78
|
+
...options
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
let stdout = '';
|
|
82
|
+
let stderr = '';
|
|
83
|
+
|
|
84
|
+
proc.stdout.on('data', data => {
|
|
85
|
+
stdout += data.toString();
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
proc.stderr.on('data', data => {
|
|
89
|
+
stderr += data.toString();
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
proc.on('close', code => {
|
|
93
|
+
stdout = stdout === '""' ? '' : stdout;
|
|
94
|
+
this.log.verbose(stdout, { isExternal });
|
|
95
|
+
debug({ command, options, stdout, stderr });
|
|
96
|
+
|
|
97
|
+
if (code === 0) {
|
|
98
|
+
resolve((stdout || stderr).trim());
|
|
99
|
+
} else {
|
|
100
|
+
if (stdout) {
|
|
101
|
+
this.log.log(`\n${stdout}`);
|
|
102
|
+
}
|
|
103
|
+
debug({ code, command, options, stdout, stderr });
|
|
104
|
+
reject(new Error(stderr || stdout || `Process exited with code ${code}`));
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
proc.on('error', err => {
|
|
109
|
+
debug(err);
|
|
110
|
+
reject(new Error(err.message));
|
|
111
|
+
});
|
|
112
|
+
});
|
|
80
113
|
} catch (err) {
|
|
81
|
-
if (err.output.stdout) {
|
|
82
|
-
this.log.log(`\n${err.output.stdout}`);
|
|
83
|
-
}
|
|
84
114
|
debug(err);
|
|
85
|
-
return Promise.reject(
|
|
115
|
+
return Promise.reject(err);
|
|
86
116
|
}
|
|
87
117
|
}
|
|
88
118
|
}
|
package/lib/util.js
CHANGED
|
@@ -179,3 +179,28 @@ export const pick = (object, keys) => {
|
|
|
179
179
|
return obj;
|
|
180
180
|
}, {});
|
|
181
181
|
};
|
|
182
|
+
|
|
183
|
+
const parsePath = (path)=> {
|
|
184
|
+
const result = [];
|
|
185
|
+
const regex = /[^.[\]]+|\[(?:(\d+)|["'](.+?)["'])\]/g;
|
|
186
|
+
let match;
|
|
187
|
+
|
|
188
|
+
while ((match = regex.exec(path)) !== null) {
|
|
189
|
+
result.push(match[1] ?? match[2] ?? match[0]);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return result;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export const get = (obj, path, defaultValue = undefined) =>{
|
|
196
|
+
if (!path || typeof path !== 'string') {
|
|
197
|
+
return defaultValue;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
try {
|
|
201
|
+
const keys = parsePath(path);
|
|
202
|
+
return keys.reduce((acc, key) => acc?.[key], obj) ?? defaultValue;
|
|
203
|
+
} catch {
|
|
204
|
+
return defaultValue;
|
|
205
|
+
}
|
|
206
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "release-it",
|
|
3
|
-
"version": "19.0.
|
|
3
|
+
"version": "19.0.4",
|
|
4
4
|
"description": "Generic CLI tool to automate versioning and package publishing-related tasks.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"build",
|
|
@@ -82,42 +82,40 @@
|
|
|
82
82
|
"@octokit/rest": "21.1.1",
|
|
83
83
|
"@phun-ky/typeof": "1.2.8",
|
|
84
84
|
"async-retry": "1.3.3",
|
|
85
|
-
"c12": "3.0
|
|
86
|
-
"ci-info": "^4.
|
|
85
|
+
"c12": "3.1.0",
|
|
86
|
+
"ci-info": "^4.3.0",
|
|
87
87
|
"eta": "3.5.0",
|
|
88
88
|
"git-url-parse": "16.1.0",
|
|
89
|
-
"inquirer": "12.
|
|
89
|
+
"inquirer": "12.7.0",
|
|
90
90
|
"issue-parser": "7.0.1",
|
|
91
|
-
"lodash.get": "4.4.2",
|
|
92
91
|
"lodash.merge": "4.6.2",
|
|
93
92
|
"mime-types": "3.0.1",
|
|
94
93
|
"new-github-release-url": "2.0.0",
|
|
95
|
-
"open": "10.
|
|
94
|
+
"open": "10.2.0",
|
|
96
95
|
"ora": "8.2.0",
|
|
97
|
-
"os-name": "6.
|
|
96
|
+
"os-name": "6.1.0",
|
|
98
97
|
"proxy-agent": "6.5.0",
|
|
99
|
-
"semver": "7.7.
|
|
100
|
-
"
|
|
101
|
-
"
|
|
102
|
-
"undici": "6.21.2",
|
|
98
|
+
"semver": "7.7.2",
|
|
99
|
+
"tinyglobby": "0.2.14",
|
|
100
|
+
"undici": "6.21.3",
|
|
103
101
|
"url-join": "5.0.0",
|
|
104
102
|
"wildcard-match": "5.1.4",
|
|
105
103
|
"yargs-parser": "21.1.1"
|
|
106
104
|
},
|
|
107
105
|
"devDependencies": {
|
|
108
|
-
"@eslint/compat": "1.
|
|
106
|
+
"@eslint/compat": "1.3.1",
|
|
109
107
|
"@eslint/eslintrc": "3.3.1",
|
|
110
|
-
"@eslint/js": "9.
|
|
108
|
+
"@eslint/js": "9.31.0",
|
|
111
109
|
"@octokit/request-error": "6.1.8",
|
|
112
110
|
"@types/node": "20.17.32",
|
|
113
|
-
"eslint": "9.
|
|
114
|
-
"eslint-plugin-import-x": "4.
|
|
115
|
-
"globals": "16.
|
|
111
|
+
"eslint": "9.31.0",
|
|
112
|
+
"eslint-plugin-import-x": "4.16.1",
|
|
113
|
+
"globals": "16.3.0",
|
|
116
114
|
"installed-check": "9.3.0",
|
|
117
|
-
"knip": "5.
|
|
115
|
+
"knip": "5.61.3",
|
|
118
116
|
"mentoss": "0.11.0",
|
|
119
117
|
"mock-stdio": "1.0.3",
|
|
120
|
-
"prettier": "3.
|
|
118
|
+
"prettier": "3.6.2",
|
|
121
119
|
"remark-cli": "12.0.1",
|
|
122
120
|
"remark-preset-webpro": "1.1.1",
|
|
123
121
|
"tar": "7.4.3",
|
package/schema/gitlab.json
CHANGED
package/test/utils.js
CHANGED
|
@@ -3,7 +3,7 @@ import test from 'node:test';
|
|
|
3
3
|
import assert from 'node:assert/strict';
|
|
4
4
|
import { stripVTControlCharacters } from 'node:util';
|
|
5
5
|
import mockStdIo from 'mock-stdio';
|
|
6
|
-
import { format, truncateLines, parseGitUrl, parseVersion } from '../lib/util.js';
|
|
6
|
+
import { format, truncateLines, parseGitUrl, parseVersion, get } from '../lib/util.js';
|
|
7
7
|
|
|
8
8
|
test('format', () => {
|
|
9
9
|
assert.equal(format('release v${version}', { version: '1.0.0' }), 'release v1.0.0');
|
|
@@ -96,3 +96,53 @@ test('parseVersion', () => {
|
|
|
96
96
|
assert.deepEqual(parseVersion('1.0.0-next.1'), { version: '1.0.0-next.1', isPreRelease: true, preReleaseId: 'next' });
|
|
97
97
|
assert.deepEqual(parseVersion('21.04.1'), { version: '21.04.1', isPreRelease: false, preReleaseId: null });
|
|
98
98
|
});
|
|
99
|
+
|
|
100
|
+
const sample = {
|
|
101
|
+
root: {
|
|
102
|
+
level1: {
|
|
103
|
+
level2: {
|
|
104
|
+
value: 'nested'
|
|
105
|
+
},
|
|
106
|
+
array: [
|
|
107
|
+
{ id: 1, data: 'first' },
|
|
108
|
+
{ id: 2, data: 'second' }
|
|
109
|
+
],
|
|
110
|
+
'key.with.dot': {
|
|
111
|
+
special: true
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
mixed: [
|
|
115
|
+
{ deep: { value: 100 } },
|
|
116
|
+
{ deep: { value: 200 } }
|
|
117
|
+
],
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
test('get: accesses a simple nested property', () => {
|
|
122
|
+
assert.equal(get(sample, 'root.level1.level2.value'), 'nested');
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
test('get: accesses array elements by index', () => {
|
|
126
|
+
assert.equal(get(sample, 'root.level1.array[0].data'), 'first');
|
|
127
|
+
assert.equal(get(sample, 'root.level1.array[1].id'), 2);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
test('get: accesses keys with dots using bracket notation', () => {
|
|
131
|
+
assert.equal(get(sample, 'root.level1["key.with.dot"].special'), true);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
test('get: navigates mixed objects and arrays', () => {
|
|
135
|
+
assert.equal(get(sample, 'root.mixed[0].deep.value'), 100);
|
|
136
|
+
assert.equal(get(sample, 'root.mixed[1].deep.value'), 200);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
test('get: returns default value for non-existent properties', () => {
|
|
140
|
+
assert.equal(get(sample, 'root.level1.unknown', 'default'), 'default');
|
|
141
|
+
assert.equal(get(sample, 'root.level1.array[10].id', null), null);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
test('get: handles empty path and null/undefined objects', () => {
|
|
145
|
+
assert.equal(get(sample, '', 'default'), 'default');
|
|
146
|
+
assert.equal(get(null, 'any.path', 'default'), 'default');
|
|
147
|
+
assert.equal(get(undefined, 'any.path', 'default'), 'default');
|
|
148
|
+
});
|