release-it 15.2.0 → 15.4.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 +3 -0
- package/lib/cli.js +1 -0
- package/lib/config.js +5 -1
- package/lib/index.js +6 -1
- package/lib/plugin/GitBase.js +14 -10
- package/lib/plugin/git/Git.js +2 -2
- package/lib/plugin/npm/npm.js +1 -0
- package/lib/util.js +4 -1
- package/package.json +11 -11
- package/test/git.js +3 -3
- package/test/github.js +1 -1
- package/test/gitlab.js +2 -2
- package/test/tasks.js +43 -0
- package/test/util/helpers.js +4 -1
- package/test/utils.js +29 -2
package/README.md
CHANGED
|
@@ -110,6 +110,8 @@ Use `--dry-run` to show the interactivity and the commands it _would_ execute.
|
|
|
110
110
|
|
|
111
111
|
To print the next version without releasing anything, add the `--release-version` flag.
|
|
112
112
|
|
|
113
|
+
To print the changelog without releasing anything, add the `--changelog` flag.
|
|
114
|
+
|
|
113
115
|
## Configuration
|
|
114
116
|
|
|
115
117
|
Out of the box, release-it has sane defaults, and [plenty of options](./config/release-it.json) to configure it. Most
|
|
@@ -275,6 +277,7 @@ latestVersion
|
|
|
275
277
|
changelog
|
|
276
278
|
name
|
|
277
279
|
repo.remote, repo.protocol, repo.host, repo.owner, repo.repository, repo.project
|
|
280
|
+
branchName
|
|
278
281
|
```
|
|
279
282
|
|
|
280
283
|
All variables are available in all hooks. The only exception is that the additional variables listed above are not yet
|
package/lib/cli.js
CHANGED
|
@@ -20,6 +20,7 @@ const helpText = `Release It! v${pkg.version}
|
|
|
20
20
|
--only-version Prompt only for version, no further interaction
|
|
21
21
|
-v --version Print release-it version number
|
|
22
22
|
--release-version Print version number to be released
|
|
23
|
+
--changelog Print changelog for the version to be released
|
|
23
24
|
-V --verbose Verbose output (user hooks output)
|
|
24
25
|
-VV Extra verbose output (also internal commands output)
|
|
25
26
|
|
package/lib/config.js
CHANGED
|
@@ -109,7 +109,7 @@ class Config {
|
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
get isCI() {
|
|
112
|
-
return Boolean(this.options.ci) || this.isReleaseVersion;
|
|
112
|
+
return Boolean(this.options.ci) || this.isReleaseVersion || this.isChangelog;
|
|
113
113
|
}
|
|
114
114
|
|
|
115
115
|
get isPromptOnlyVersion() {
|
|
@@ -119,6 +119,10 @@ class Config {
|
|
|
119
119
|
get isReleaseVersion() {
|
|
120
120
|
return Boolean(this.options['release-version']);
|
|
121
121
|
}
|
|
122
|
+
|
|
123
|
+
get isChangelog() {
|
|
124
|
+
return Boolean(this.options['changelog']);
|
|
125
|
+
}
|
|
122
126
|
}
|
|
123
127
|
|
|
124
128
|
export default Config;
|
package/lib/index.js
CHANGED
|
@@ -78,7 +78,7 @@ const runTasks = async (opts, di) => {
|
|
|
78
78
|
const action = config.isIncrement ? 'release' : 'update';
|
|
79
79
|
const suffix = version && config.isIncrement ? `${latestVersion}...${version}` : `currently at ${latestVersion}`;
|
|
80
80
|
|
|
81
|
-
if (!config.isReleaseVersion) {
|
|
81
|
+
if (!config.isReleaseVersion && !config.isChangelog) {
|
|
82
82
|
log.obtrusive(`🚀 Let's ${action} ${name} (${suffix})`);
|
|
83
83
|
|
|
84
84
|
log.preview({ title: 'changelog', text: changelog });
|
|
@@ -93,6 +93,11 @@ const runTasks = async (opts, di) => {
|
|
|
93
93
|
process.exit(0);
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
+
if (config.isChangelog) {
|
|
97
|
+
console.log(changelog);
|
|
98
|
+
process.exit(0);
|
|
99
|
+
}
|
|
100
|
+
|
|
96
101
|
if (version) {
|
|
97
102
|
config.setContext(parseVersion(version));
|
|
98
103
|
|
package/lib/plugin/GitBase.js
CHANGED
|
@@ -7,14 +7,18 @@ const changelogFallback = 'git log --pretty=format:"* %s (%h)"';
|
|
|
7
7
|
|
|
8
8
|
class GitBase extends Plugin {
|
|
9
9
|
async init() {
|
|
10
|
-
|
|
11
|
-
await this.fetch();
|
|
12
|
-
|
|
13
|
-
const
|
|
10
|
+
const remoteUrl = await this.getRemoteUrl();
|
|
11
|
+
await this.fetch(remoteUrl);
|
|
12
|
+
|
|
13
|
+
const branchName = await this.getBranchName();
|
|
14
|
+
const repo = parseGitUrl(remoteUrl);
|
|
15
|
+
this.setContext({ remoteUrl, branchName, repo });
|
|
16
|
+
this.config.setContext({ remoteUrl, branchName, repo });
|
|
17
|
+
|
|
18
|
+
const latestTag = await this.getLatestTagName();
|
|
14
19
|
const secondLatestTag = !this.config.isIncrement ? await this.getSecondLatestTagName(latestTag) : null;
|
|
15
20
|
const tagTemplate = this.options.tagName || ((latestTag || '').match(/^v/) ? 'v${version}' : '${version}');
|
|
16
|
-
this.setContext({
|
|
17
|
-
this.config.setContext({ tagTemplate, latestTag, secondLatestTag });
|
|
21
|
+
this.config.setContext({ latestTag, secondLatestTag, tagTemplate });
|
|
18
22
|
}
|
|
19
23
|
|
|
20
24
|
getName() {
|
|
@@ -79,15 +83,15 @@ class GitBase extends Plugin {
|
|
|
79
83
|
return this.exec(`git config --get branch.${branch}.remote`, { options }).catch(() => null);
|
|
80
84
|
}
|
|
81
85
|
|
|
82
|
-
fetch() {
|
|
86
|
+
fetch(remoteUrl) {
|
|
83
87
|
return this.exec('git fetch').catch(err => {
|
|
84
88
|
this.debug(err);
|
|
85
|
-
throw new Error(`Unable to fetch from ${
|
|
89
|
+
throw new Error(`Unable to fetch from ${remoteUrl}${EOL}${err.message}`);
|
|
86
90
|
});
|
|
87
91
|
}
|
|
88
92
|
|
|
89
|
-
getLatestTagName(
|
|
90
|
-
const context = Object.assign({
|
|
93
|
+
getLatestTagName() {
|
|
94
|
+
const context = Object.assign({}, this.config.getContext(), { version: '*' });
|
|
91
95
|
const match = format(this.options.tagMatch || this.options.tagName || '${version}', context);
|
|
92
96
|
return this.exec(`git describe --tags --match=${match} --abbrev=0`, { options }).then(
|
|
93
97
|
stdout => stdout || null,
|
package/lib/plugin/git/Git.js
CHANGED
|
@@ -39,7 +39,8 @@ class Git extends GitBase {
|
|
|
39
39
|
|
|
40
40
|
await super.init();
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
const remoteUrl = this.getContext('remoteUrl');
|
|
43
|
+
if (this.options.push && !remoteUrl) {
|
|
43
44
|
throw e(`Could not get remote Git url.${EOL}Please add a remote repository.`, docs);
|
|
44
45
|
}
|
|
45
46
|
if (this.options.requireUpstream && !(await this.hasUpstreamBranch())) {
|
|
@@ -48,7 +49,6 @@ class Git extends GitBase {
|
|
|
48
49
|
if (this.options.requireCommits && (await this.getCommitsSinceLatestTag()) === 0) {
|
|
49
50
|
throw e(`There are no commits since the latest tag.`, docs);
|
|
50
51
|
}
|
|
51
|
-
this.config.setContext({ repo: this.getContext('repo') });
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
rollback() {
|
package/lib/plugin/npm/npm.js
CHANGED
|
@@ -29,6 +29,7 @@ class npm extends Plugin {
|
|
|
29
29
|
async init() {
|
|
30
30
|
const { name, version: latestVersion, private: isPrivate, publishConfig } = readJSON(path.resolve(MANIFEST_PATH));
|
|
31
31
|
this.setContext({ name, latestVersion, private: isPrivate, publishConfig });
|
|
32
|
+
this.config.setContext({ npm: { name } });
|
|
32
33
|
|
|
33
34
|
const { publish, skipChecks } = this.options;
|
|
34
35
|
|
package/lib/util.js
CHANGED
|
@@ -48,7 +48,10 @@ const rejectAfter = (ms, error) =>
|
|
|
48
48
|
|
|
49
49
|
const parseGitUrl = remoteUrl => {
|
|
50
50
|
if (!remoteUrl) return { host: null, owner: null, project: null, protocol: null, remote: null, repository: null };
|
|
51
|
-
const normalizedUrl = (remoteUrl || '')
|
|
51
|
+
const normalizedUrl = (remoteUrl || '')
|
|
52
|
+
.replace(/^[A-Z]:\\\\/, 'file://') // Assume file protocol for Windows drive letters
|
|
53
|
+
.replace(/^\//, 'file://') // Assume file protocol if only /path is given
|
|
54
|
+
.replace(/\\+/g, '/'); // Replace forward with backslashes
|
|
52
55
|
const parsedUrl = gitUrlParse(normalizedUrl);
|
|
53
56
|
const { resource: host, name: project, protocol, href: remote } = parsedUrl;
|
|
54
57
|
const owner = protocol === 'file' ? _.last(parsedUrl.owner.split('/')) : parsedUrl.owner; // Fix owner for file protocol
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "release-it",
|
|
3
|
-
"version": "15.
|
|
3
|
+
"version": "15.4.1",
|
|
4
4
|
"description": "Generic CLI tool to automate versioning and package publishing related tasks.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"build",
|
|
@@ -60,21 +60,21 @@
|
|
|
60
60
|
"license": "MIT",
|
|
61
61
|
"dependencies": {
|
|
62
62
|
"@iarna/toml": "2.2.5",
|
|
63
|
-
"@octokit/rest": "19.0.
|
|
63
|
+
"@octokit/rest": "19.0.4",
|
|
64
64
|
"async-retry": "1.3.3",
|
|
65
65
|
"chalk": "5.0.1",
|
|
66
66
|
"cosmiconfig": "7.0.1",
|
|
67
67
|
"execa": "6.1.0",
|
|
68
68
|
"form-data": "4.0.0",
|
|
69
|
-
"git-url-parse": "
|
|
69
|
+
"git-url-parse": "13.0.0",
|
|
70
70
|
"globby": "13.1.2",
|
|
71
|
-
"got": "12.
|
|
72
|
-
"inquirer": "9.0
|
|
71
|
+
"got": "12.3.1",
|
|
72
|
+
"inquirer": "9.1.0",
|
|
73
73
|
"is-ci": "3.0.1",
|
|
74
74
|
"lodash": "4.17.21",
|
|
75
75
|
"mime-types": "2.1.35",
|
|
76
76
|
"new-github-release-url": "2.0.0",
|
|
77
|
-
"node-fetch": "3.2.
|
|
77
|
+
"node-fetch": "3.2.10",
|
|
78
78
|
"open": "8.4.0",
|
|
79
79
|
"ora": "6.1.2",
|
|
80
80
|
"os-name": "5.0.1",
|
|
@@ -85,17 +85,17 @@
|
|
|
85
85
|
"update-notifier": "6.0.2",
|
|
86
86
|
"url-join": "5.0.0",
|
|
87
87
|
"wildcard-match": "5.1.2",
|
|
88
|
-
"yargs-parser": "21.
|
|
88
|
+
"yargs-parser": "21.1.1"
|
|
89
89
|
},
|
|
90
90
|
"devDependencies": {
|
|
91
|
-
"@octokit/request-error": "3.0.
|
|
92
|
-
"ava": "4.3.
|
|
93
|
-
"eslint": "8.
|
|
91
|
+
"@octokit/request-error": "3.0.1",
|
|
92
|
+
"ava": "4.3.3",
|
|
93
|
+
"eslint": "8.23.0",
|
|
94
94
|
"eslint-config-prettier": "8.5.0",
|
|
95
95
|
"eslint-plugin-ava": "13.2.0",
|
|
96
96
|
"eslint-plugin-import": "2.26.0",
|
|
97
97
|
"eslint-plugin-prettier": "4.2.1",
|
|
98
|
-
"mock-fs": "5.1.
|
|
98
|
+
"mock-fs": "5.1.4",
|
|
99
99
|
"mock-stdio": "1.0.3",
|
|
100
100
|
"nock": "13.2.9",
|
|
101
101
|
"nyc": "15.1.0",
|
package/test/git.js
CHANGED
|
@@ -274,7 +274,7 @@ test.serial('should reset files', async t => {
|
|
|
274
274
|
|
|
275
275
|
test.serial('should roll back when cancelled', async t => {
|
|
276
276
|
sh.exec('git init');
|
|
277
|
-
sh.exec(`git remote add origin foo`);
|
|
277
|
+
sh.exec(`git remote add origin file://foo`);
|
|
278
278
|
const version = '1.2.3';
|
|
279
279
|
gitAdd(`{"version":"${version}"}`, 'package.json', 'Add package.json');
|
|
280
280
|
const options = { git: { requireCleanWorkingDir: true, commit: true, tag: true, tagName: 'v${version}' } };
|
|
@@ -294,8 +294,8 @@ test.serial('should roll back when cancelled', async t => {
|
|
|
294
294
|
await gitClient.tag();
|
|
295
295
|
await gitClient.rollbackOnce();
|
|
296
296
|
|
|
297
|
-
t.is(exec.args[
|
|
298
|
-
t.is(exec.args[
|
|
297
|
+
t.is(exec.args[11][0], 'git tag --delete v1.2.4');
|
|
298
|
+
t.is(exec.args[12][0], 'git reset --hard HEAD~1');
|
|
299
299
|
});
|
|
300
300
|
|
|
301
301
|
test.serial('should not touch existing history when rolling back', async t => {
|
package/test/github.js
CHANGED
|
@@ -357,7 +357,7 @@ test('should not call octokit client in dry run', async t => {
|
|
|
357
357
|
await runTasks(github);
|
|
358
358
|
|
|
359
359
|
t.is(spy.get.callCount, 0);
|
|
360
|
-
t.is(github.log.exec.args[
|
|
360
|
+
t.is(github.log.exec.args[1][0], 'octokit repos.createRelease "R 1.0.1" (v1.0.1)');
|
|
361
361
|
t.is(github.log.exec.lastCall.args[0], 'octokit repos.uploadReleaseAssets');
|
|
362
362
|
const { isReleased, releaseUrl } = github.getContext();
|
|
363
363
|
t.true(isReleased);
|
package/test/gitlab.js
CHANGED
|
@@ -231,8 +231,8 @@ test('should not make requests in dry run', async t => {
|
|
|
231
231
|
|
|
232
232
|
const { isReleased, releaseUrl } = gitlab.getContext();
|
|
233
233
|
t.is(spy.get.callCount, 0);
|
|
234
|
-
t.is(gitlab.log.exec.args[
|
|
235
|
-
t.is(gitlab.log.exec.args[
|
|
234
|
+
t.is(gitlab.log.exec.args[2][0], 'gitlab releases#uploadAssets');
|
|
235
|
+
t.is(gitlab.log.exec.args[3][0], 'gitlab releases#createRelease "R" (1.0.1)');
|
|
236
236
|
t.true(isReleased);
|
|
237
237
|
t.is(releaseUrl, `${pushRepo}/-/releases`);
|
|
238
238
|
spy.get.restore();
|
package/test/tasks.js
CHANGED
|
@@ -186,6 +186,49 @@ test.serial('should release all the things (basic)', async t => {
|
|
|
186
186
|
exec.restore();
|
|
187
187
|
});
|
|
188
188
|
|
|
189
|
+
test.serial('should release with correct tag name', async t => {
|
|
190
|
+
const { bare, target } = t.context;
|
|
191
|
+
const project = path.basename(bare);
|
|
192
|
+
const pkgName = path.basename(target);
|
|
193
|
+
const owner = path.basename(path.dirname(bare));
|
|
194
|
+
const { stdout } = sh.exec('git rev-parse --abbrev-ref HEAD');
|
|
195
|
+
const branchName = stdout.trim();
|
|
196
|
+
gitAdd(`{"name":"${pkgName}","version":"1.0.0"}`, 'package.json', 'Add package.json');
|
|
197
|
+
sh.exec(`git tag ${pkgName}-${branchName}-1.0.0`);
|
|
198
|
+
const sha = gitAdd('line', 'file', 'More file');
|
|
199
|
+
|
|
200
|
+
interceptGitHubCreate({
|
|
201
|
+
owner,
|
|
202
|
+
project,
|
|
203
|
+
body: {
|
|
204
|
+
tag_name: `${pkgName}-${branchName}-1.0.1`,
|
|
205
|
+
name: 'Release 1.0.1',
|
|
206
|
+
body: `* More file (${sha})`,
|
|
207
|
+
prerelease: false
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
const container = getContainer({
|
|
212
|
+
git: { tagName: '${npm.name}-${branchName}-${version}' },
|
|
213
|
+
github: { release: true, skipChecks: true, pushRepo: `https://github.com/${owner}/${project}` }
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
const exec = sinon.spy(container.shell, 'exec');
|
|
217
|
+
|
|
218
|
+
await runTasks({}, container);
|
|
219
|
+
|
|
220
|
+
const gitArgs = getArgs(container.shell.exec.args, 'git');
|
|
221
|
+
|
|
222
|
+
t.true(gitArgs.includes(`git tag --annotate --message Release 1.0.1 ${pkgName}-${branchName}-1.0.1`));
|
|
223
|
+
t.true(
|
|
224
|
+
log.log.secondCall.args[0].endsWith(
|
|
225
|
+
`https://github.com/${owner}/${project}/releases/tag/${pkgName}-${branchName}-1.0.1`
|
|
226
|
+
)
|
|
227
|
+
);
|
|
228
|
+
|
|
229
|
+
exec.restore();
|
|
230
|
+
});
|
|
231
|
+
|
|
189
232
|
test.serial('should release all the things (pre-release, github, gitlab)', async t => {
|
|
190
233
|
const { bare, target } = t.context;
|
|
191
234
|
const project = path.basename(bare);
|
package/test/util/helpers.js
CHANGED
|
@@ -19,6 +19,9 @@ const gitAdd = (content, file, message) => {
|
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
const getArgs = (args, prefix) =>
|
|
22
|
-
args
|
|
22
|
+
args
|
|
23
|
+
.map(args => (typeof args[0] !== 'string' ? args[0].join(' ') : args[0]))
|
|
24
|
+
.filter(cmd => cmd.startsWith(prefix))
|
|
25
|
+
.map(cmd => cmd.trim());
|
|
23
26
|
|
|
24
27
|
export { mkTmpDir, readFile, gitAdd, getArgs };
|
package/test/utils.js
CHANGED
|
@@ -47,12 +47,39 @@ test('parseGitUrl', t => {
|
|
|
47
47
|
repository: 'org/sub-group/repo-in-sub-group'
|
|
48
48
|
});
|
|
49
49
|
|
|
50
|
+
t.deepEqual(parseGitUrl('git@github.com:org/example.com.git'), {
|
|
51
|
+
host: 'github.com',
|
|
52
|
+
owner: 'org',
|
|
53
|
+
project: 'example.com',
|
|
54
|
+
protocol: 'ssh',
|
|
55
|
+
remote: 'git@github.com:org/example.com.git',
|
|
56
|
+
repository: 'org/example.com'
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
t.deepEqual(parseGitUrl('file://Users/john/doe/owner/project'), {
|
|
60
|
+
host: 'users',
|
|
61
|
+
owner: 'owner',
|
|
62
|
+
project: 'project',
|
|
63
|
+
protocol: 'file',
|
|
64
|
+
remote: 'file://users/john/doe/owner/project',
|
|
65
|
+
repository: 'owner/project'
|
|
66
|
+
});
|
|
67
|
+
|
|
50
68
|
t.deepEqual(parseGitUrl('/Users/john/doe/owner/project'), {
|
|
51
|
-
host: '',
|
|
69
|
+
host: 'users',
|
|
70
|
+
owner: 'owner',
|
|
71
|
+
project: 'project',
|
|
72
|
+
protocol: 'file',
|
|
73
|
+
remote: 'file://users/john/doe/owner/project',
|
|
74
|
+
repository: 'owner/project'
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
t.deepEqual(parseGitUrl('C:\\\\Users\\john\\doe\\owner\\project'), {
|
|
78
|
+
host: 'users',
|
|
52
79
|
owner: 'owner',
|
|
53
80
|
project: 'project',
|
|
54
81
|
protocol: 'file',
|
|
55
|
-
remote: '/
|
|
82
|
+
remote: 'file://users/john/doe/owner/project',
|
|
56
83
|
repository: 'owner/project'
|
|
57
84
|
});
|
|
58
85
|
});
|