release-it 18.1.2 → 19.0.0-next.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/lib/config.js +10 -7
- package/lib/index.js +4 -5
- package/lib/log.js +9 -8
- package/lib/plugin/GitBase.js +2 -1
- package/lib/plugin/GitRelease.js +5 -5
- package/lib/plugin/Plugin.js +6 -4
- package/lib/plugin/factory.js +11 -11
- package/lib/plugin/git/Git.js +5 -7
- package/lib/plugin/github/GitHub.js +15 -14
- package/lib/plugin/gitlab/GitLab.js +5 -6
- package/lib/plugin/npm/npm.js +1 -3
- package/lib/shell.js +5 -6
- package/lib/util.js +97 -30
- package/package.json +26 -23
- 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 +13 -12
- package/test/tasks.js +40 -33
- package/test/util/helpers.js +10 -8
- package/test/util/index.js +2 -4
- package/test/util/setup.js +0 -2
- package/test/util/sh.js +18 -0
package/lib/util.js
CHANGED
|
@@ -1,18 +1,57 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
1
|
+
import fs, { close, openSync, statSync, utimesSync, accessSync } from 'node:fs'; // need import fs here due to test stubbing
|
|
2
|
+
import util from 'node:util';
|
|
2
3
|
import { EOL } from 'node:os';
|
|
3
|
-
import _ from 'lodash';
|
|
4
4
|
import gitUrlParse from 'git-url-parse';
|
|
5
5
|
import semver from 'semver';
|
|
6
6
|
import osName from 'os-name';
|
|
7
|
+
import { Eta } from 'eta';
|
|
7
8
|
import Log from './log.js';
|
|
8
9
|
|
|
9
|
-
const
|
|
10
|
+
const debug = util.debug('release-it:shell');
|
|
10
11
|
|
|
11
|
-
const
|
|
12
|
+
const eta = new Eta({
|
|
13
|
+
autoEscape: false,
|
|
14
|
+
useWith: true,
|
|
15
|
+
tags: ['${', '}'],
|
|
16
|
+
parse: { interpolate: '' },
|
|
17
|
+
rmWhitespace: false,
|
|
18
|
+
autoTrim: false
|
|
19
|
+
});
|
|
20
|
+
const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
|
|
21
|
+
const before = (n, func) => {
|
|
22
|
+
var result;
|
|
23
|
+
if (typeof func != 'function') {
|
|
24
|
+
throw new TypeError('Missing argument for `func`');
|
|
25
|
+
}
|
|
26
|
+
n = parseInt(n);
|
|
27
|
+
return function () {
|
|
28
|
+
if (--n > 0) {
|
|
29
|
+
result = func.apply(this, arguments);
|
|
30
|
+
}
|
|
31
|
+
if (n <= 1) {
|
|
32
|
+
func = undefined;
|
|
33
|
+
}
|
|
34
|
+
return result;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
const tryStatFile = filePath => {
|
|
38
|
+
try {
|
|
39
|
+
return statSync(filePath);
|
|
40
|
+
} catch (e) {
|
|
41
|
+
debug(e);
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export const execOpts = {
|
|
47
|
+
stdio: process.env.NODE_DEBUG && process.env.NODE_DEBUG.indexOf('release-it') === 0 ? 'pipe' : []
|
|
48
|
+
};
|
|
12
49
|
|
|
13
|
-
const
|
|
50
|
+
export const readJSON = file => JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
14
51
|
|
|
15
|
-
const
|
|
52
|
+
const pkg = readJSON(new URL('../package.json', import.meta.url));
|
|
53
|
+
|
|
54
|
+
export const getSystemInfo = () => {
|
|
16
55
|
return {
|
|
17
56
|
'release-it': pkg.version,
|
|
18
57
|
node: process.version,
|
|
@@ -20,9 +59,11 @@ const getSystemInfo = () => {
|
|
|
20
59
|
};
|
|
21
60
|
};
|
|
22
61
|
|
|
23
|
-
const format = (template = '', context = {}) => {
|
|
62
|
+
export const format = (template = '', context = {}) => {
|
|
63
|
+
if (!context || context === null || !template || template === null || template.indexOf('${') === -1) return template;
|
|
64
|
+
const log = new Log();
|
|
24
65
|
try {
|
|
25
|
-
return
|
|
66
|
+
return eta.renderString(template, context);
|
|
26
67
|
} catch (error) {
|
|
27
68
|
log.error(`Unable to render template with context:\n${template}\n${JSON.stringify(context)}`);
|
|
28
69
|
log.error(error);
|
|
@@ -30,21 +71,19 @@ const format = (template = '', context = {}) => {
|
|
|
30
71
|
}
|
|
31
72
|
};
|
|
32
73
|
|
|
33
|
-
const truncateLines = (input, maxLines = 10, surplusText = null) => {
|
|
74
|
+
export const truncateLines = (input, maxLines = 10, surplusText = null) => {
|
|
34
75
|
const lines = input.split(EOL);
|
|
35
76
|
const surplus = lines.length - maxLines;
|
|
36
77
|
const output = lines.slice(0, maxLines).join(EOL);
|
|
37
78
|
return surplus > 0 ? (surplusText ? `${output}${surplusText}` : `${output}${EOL}...and ${surplus} more`) : output;
|
|
38
79
|
};
|
|
39
80
|
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
const rejectAfter = (ms, error) =>
|
|
81
|
+
export const rejectAfter = (ms, error) =>
|
|
43
82
|
wait(ms).then(() => {
|
|
44
83
|
throw error;
|
|
45
84
|
});
|
|
46
85
|
|
|
47
|
-
const parseGitUrl = remoteUrl => {
|
|
86
|
+
export const parseGitUrl = remoteUrl => {
|
|
48
87
|
if (!remoteUrl) return { host: null, owner: null, project: null, protocol: null, remote: null, repository: null };
|
|
49
88
|
const normalizedUrl = (remoteUrl || '')
|
|
50
89
|
.replace(/^[A-Z]:\\\\/, 'file://') // Assume file protocol for Windows drive letters
|
|
@@ -52,12 +91,12 @@ const parseGitUrl = remoteUrl => {
|
|
|
52
91
|
.replace(/\\+/g, '/'); // Replace forward with backslashes
|
|
53
92
|
const parsedUrl = gitUrlParse(normalizedUrl);
|
|
54
93
|
const { resource: host, name: project, protocol, href: remote } = parsedUrl;
|
|
55
|
-
const owner = protocol === 'file' ?
|
|
94
|
+
const owner = protocol === 'file' ? parsedUrl.owner.split('/').at(-1) : parsedUrl.owner; // Fix owner for file protocol
|
|
56
95
|
const repository = `${owner}/${project}`;
|
|
57
96
|
return { host, owner, project, protocol, remote, repository };
|
|
58
97
|
};
|
|
59
98
|
|
|
60
|
-
const reduceUntil = async (collection, fn) => {
|
|
99
|
+
export const reduceUntil = async (collection, fn) => {
|
|
61
100
|
let result;
|
|
62
101
|
for (const item of collection) {
|
|
63
102
|
if (result) break;
|
|
@@ -66,16 +105,16 @@ const reduceUntil = async (collection, fn) => {
|
|
|
66
105
|
return result;
|
|
67
106
|
};
|
|
68
107
|
|
|
69
|
-
const hasAccess = path => {
|
|
108
|
+
export const hasAccess = path => {
|
|
70
109
|
try {
|
|
71
|
-
|
|
110
|
+
accessSync(path);
|
|
72
111
|
return true;
|
|
73
112
|
} catch (err) {
|
|
74
113
|
return false;
|
|
75
114
|
}
|
|
76
115
|
};
|
|
77
116
|
|
|
78
|
-
const parseVersion = raw => {
|
|
117
|
+
export const parseVersion = raw => {
|
|
79
118
|
if (raw == null) return { version: raw, isPreRelease: false, preReleaseId: null };
|
|
80
119
|
const version = semver.valid(raw) ? raw : semver.coerce(raw);
|
|
81
120
|
if (!version) return { version: raw, isPreRelease: false, preReleaseId: null };
|
|
@@ -89,22 +128,50 @@ const parseVersion = raw => {
|
|
|
89
128
|
};
|
|
90
129
|
};
|
|
91
130
|
|
|
92
|
-
const e = (message, docs, fail = true) => {
|
|
131
|
+
export const e = (message, docs, fail = true) => {
|
|
93
132
|
const error = new Error(docs ? `${message}${EOL}Documentation: ${docs}${EOL}` : message);
|
|
94
133
|
error.code = fail ? 1 : 0;
|
|
95
134
|
error.cause = fail ? 'ERROR' : 'INFO';
|
|
96
135
|
return error;
|
|
97
136
|
};
|
|
98
137
|
|
|
99
|
-
export {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
138
|
+
export const touch = (path, callback) => {
|
|
139
|
+
const stat = tryStatFile(path);
|
|
140
|
+
if (stat && stat.isDirectory()) {
|
|
141
|
+
// don't error just exit
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const fd = openSync(path, 'a');
|
|
146
|
+
close(fd);
|
|
147
|
+
const now = new Date();
|
|
148
|
+
const mtime = now;
|
|
149
|
+
const atime = now;
|
|
150
|
+
utimesSync(path, atime, mtime);
|
|
151
|
+
if (callback) {
|
|
152
|
+
callback();
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
export const fixArgs = args => (args ? (typeof args === 'string' ? args.split(' ') : args) : []);
|
|
157
|
+
|
|
158
|
+
export const upperFirst = string => {
|
|
159
|
+
return string ? string.charAt(0).toUpperCase() + string.slice(1) : '';
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
export const castArray = arr => {
|
|
163
|
+
return Array.isArray(arr) ? arr : [arr];
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
export const once = fn => {
|
|
167
|
+
return before(2, fn);
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
export const pick = (object, keys) => {
|
|
171
|
+
return keys.reduce((obj, key) => {
|
|
172
|
+
if (object && Object.prototype.hasOwnProperty.call(object, key)) {
|
|
173
|
+
obj[key] = object[key];
|
|
174
|
+
}
|
|
175
|
+
return obj;
|
|
176
|
+
}, {});
|
|
110
177
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "release-it",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "19.0.0-next.1",
|
|
4
4
|
"description": "Generic CLI tool to automate versioning and package publishing-related tasks.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"build",
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"lint": "eslint lib test",
|
|
70
70
|
"format": "prettier --write eslint.config.mjs \"{lib,test}/**/*.js\"",
|
|
71
71
|
"docs": "remark README.md 'docs/**/*.md' '.github/*.md' -o",
|
|
72
|
-
"test": "ava --no-worker-threads && installed-check --ignore ava",
|
|
72
|
+
"test": "ava --no-worker-threads && installed-check --ignore ava --ignore nock",
|
|
73
73
|
"release": "./bin/release-it.js"
|
|
74
74
|
},
|
|
75
75
|
"author": {
|
|
@@ -79,25 +79,28 @@
|
|
|
79
79
|
"license": "MIT",
|
|
80
80
|
"dependencies": {
|
|
81
81
|
"@iarna/toml": "2.2.5",
|
|
82
|
-
"@
|
|
82
|
+
"@nodeutils/defaults-deep": "1.1.0",
|
|
83
|
+
"@octokit/rest": "21.1.1",
|
|
84
|
+
"@phun-ky/typeof": "1.2.3",
|
|
83
85
|
"async-retry": "1.3.3",
|
|
84
86
|
"chalk": "5.4.1",
|
|
85
|
-
"ci-info": "^4.
|
|
87
|
+
"ci-info": "^4.2.0",
|
|
86
88
|
"cosmiconfig": "9.0.0",
|
|
89
|
+
"eta": "3.5.0",
|
|
87
90
|
"execa": "9.5.2",
|
|
88
|
-
"git-url-parse": "16.0.
|
|
89
|
-
"globby": "14.0
|
|
90
|
-
"inquirer": "12.3
|
|
91
|
+
"git-url-parse": "16.0.1",
|
|
92
|
+
"globby": "14.1.0",
|
|
93
|
+
"inquirer": "12.4.3",
|
|
91
94
|
"issue-parser": "7.0.1",
|
|
92
|
-
"lodash": "4.
|
|
95
|
+
"lodash.get": "4.4.2",
|
|
96
|
+
"lodash.merge": "4.6.2",
|
|
93
97
|
"mime-types": "2.1.35",
|
|
94
98
|
"new-github-release-url": "2.0.0",
|
|
95
99
|
"open": "10.1.0",
|
|
96
|
-
"ora": "8.
|
|
100
|
+
"ora": "8.2.0",
|
|
97
101
|
"os-name": "6.0.0",
|
|
98
102
|
"proxy-agent": "6.5.0",
|
|
99
|
-
"semver": "7.
|
|
100
|
-
"shelljs": "0.8.5",
|
|
103
|
+
"semver": "7.7.1",
|
|
101
104
|
"undici": "6.21.1",
|
|
102
105
|
"update-notifier": "7.3.1",
|
|
103
106
|
"url-join": "5.0.0",
|
|
@@ -105,30 +108,30 @@
|
|
|
105
108
|
"yargs-parser": "21.1.1"
|
|
106
109
|
},
|
|
107
110
|
"devDependencies": {
|
|
108
|
-
"@eslint/compat": "1.2.
|
|
109
|
-
"@eslint/eslintrc": "3.
|
|
110
|
-
"@eslint/js": "9.
|
|
111
|
-
"@octokit/request-error": "6.1.
|
|
112
|
-
"@types/node": "20.17.
|
|
111
|
+
"@eslint/compat": "1.2.7",
|
|
112
|
+
"@eslint/eslintrc": "3.3.0",
|
|
113
|
+
"@eslint/js": "9.22.0",
|
|
114
|
+
"@octokit/request-error": "6.1.7",
|
|
115
|
+
"@types/node": "20.17.17",
|
|
113
116
|
"ava": "6.2.0",
|
|
114
|
-
"eslint": "9.
|
|
115
|
-
"eslint-config-prettier": "10.
|
|
117
|
+
"eslint": "9.22.0",
|
|
118
|
+
"eslint-config-prettier": "10.1.1",
|
|
116
119
|
"eslint-plugin-ava": "15.0.1",
|
|
117
120
|
"eslint-plugin-import-x": "4.6.1",
|
|
118
121
|
"eslint-plugin-prettier": "5.2.3",
|
|
119
122
|
"fs-monkey": "1.0.6",
|
|
120
|
-
"globals": "
|
|
123
|
+
"globals": "16.0.0",
|
|
121
124
|
"installed-check": "9.3.0",
|
|
122
|
-
"knip": "5.
|
|
125
|
+
"knip": "5.45.0",
|
|
123
126
|
"memfs": "4.17.0",
|
|
124
127
|
"mock-stdio": "1.0.3",
|
|
125
|
-
"nock": "14.0.
|
|
126
|
-
"prettier": "3.
|
|
128
|
+
"nock": "14.0.1",
|
|
129
|
+
"prettier": "3.5.3",
|
|
127
130
|
"remark-cli": "12.0.1",
|
|
128
131
|
"remark-preset-webpro": "1.1.1",
|
|
129
132
|
"sinon": "19.0.2",
|
|
130
133
|
"strip-ansi": "7.1.0",
|
|
131
|
-
"typescript": "5.
|
|
134
|
+
"typescript": "5.8.2"
|
|
132
135
|
},
|
|
133
136
|
"overrides": {
|
|
134
137
|
"pac-resolver": "7.0.1",
|
package/test/git.init.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import childProcess from 'node:child_process';
|
|
2
|
+
import { mkdirSync } from 'node:fs';
|
|
1
3
|
import test from 'ava';
|
|
2
|
-
import sh from 'shelljs';
|
|
3
4
|
import Shell from '../lib/shell.js';
|
|
4
5
|
import Git from '../lib/plugin/git/Git.js';
|
|
5
|
-
import { readJSON } from '../lib/util.js';
|
|
6
|
+
import { execOpts, readJSON } from '../lib/util.js';
|
|
7
|
+
import sh from './util/sh.js';
|
|
6
8
|
import { factory } from './util/index.js';
|
|
7
9
|
import { mkTmpDir, gitAdd } from './util/helpers.js';
|
|
8
10
|
|
|
@@ -11,10 +13,10 @@ const { git } = readJSON(new URL('../config/release-it.json', import.meta.url));
|
|
|
11
13
|
test.serial.beforeEach(t => {
|
|
12
14
|
const bare = mkTmpDir();
|
|
13
15
|
const target = mkTmpDir();
|
|
14
|
-
|
|
15
|
-
sh.exec(`git init --bare
|
|
16
|
-
sh.exec(`git clone ${bare} ${target}
|
|
17
|
-
|
|
16
|
+
process.chdir(bare);
|
|
17
|
+
sh.exec(`git init --bare .`, execOpts);
|
|
18
|
+
sh.exec(`git clone ${bare} ${target}`, execOpts);
|
|
19
|
+
process.chdir(target);
|
|
18
20
|
gitAdd('line', 'file', 'Add file');
|
|
19
21
|
t.context = { bare, target };
|
|
20
22
|
});
|
|
@@ -22,14 +24,14 @@ test.serial.beforeEach(t => {
|
|
|
22
24
|
test.serial('should throw if on wrong branch', async t => {
|
|
23
25
|
const options = { git: { requireBranch: 'dev' } };
|
|
24
26
|
const gitClient = factory(Git, { options });
|
|
25
|
-
|
|
27
|
+
childProcess.execSync('git remote remove origin', execOpts);
|
|
26
28
|
await t.throwsAsync(gitClient.init(), { message: /^Must be on branch dev/ });
|
|
27
29
|
});
|
|
28
30
|
|
|
29
31
|
test.serial('should throw if on negated branch', async t => {
|
|
30
32
|
const options = { git: { requireBranch: '!main' } };
|
|
31
33
|
const gitClient = factory(Git, { options });
|
|
32
|
-
sh.exec('git checkout -b main');
|
|
34
|
+
sh.exec('git checkout -b main', execOpts);
|
|
33
35
|
await t.throwsAsync(gitClient.init(), { message: /^Must be on branch !main/ });
|
|
34
36
|
});
|
|
35
37
|
|
|
@@ -42,39 +44,39 @@ test.serial('should not throw if required branch matches', async t => {
|
|
|
42
44
|
test.serial('should not throw if one of required branch matches', async t => {
|
|
43
45
|
const options = { git: { requireBranch: ['release/*', 'hotfix/*'] } };
|
|
44
46
|
const gitClient = factory(Git, { options });
|
|
45
|
-
|
|
47
|
+
childProcess.execSync('git checkout -b release/v1', execOpts);
|
|
46
48
|
await t.notThrowsAsync(gitClient.init());
|
|
47
49
|
});
|
|
48
50
|
|
|
49
51
|
test.serial('should throw if there is no remote Git url', async t => {
|
|
50
52
|
const gitClient = factory(Git, { options: { git } });
|
|
51
|
-
|
|
53
|
+
childProcess.execSync('git remote remove origin', execOpts);
|
|
52
54
|
await t.throwsAsync(gitClient.init(), { message: /^Could not get remote Git url/ });
|
|
53
55
|
});
|
|
54
56
|
|
|
55
57
|
test.serial('should throw if working dir is not clean', async t => {
|
|
56
58
|
const gitClient = factory(Git, { options: { git } });
|
|
57
|
-
|
|
59
|
+
childProcess.execSync('rm file', execOpts);
|
|
58
60
|
await t.throwsAsync(gitClient.init(), { message: /^Working dir must be clean/ });
|
|
59
61
|
});
|
|
60
62
|
|
|
61
63
|
test.serial('should throw if no upstream is configured', async t => {
|
|
62
64
|
const gitClient = factory(Git, { options: { git } });
|
|
63
|
-
|
|
65
|
+
childProcess.execSync('git checkout -b foo', execOpts);
|
|
64
66
|
await t.throwsAsync(gitClient.init(), { message: /^No upstream configured for current branch/ });
|
|
65
67
|
});
|
|
66
68
|
|
|
67
69
|
test.serial('should throw if there are no commits', async t => {
|
|
68
70
|
const options = { git: { requireCommits: true } };
|
|
69
71
|
const gitClient = factory(Git, { options });
|
|
70
|
-
|
|
72
|
+
childProcess.execSync('git tag 1.0.0', execOpts);
|
|
71
73
|
await t.throwsAsync(gitClient.init(), { message: /^There are no commits since the latest tag/ });
|
|
72
74
|
});
|
|
73
75
|
|
|
74
76
|
test.serial('should not throw if there are commits', async t => {
|
|
75
77
|
const options = { git: { requireCommits: true } };
|
|
76
78
|
const gitClient = factory(Git, { options });
|
|
77
|
-
|
|
79
|
+
childProcess.execSync('git tag 1.0.0', execOpts);
|
|
78
80
|
gitAdd('line', 'file', 'Add file');
|
|
79
81
|
await t.notThrowsAsync(gitClient.init(), 'There are no commits since the latest tag');
|
|
80
82
|
});
|
|
@@ -82,29 +84,29 @@ test.serial('should not throw if there are commits', async t => {
|
|
|
82
84
|
test.serial('should fail (exit code 1) if there are no commits', async t => {
|
|
83
85
|
const options = { git: { requireCommits: true } };
|
|
84
86
|
const gitClient = factory(Git, { options });
|
|
85
|
-
|
|
87
|
+
childProcess.execSync('git tag 1.0.0', execOpts);
|
|
86
88
|
await t.throwsAsync(gitClient.init(), { code: 1 });
|
|
87
89
|
});
|
|
88
90
|
|
|
89
91
|
test.serial('should not fail (exit code 0) if there are no commits', async t => {
|
|
90
92
|
const options = { git: { requireCommits: true, requireCommitsFail: false } };
|
|
91
93
|
const gitClient = factory(Git, { options });
|
|
92
|
-
|
|
94
|
+
childProcess.execSync('git tag 1.0.0', execOpts);
|
|
93
95
|
await t.throwsAsync(gitClient.init(), { code: 0 });
|
|
94
96
|
});
|
|
95
97
|
|
|
96
98
|
test.serial('should throw if there are no commits in specified path', async t => {
|
|
97
99
|
const options = { git: { requireCommits: true, commitsPath: 'dir' } };
|
|
98
100
|
const gitClient = factory(Git, { options });
|
|
99
|
-
|
|
100
|
-
sh.exec('git tag 1.0.0');
|
|
101
|
+
mkdirSync('dir', { recursive: true });
|
|
102
|
+
sh.exec('git tag 1.0.0', execOpts);
|
|
101
103
|
await t.throwsAsync(gitClient.init(), { message: /^There are no commits since the latest tag/ });
|
|
102
104
|
});
|
|
103
105
|
|
|
104
106
|
test.serial('should not throw if there are commits in specified path', async t => {
|
|
105
107
|
const options = { git: { requireCommits: true, commitsPath: 'dir' } };
|
|
106
108
|
const gitClient = factory(Git, { options });
|
|
107
|
-
sh.exec('git tag 1.0.0');
|
|
109
|
+
sh.exec('git tag 1.0.0', execOpts);
|
|
108
110
|
gitAdd('line', 'dir/file', 'Add file');
|
|
109
111
|
await t.notThrowsAsync(gitClient.init());
|
|
110
112
|
});
|
|
@@ -117,14 +119,14 @@ test.serial('should not throw if there are no tags', async t => {
|
|
|
117
119
|
});
|
|
118
120
|
|
|
119
121
|
test.serial('should not throw if origin remote is renamed', async t => {
|
|
120
|
-
|
|
122
|
+
childProcess.execSync('git remote rename origin upstream', execOpts);
|
|
121
123
|
const gitClient = factory(Git);
|
|
122
124
|
await t.notThrowsAsync(gitClient.init());
|
|
123
125
|
});
|
|
124
126
|
|
|
125
127
|
test.serial('should detect and include version prefix ("v")', async t => {
|
|
126
128
|
const gitClient = factory(Git, { options: { git } });
|
|
127
|
-
|
|
129
|
+
childProcess.execSync('git tag v1.0.0', execOpts);
|
|
128
130
|
await gitClient.init();
|
|
129
131
|
await gitClient.bump('1.0.1');
|
|
130
132
|
t.is(gitClient.config.getContext('tagName'), 'v1.0.1');
|
|
@@ -132,7 +134,7 @@ test.serial('should detect and include version prefix ("v")', async t => {
|
|
|
132
134
|
|
|
133
135
|
test.serial('should detect and exclude version prefix', async t => {
|
|
134
136
|
const gitClient = factory(Git, { options: { git } });
|
|
135
|
-
|
|
137
|
+
childProcess.execSync('git tag 1.0.0', execOpts);
|
|
136
138
|
await gitClient.init();
|
|
137
139
|
await gitClient.bump('1.0.1');
|
|
138
140
|
t.is(gitClient.config.getContext('tagName'), '1.0.1');
|
|
@@ -140,7 +142,7 @@ test.serial('should detect and exclude version prefix', async t => {
|
|
|
140
142
|
|
|
141
143
|
test.serial('should detect and exclude version prefix (configured)', async t => {
|
|
142
144
|
const gitClient = factory(Git, { options: { git: { tagName: 'v${version}' } } });
|
|
143
|
-
|
|
145
|
+
childProcess.execSync('git tag 1.0.0', execOpts);
|
|
144
146
|
await gitClient.init();
|
|
145
147
|
await gitClient.bump('1.0.1');
|
|
146
148
|
t.is(gitClient.config.getContext('tagName'), 'v1.0.1');
|
|
@@ -148,7 +150,7 @@ test.serial('should detect and exclude version prefix (configured)', async t =>
|
|
|
148
150
|
|
|
149
151
|
test.serial('should honor custom tagName configuration', async t => {
|
|
150
152
|
const gitClient = factory(Git, { options: { git: { tagName: 'TAGNAME-${repo.project}-v${version}' } } });
|
|
151
|
-
|
|
153
|
+
childProcess.execSync('git tag 1.0.0', execOpts);
|
|
152
154
|
await gitClient.init();
|
|
153
155
|
await gitClient.bump('1.0.1');
|
|
154
156
|
const { project } = gitClient.getContext('repo');
|
|
@@ -160,12 +162,13 @@ test.serial('should get the latest tag after fetch', async t => {
|
|
|
160
162
|
const gitClient = factory(Git, { container: { shell } });
|
|
161
163
|
const { bare, target } = t.context;
|
|
162
164
|
const other = mkTmpDir();
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
165
|
+
childProcess.execSync('git push', execOpts);
|
|
166
|
+
childProcess.execSync(`git clone ${bare} ${other}`, execOpts);
|
|
167
|
+
|
|
168
|
+
process.chdir(other);
|
|
169
|
+
childProcess.execSync('git tag 1.0.0', execOpts);
|
|
170
|
+
childProcess.execSync('git push --tags', execOpts);
|
|
171
|
+
process.chdir(target);
|
|
169
172
|
await gitClient.init();
|
|
170
173
|
t.is(gitClient.config.getContext('latestTag'), '1.0.0');
|
|
171
174
|
});
|
|
@@ -178,14 +181,14 @@ test.serial('should get the latest custom tag after fetch when tagName is config
|
|
|
178
181
|
});
|
|
179
182
|
const { bare, target } = t.context;
|
|
180
183
|
const other = mkTmpDir();
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
184
|
+
childProcess.execSync('git push', execOpts);
|
|
185
|
+
childProcess.execSync(`git clone ${bare} ${other}`, execOpts);
|
|
186
|
+
process.chdir(other);
|
|
187
|
+
childProcess.execSync('git tag TAGNAME-OTHER-v2.0.0', execOpts);
|
|
188
|
+
childProcess.execSync('git tag TAGNAME-v1.0.0', execOpts);
|
|
189
|
+
childProcess.execSync('git tag TAGNAME-OTHER-v2.0.2', execOpts);
|
|
190
|
+
childProcess.execSync('git push --tags', execOpts);
|
|
191
|
+
process.chdir(target);
|
|
189
192
|
await gitClient.init();
|
|
190
193
|
t.is(gitClient.config.getContext('latestTag'), 'TAGNAME-v1.0.0');
|
|
191
194
|
});
|
|
@@ -196,10 +199,10 @@ test.serial('should get the latest tag based on tagMatch', async t => {
|
|
|
196
199
|
options: { git: { tagMatch: '[0-9][0-9]\\.[0-1][0-9]\\.[0-9]*' } },
|
|
197
200
|
container: { shell }
|
|
198
201
|
});
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
202
|
+
childProcess.execSync('git tag 1.0.0', execOpts);
|
|
203
|
+
childProcess.execSync('git tag 21.04.3', execOpts);
|
|
204
|
+
childProcess.execSync('git tag 1.0.1', execOpts);
|
|
205
|
+
childProcess.execSync('git push --tags', execOpts);
|
|
203
206
|
await gitClient.init();
|
|
204
207
|
t.is(gitClient.config.getContext('latestTag'), '21.04.3');
|
|
205
208
|
});
|
|
@@ -210,20 +213,20 @@ test.serial('should get the latest tag based on tagExclude', async t => {
|
|
|
210
213
|
options: { git: { tagExclude: '*[-]*' } },
|
|
211
214
|
container: { shell }
|
|
212
215
|
});
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
216
|
+
childProcess.execSync('git tag 1.0.0', execOpts);
|
|
217
|
+
childProcess.execSync('git commit --allow-empty -m "commit 1"', execOpts);
|
|
218
|
+
childProcess.execSync('git tag 1.0.1-rc.0', execOpts);
|
|
219
|
+
childProcess.execSync('git tag 1.0.1', execOpts);
|
|
220
|
+
childProcess.execSync('git commit --allow-empty -m "commit 2"', execOpts);
|
|
221
|
+
childProcess.execSync('git tag 1.1.0-rc.0', execOpts);
|
|
222
|
+
childProcess.execSync('git push --tags', execOpts);
|
|
220
223
|
await gitClient.init();
|
|
221
224
|
t.is(gitClient.config.getContext('latestTag'), '1.0.1');
|
|
222
225
|
});
|
|
223
226
|
|
|
224
227
|
test.serial('should generate correct changelog', async t => {
|
|
225
228
|
const gitClient = factory(Git, { options: { git } });
|
|
226
|
-
|
|
229
|
+
childProcess.execSync('git tag 1.0.0', execOpts);
|
|
227
230
|
gitAdd('line', 'file', 'Add file');
|
|
228
231
|
gitAdd('line', 'file', 'Add file');
|
|
229
232
|
await gitClient.init();
|
|
@@ -237,11 +240,11 @@ test.serial('should get the full changelog since latest major tag', async t => {
|
|
|
237
240
|
options: { git: { tagMatch: '[0-9]\\.[0-9]\\.[0-9]', changelog: git.changelog } },
|
|
238
241
|
container: { shell }
|
|
239
242
|
});
|
|
240
|
-
|
|
243
|
+
childProcess.execSync('git tag 1.0.0', execOpts);
|
|
241
244
|
gitAdd('line', 'file', 'Add file');
|
|
242
|
-
|
|
245
|
+
childProcess.execSync('git tag 2.0.0-rc.0', execOpts);
|
|
243
246
|
gitAdd('line', 'file', 'Add file');
|
|
244
|
-
|
|
247
|
+
childProcess.execSync('git tag 2.0.0-rc.1', execOpts);
|
|
245
248
|
gitAdd('line', 'file', 'Add file');
|
|
246
249
|
await gitClient.init();
|
|
247
250
|
t.is(gitClient.config.getContext('latestTag'), '1.0.0');
|