release-it 18.1.2 → 19.0.0-next.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/lib/plugin/git/Git.js +1 -2
- package/lib/plugin/github/GitHub.js +3 -3
- package/lib/plugin/gitlab/GitLab.js +3 -3
- package/lib/plugin/npm/npm.js +1 -3
- package/lib/shell.js +5 -6
- package/lib/util.js +41 -3
- package/package.json +14 -15
- package/test/git.init.js +56 -53
- package/test/git.js +106 -80
- package/test/npm.js +1 -0
- package/test/plugins.js +44 -39
- package/test/shell.js +2 -3
- package/test/tasks.interactive.js +10 -8
- package/test/tasks.js +39 -31
- package/test/util/helpers.js +10 -8
- package/test/util/index.js +1 -0
- package/test/util/setup.js +0 -2
- package/test/util/sh.js +18 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
+
import { renameSync } from 'node:fs';
|
|
3
|
+
import childProcess from 'node:child_process';
|
|
2
4
|
import test from 'ava';
|
|
3
|
-
import sh from 'shelljs';
|
|
4
5
|
import _ from 'lodash';
|
|
5
6
|
import sinon from 'sinon';
|
|
6
7
|
import Log from '../lib/log.js';
|
|
@@ -9,6 +10,7 @@ import Prompt from '../lib/prompt.js';
|
|
|
9
10
|
import Config from '../lib/config.js';
|
|
10
11
|
import runTasks from '../lib/index.js';
|
|
11
12
|
import Git from '../lib/plugin/git/Git.js';
|
|
13
|
+
import { execOpts } from '../lib/util.js';
|
|
12
14
|
import { mkTmpDir, gitAdd } from './util/helpers.js';
|
|
13
15
|
import ShellStub from './stub/shell.js';
|
|
14
16
|
import { interceptPublish as interceptGitLabPublish } from './stub/gitlab.js';
|
|
@@ -68,10 +70,10 @@ test.before(t => {
|
|
|
68
70
|
test.serial.beforeEach(t => {
|
|
69
71
|
const bare = mkTmpDir();
|
|
70
72
|
const target = mkTmpDir();
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
process.chdir(bare);
|
|
74
|
+
childProcess.execSync(`git init --bare .`, execOpts);
|
|
75
|
+
childProcess.execSync(`git clone ${bare} ${target}`, execOpts);
|
|
76
|
+
process.chdir(target);
|
|
75
77
|
gitAdd('line', 'file', 'Add file');
|
|
76
78
|
t.context = { bare, target };
|
|
77
79
|
});
|
|
@@ -81,7 +83,7 @@ test.serial.afterEach(() => {
|
|
|
81
83
|
});
|
|
82
84
|
|
|
83
85
|
test.serial('should run tasks without throwing errors', async t => {
|
|
84
|
-
|
|
86
|
+
renameSync('.git', 'foo');
|
|
85
87
|
const { name, latestVersion, version } = await runTasks({}, getContainer());
|
|
86
88
|
t.is(version, '0.0.1');
|
|
87
89
|
t.true(log.obtrusive.firstCall.args[0].includes(`release ${name} (currently at ${latestVersion})`));
|
|
@@ -118,7 +120,7 @@ test.serial('should not run hooks for cancelled release-cycle methods', async t
|
|
|
118
120
|
const { target } = t.context;
|
|
119
121
|
const pkgName = path.basename(target);
|
|
120
122
|
gitAdd(`{"name":"${pkgName}","version":"1.0.0"}`, 'package.json', 'Add package.json');
|
|
121
|
-
|
|
123
|
+
childProcess.execSync('git tag 1.0.0', execOpts);
|
|
122
124
|
|
|
123
125
|
const hooks = getHooks(['version', 'git', 'github', 'gitlab', 'npm']);
|
|
124
126
|
const inquirer = { prompt: sandbox.stub().callsFake(([options]) => ({ [options.name]: false })) };
|
|
@@ -159,7 +161,7 @@ test.serial('should run "after:*:release" plugin hooks', async t => {
|
|
|
159
161
|
const pkgName = path.basename(target);
|
|
160
162
|
const owner = path.basename(path.dirname(bare));
|
|
161
163
|
gitAdd(`{"name":"${pkgName}","version":"1.0.0"}`, 'package.json', 'Add package.json');
|
|
162
|
-
|
|
164
|
+
childProcess.execSync('git tag 1.0.0', execOpts);
|
|
163
165
|
const sha = gitAdd('line', 'file', 'More file');
|
|
164
166
|
|
|
165
167
|
const git = factory(Git);
|
package/test/tasks.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
+
import childProcess from 'node:child_process';
|
|
3
|
+
import { appendFileSync, mkdirSync, renameSync } from 'node:fs';
|
|
2
4
|
import test from 'ava';
|
|
3
5
|
import semver from 'semver';
|
|
4
|
-
import sh from 'shelljs';
|
|
5
6
|
import _ from 'lodash';
|
|
6
7
|
import sinon from 'sinon';
|
|
7
8
|
import Log from '../lib/log.js';
|
|
@@ -9,6 +10,7 @@ import Spinner from '../lib/spinner.js';
|
|
|
9
10
|
import Config from '../lib/config.js';
|
|
10
11
|
import runTasks from '../lib/index.js';
|
|
11
12
|
import Git from '../lib/plugin/git/Git.js';
|
|
13
|
+
import { execOpts } from '../lib/util.js';
|
|
12
14
|
import { mkTmpDir, gitAdd, getArgs } from './util/helpers.js';
|
|
13
15
|
import ShellStub from './stub/shell.js';
|
|
14
16
|
import {
|
|
@@ -60,10 +62,10 @@ test.before(t => {
|
|
|
60
62
|
test.serial.beforeEach(t => {
|
|
61
63
|
const bare = mkTmpDir();
|
|
62
64
|
const target = mkTmpDir();
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
process.chdir(bare);
|
|
66
|
+
childProcess.execSync(`git init --bare .`, execOpts);
|
|
67
|
+
childProcess.execSync(`git clone ${bare} ${target}`, execOpts);
|
|
68
|
+
process.chdir(target);
|
|
67
69
|
gitAdd('line', 'file', 'Add file');
|
|
68
70
|
t.context = { bare, target };
|
|
69
71
|
});
|
|
@@ -73,28 +75,30 @@ test.serial.afterEach(() => {
|
|
|
73
75
|
});
|
|
74
76
|
|
|
75
77
|
test.serial('should run tasks without throwing errors', async t => {
|
|
76
|
-
|
|
78
|
+
renameSync('.git', 'foo');
|
|
77
79
|
const { name, latestVersion, version } = await runTasks({}, getContainer());
|
|
78
80
|
t.true(log.obtrusive.firstCall.args[0].includes(`release ${name} (${latestVersion}...${version})`));
|
|
79
81
|
t.regex(log.log.lastCall.args[0], /Done \(in [0-9]+s\.\)/);
|
|
80
82
|
});
|
|
81
83
|
|
|
82
84
|
test.serial('should run tasks without package.json', async t => {
|
|
83
|
-
|
|
85
|
+
childProcess.execSync('git tag 1.0.0', execOpts);
|
|
84
86
|
gitAdd('line', 'file', 'Add file');
|
|
85
87
|
const { name } = await runTasks({}, getContainer({ increment: 'major', git: { commit: false } }));
|
|
86
88
|
t.true(log.obtrusive.firstCall.args[0].includes(`release ${name} (1.0.0...2.0.0)`));
|
|
87
89
|
t.regex(log.log.lastCall.args[0], /Done \(in [0-9]+s\.\)/);
|
|
88
90
|
t.is(log.warn.callCount, 0);
|
|
89
91
|
{
|
|
90
|
-
const
|
|
92
|
+
const stdout = childProcess.execSync('git describe --tags --match=* --abbrev=0', {
|
|
93
|
+
encoding: 'utf-8'
|
|
94
|
+
});
|
|
91
95
|
t.is(stdout.trim(), '2.0.0');
|
|
92
96
|
}
|
|
93
97
|
});
|
|
94
98
|
|
|
95
99
|
test.serial('should disable plugins', async t => {
|
|
96
100
|
gitAdd('{"name":"my-package","version":"1.2.3"}', 'package.json', 'Add package.json');
|
|
97
|
-
|
|
101
|
+
childProcess.execSync('git tag 1.2.3', execOpts);
|
|
98
102
|
gitAdd('line', 'file', 'Add file');
|
|
99
103
|
const container = getContainer({ increment: 'minor', git: false, npm: false });
|
|
100
104
|
const { latestVersion, version } = await runTasks({}, container);
|
|
@@ -105,12 +109,12 @@ test.serial('should disable plugins', async t => {
|
|
|
105
109
|
|
|
106
110
|
test.serial('should run tasks with minimal config and without any warnings/errors', async t => {
|
|
107
111
|
gitAdd('{"name":"my-package","version":"1.2.3"}', 'package.json', 'Add package.json');
|
|
108
|
-
|
|
112
|
+
childProcess.execSync('git tag 1.2.3', execOpts);
|
|
109
113
|
gitAdd('line', 'file', 'More file');
|
|
110
114
|
await runTasks({}, getContainer({ increment: 'patch' }));
|
|
111
115
|
t.true(log.obtrusive.firstCall.args[0].includes('release my-package (1.2.3...1.2.4)'));
|
|
112
116
|
t.regex(log.log.lastCall.args[0], /Done \(in [0-9]+s\.\)/);
|
|
113
|
-
const
|
|
117
|
+
const stdout = childProcess.execSync('git describe --tags --match=* --abbrev=0', { encoding: 'utf-8' });
|
|
114
118
|
t.is(stdout.trim(), '1.2.4');
|
|
115
119
|
});
|
|
116
120
|
|
|
@@ -119,22 +123,22 @@ test.serial('should use pkg.version', async t => {
|
|
|
119
123
|
await runTasks({}, getContainer({ increment: 'minor' }));
|
|
120
124
|
t.true(log.obtrusive.firstCall.args[0].includes('release my-package (1.2.3...1.3.0)'));
|
|
121
125
|
t.regex(log.log.lastCall.args[0], /Done \(in [0-9]+s\.\)/);
|
|
122
|
-
const
|
|
126
|
+
const stdout = childProcess.execSync('git describe --tags --match=* --abbrev=0', { encoding: 'utf-8' });
|
|
123
127
|
t.is(stdout.trim(), '1.3.0');
|
|
124
128
|
});
|
|
125
129
|
|
|
126
130
|
test.serial('should use pkg.version (in sub dir) w/o tagging repo', async t => {
|
|
127
131
|
gitAdd('{"name":"root-package","version":"1.0.0"}', 'package.json', 'Add package.json');
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
132
|
+
childProcess.execSync('git tag 1.0.0', execOpts);
|
|
133
|
+
mkdirSync('my-package');
|
|
134
|
+
process.chdir('my-package');
|
|
131
135
|
gitAdd('{"name":"my-package","version":"1.2.3"}', 'package.json', 'Add package.json');
|
|
132
136
|
const container = getContainer({ increment: 'minor', git: { tag: false } });
|
|
133
137
|
const exec = sinon.spy(container.shell, 'exec');
|
|
134
138
|
await runTasks({}, container);
|
|
135
139
|
t.true(log.obtrusive.firstCall.args[0].endsWith('release my-package (1.2.3...1.3.0)'));
|
|
136
140
|
t.regex(log.log.lastCall.args[0], /Done \(in [0-9]+s\.\)/);
|
|
137
|
-
const
|
|
141
|
+
const stdout = childProcess.execSync('git describe --tags --match=* --abbrev=0', { encoding: 'utf-8' });
|
|
138
142
|
t.is(stdout.trim(), '1.0.0');
|
|
139
143
|
const npmArgs = getArgs(exec.args, 'npm');
|
|
140
144
|
t.is(npmArgs[5], 'npm version 1.3.0 --no-git-tag-version');
|
|
@@ -143,12 +147,12 @@ test.serial('should use pkg.version (in sub dir) w/o tagging repo', async t => {
|
|
|
143
147
|
|
|
144
148
|
test.serial('should ignore version in pkg.version and use git tag instead', async t => {
|
|
145
149
|
gitAdd('{"name":"my-package","version":"0.0.0"}', 'package.json', 'Add package.json');
|
|
146
|
-
|
|
150
|
+
childProcess.execSync('git tag 1.1.1', execOpts);
|
|
147
151
|
gitAdd('line', 'file', 'More file');
|
|
148
152
|
await runTasks({}, getContainer({ increment: 'minor', npm: { ignoreVersion: true } }));
|
|
149
153
|
t.true(log.obtrusive.firstCall.args[0].includes('release my-package (1.1.1...1.2.0)'));
|
|
150
154
|
t.regex(log.log.lastCall.args[0], /Done \(in [0-9]+s\.\)/);
|
|
151
|
-
const
|
|
155
|
+
const stdout = childProcess.execSync('git describe --tags --match=* --abbrev=0', { encoding: 'utf-8' });
|
|
152
156
|
t.is(stdout.trim(), '1.2.0');
|
|
153
157
|
});
|
|
154
158
|
|
|
@@ -158,7 +162,7 @@ test.serial('should release all the things (basic)', async t => {
|
|
|
158
162
|
const pkgName = path.basename(target);
|
|
159
163
|
const owner = path.basename(path.dirname(bare));
|
|
160
164
|
gitAdd(`{"name":"${pkgName}","version":"1.0.0"}`, 'package.json', 'Add package.json');
|
|
161
|
-
|
|
165
|
+
childProcess.execSync('git tag 1.0.0', execOpts);
|
|
162
166
|
const sha = gitAdd('line', 'file', 'More file');
|
|
163
167
|
|
|
164
168
|
interceptGitHubAuthentication();
|
|
@@ -201,10 +205,10 @@ test.serial('should release with correct tag name', async t => {
|
|
|
201
205
|
const project = path.basename(bare);
|
|
202
206
|
const pkgName = path.basename(target);
|
|
203
207
|
const owner = path.basename(path.dirname(bare));
|
|
204
|
-
const
|
|
208
|
+
const stdout = childProcess.execSync('git rev-parse --abbrev-ref HEAD', { encoding: 'utf-8' });
|
|
205
209
|
const branchName = stdout.trim();
|
|
206
210
|
gitAdd(`{"name":"${pkgName}","version":"1.0.0"}`, 'package.json', 'Add package.json');
|
|
207
|
-
|
|
211
|
+
childProcess.execSync(`git tag ${pkgName}-${branchName}-1.0.0`, execOpts);
|
|
208
212
|
const sha = gitAdd('line', 'file', 'More file');
|
|
209
213
|
|
|
210
214
|
interceptGitHubCreate({
|
|
@@ -246,9 +250,9 @@ test.serial('should release all the things (pre-release, github, gitlab)', async
|
|
|
246
250
|
const owner = path.basename(path.dirname(bare));
|
|
247
251
|
const url = `https://gitlab.com/${owner}/${project}`;
|
|
248
252
|
gitAdd(`{"name":"${pkgName}","version":"1.0.0"}`, 'package.json', 'Add package.json');
|
|
249
|
-
|
|
253
|
+
childProcess.execSync('git tag v1.0.0', execOpts);
|
|
250
254
|
const sha = gitAdd('line', 'file', 'More file');
|
|
251
|
-
|
|
255
|
+
childProcess.execSync('git push --follow-tags', execOpts);
|
|
252
256
|
const git = factory(Git);
|
|
253
257
|
const ref = (await git.getBranchName()) ?? 'HEAD';
|
|
254
258
|
|
|
@@ -327,13 +331,17 @@ test.serial('should release all the things (pre-release, github, gitlab)', async
|
|
|
327
331
|
'npm publish . --tag alpha'
|
|
328
332
|
]);
|
|
329
333
|
|
|
330
|
-
const
|
|
334
|
+
const commitMessage = childProcess.execSync('git log --oneline --format=%B -n 1 HEAD', {
|
|
335
|
+
encoding: 'utf-8'
|
|
336
|
+
});
|
|
331
337
|
t.is(commitMessage.trim(), `Release 1.1.0-alpha.0 for ${pkgName} (from 1.0.0)`);
|
|
332
338
|
|
|
333
|
-
const
|
|
339
|
+
const tagName = childProcess.execSync('git describe --tags --match=* --abbrev=0', { encoding: 'utf-8' });
|
|
334
340
|
t.is(tagName.trim(), 'v1.1.0-alpha.0');
|
|
335
341
|
|
|
336
|
-
const
|
|
342
|
+
const tagAnnotation = childProcess.execSync('git for-each-ref refs/tags/v1.1.0-alpha.0 --format="%(contents)"', {
|
|
343
|
+
encoding: 'utf-8'
|
|
344
|
+
});
|
|
337
345
|
t.is(tagAnnotation.trim(), `${owner} ${owner}/${project} ${project}`);
|
|
338
346
|
|
|
339
347
|
t.true(log.obtrusive.firstCall.args[0].endsWith(`release ${pkgName} (1.0.0...1.1.0-alpha.0)`));
|
|
@@ -349,7 +357,7 @@ test.serial('should publish pre-release without pre-id with different npm.tag',
|
|
|
349
357
|
const { target } = t.context;
|
|
350
358
|
const pkgName = path.basename(target);
|
|
351
359
|
gitAdd(`{"name":"${pkgName}","version":"1.0.0"}`, 'package.json', 'Add package.json');
|
|
352
|
-
|
|
360
|
+
childProcess.execSync('git tag v1.0.0', execOpts);
|
|
353
361
|
|
|
354
362
|
const container = getContainer({ increment: 'major', preRelease: true, npm: { name: pkgName, tag: 'next' } });
|
|
355
363
|
const exec = sinon.spy(container.shell, 'exec');
|
|
@@ -367,7 +375,7 @@ test.serial('should publish pre-release without pre-id with different npm.tag',
|
|
|
367
375
|
'npm publish . --tag next'
|
|
368
376
|
]);
|
|
369
377
|
|
|
370
|
-
const
|
|
378
|
+
const stdout = childProcess.execSync('git describe --tags --match=* --abbrev=0', { encoding: 'utf-8' });
|
|
371
379
|
t.is(stdout.trim(), 'v2.0.0-0');
|
|
372
380
|
t.true(log.obtrusive.firstCall.args[0].endsWith(`release ${pkgName} (1.0.0...2.0.0-0)`));
|
|
373
381
|
t.true(log.log.firstCall.args[0].endsWith(`https://www.npmjs.com/package/${pkgName}`));
|
|
@@ -459,7 +467,7 @@ test.serial('should use custom changelog command with context', async t => {
|
|
|
459
467
|
const { bare } = t.context;
|
|
460
468
|
const project = path.basename(bare);
|
|
461
469
|
const owner = path.basename(path.dirname(bare));
|
|
462
|
-
|
|
470
|
+
childProcess.execSync('git tag v1.0.0', execOpts);
|
|
463
471
|
gitAdd('line', 'file', 'More file');
|
|
464
472
|
|
|
465
473
|
interceptGitHubAuthentication();
|
|
@@ -499,10 +507,10 @@ test.serial('should use custom changelog command with context', async t => {
|
|
|
499
507
|
{
|
|
500
508
|
test.serial('should run all hooks', async t => {
|
|
501
509
|
gitAdd(`{"name":"hooked","version":"1.0.0","type":"module"}`, 'package.json', 'Add package.json');
|
|
502
|
-
|
|
510
|
+
childProcess.execSync(`npm install ${rootDir}`, execOpts);
|
|
503
511
|
const plugin = "import { Plugin } from 'release-it'; class MyPlugin extends Plugin {}; export default MyPlugin;";
|
|
504
|
-
sh.ShellString(plugin).toEnd('my-plugin.js');
|
|
505
512
|
|
|
513
|
+
appendFileSync('my-plugin.js', plugin);
|
|
506
514
|
const hooks = {};
|
|
507
515
|
['before', 'after'].forEach(prefix => {
|
|
508
516
|
['version', 'git', 'npm', 'my-plugin'].forEach(ns => {
|
package/test/util/helpers.js
CHANGED
|
@@ -1,24 +1,26 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { appendFileSync, mkdirSync, mkdtempSync, promises } from 'node:fs';
|
|
2
2
|
import os from 'node:os';
|
|
3
3
|
import path from 'node:path';
|
|
4
|
-
import
|
|
4
|
+
import childProcess from 'node:child_process';
|
|
5
|
+
import { execOpts } from '../../lib/util.js';
|
|
5
6
|
|
|
6
7
|
const mkTmpDir = () => {
|
|
7
|
-
const dir =
|
|
8
|
+
const dir = mkdtempSync(path.join(os.tmpdir(), 'release-it-'));
|
|
8
9
|
return dir;
|
|
9
10
|
};
|
|
10
11
|
|
|
11
|
-
const readFile = file =>
|
|
12
|
+
const readFile = file => promises.readFile(path.resolve(file), 'utf8');
|
|
12
13
|
|
|
13
14
|
const gitAdd = (content, filePath, message) => {
|
|
14
15
|
const pathSegments = filePath.split('/').filter(Boolean);
|
|
15
16
|
pathSegments.pop();
|
|
16
17
|
if (pathSegments.length) {
|
|
17
|
-
|
|
18
|
+
mkdirSync(path.resolve(pathSegments.join('/')), { mode: parseInt('0777', 8), recursive: true });
|
|
18
19
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
|
|
21
|
+
appendFileSync(filePath, content);
|
|
22
|
+
childProcess.execSync(`git add ${filePath}`, execOpts);
|
|
23
|
+
const stdout = childProcess.execSync(`git commit -m "${message}"`, { encoding: 'utf-8' });
|
|
22
24
|
const match = stdout.match(/\[.+([a-z0-9]{7})\]/);
|
|
23
25
|
return match ? match[1] : null;
|
|
24
26
|
};
|
package/test/util/index.js
CHANGED
|
@@ -20,6 +20,7 @@ export let factory = (Definition, { namespace, options = {}, container = {} } =
|
|
|
20
20
|
spinner.show.callsFake(({ enabled = true, task }) => (enabled ? task() : () => {}));
|
|
21
21
|
container.spinner = spinner;
|
|
22
22
|
container.shell = container.shell || new ShellStub({ container });
|
|
23
|
+
|
|
23
24
|
container.prompt = container.prompt || new Prompt({ container });
|
|
24
25
|
container.shell.cache = { set: () => {}, has: () => false };
|
|
25
26
|
|
package/test/util/setup.js
CHANGED
package/test/util/sh.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
|
|
3
|
+
const getCommandAndArgs = input => {
|
|
4
|
+
if (typeof input !== 'string' || !input.trim()) {
|
|
5
|
+
throw new Error('Invalid input: expected a non-empty string.');
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const [command, ...args] = input.trim().split(/\s+/);
|
|
9
|
+
|
|
10
|
+
return [command, args];
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const exec = (command, opts = { stdio: 'inherit' }) => {
|
|
14
|
+
const [cmd, args] = getCommandAndArgs(command);
|
|
15
|
+
return spawnSync(cmd, args, opts);
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default { getCommandAndArgs, exec };
|