semantic-release-lerna 2.0.0 → 2.2.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/generate-notes.js +3 -3
- package/lib/get-changed-packages.js +5 -7
- package/lib/prepare.js +3 -3
- package/lib/publish.js +1 -1
- package/lib/utils/collect-dependents.js +41 -0
- package/lib/utils/collect-packages.js +35 -0
- package/lib/utils/has-tags.js +22 -0
- package/lib/utils/index.js +3 -0
- package/lib/utils/make-diff-predicate.js +69 -0
- package/lib/verify-git.js +1 -1
- package/package.json +33 -18
package/lib/generate-notes.js
CHANGED
|
@@ -8,8 +8,8 @@ import { readPackageUp } from "read-pkg-up";
|
|
|
8
8
|
import debugFactory from "debug";
|
|
9
9
|
import loadChangelogConfig from "@semantic-release/release-notes-generator/lib/load-changelog-config.js";
|
|
10
10
|
import HOSTS_CONFIG from "@semantic-release/release-notes-generator/lib/hosts-config.js";
|
|
11
|
-
import { makeDiffPredicate } from "@lerna/collect-updates/lib/make-diff-predicate.js";
|
|
12
11
|
import { Project } from "@lerna/project";
|
|
12
|
+
import { makeDiffPredicate } from "./utils/index.js";
|
|
13
13
|
|
|
14
14
|
const debug = debugFactory("semantic-release:release-notes-generator");
|
|
15
15
|
|
|
@@ -87,8 +87,8 @@ export async function generateNotes(pluginConfig, context) {
|
|
|
87
87
|
fillScope({
|
|
88
88
|
...rawCommit,
|
|
89
89
|
...parser(rawCommit.message, { referenceActions, issuePrefixes, ...parserOpts }),
|
|
90
|
-
})
|
|
91
|
-
)
|
|
90
|
+
}),
|
|
91
|
+
),
|
|
92
92
|
);
|
|
93
93
|
const previousTag = lastRelease.gitTag || lastRelease.gitHead;
|
|
94
94
|
const currentTag = nextRelease.gitTag || nextRelease.gitHead;
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { format } from "node:util";
|
|
2
2
|
import { PackageGraph } from "@lerna/package-graph";
|
|
3
3
|
import { Project } from "@lerna/project";
|
|
4
|
-
import
|
|
5
|
-
import { hasTags } from "@lerna/collect-updates/lib/has-tags.js";
|
|
6
|
-
import { collectPackages } from "@lerna/collect-updates/lib/collect-packages.js";
|
|
7
|
-
import { makeDiffPredicate } from "@lerna/collect-updates/lib/make-diff-predicate.js";
|
|
4
|
+
import { execaSync } from "execa";
|
|
8
5
|
import { shouldLatch } from "./should-latch.js";
|
|
6
|
+
import { collectPackages, hasTags, makeDiffPredicate } from "./utils/index.js";
|
|
9
7
|
|
|
10
8
|
function describeRefSync(execOptions) {
|
|
11
9
|
const args = [
|
|
@@ -20,7 +18,7 @@ function describeRefSync(execOptions) {
|
|
|
20
18
|
// Prefer tags originating on upstream branch
|
|
21
19
|
"--first-parent",
|
|
22
20
|
];
|
|
23
|
-
const stdout =
|
|
21
|
+
const { stdout } = execaSync("git", args, execOptions);
|
|
24
22
|
return parse(stdout, execOptions);
|
|
25
23
|
}
|
|
26
24
|
|
|
@@ -101,14 +99,14 @@ export default async function getChangedPackages(latch, context) {
|
|
|
101
99
|
logger.log(
|
|
102
100
|
`%d package${packages.length === 1 ? "" : "s"} found: %s`,
|
|
103
101
|
packages.length,
|
|
104
|
-
format(packages.map((pkg) => pkg.name))
|
|
102
|
+
format(packages.map((pkg) => pkg.name)),
|
|
105
103
|
);
|
|
106
104
|
|
|
107
105
|
const updates = collectUpdates(
|
|
108
106
|
packageGraph.rawPackageList,
|
|
109
107
|
packageGraph,
|
|
110
108
|
{ cwd },
|
|
111
|
-
{ logger, version, latch }
|
|
109
|
+
{ logger, version, latch },
|
|
112
110
|
);
|
|
113
111
|
|
|
114
112
|
return updates.map((node) => packages.find((pkg) => pkg.name === node.name));
|
package/lib/prepare.js
CHANGED
|
@@ -96,7 +96,7 @@ async function updateLockfile(npmrc, pkg, context) {
|
|
|
96
96
|
{
|
|
97
97
|
cwd: pkg.location,
|
|
98
98
|
env,
|
|
99
|
-
}
|
|
99
|
+
},
|
|
100
100
|
);
|
|
101
101
|
versionResult.stdout.pipe(stdout, { end: false });
|
|
102
102
|
versionResult.stderr.pipe(stderr, { end: false });
|
|
@@ -199,11 +199,11 @@ export default async function (npmrc, pluginConfig, context) {
|
|
|
199
199
|
|
|
200
200
|
const s = changed.length > 1 ? "s" : "";
|
|
201
201
|
logger.log(
|
|
202
|
-
`${changed.length} package${s} need version bump: ${format(changed.map((pkg) => pkg.name))}
|
|
202
|
+
`${changed.length} package${s} need version bump: ${format(changed.map((pkg) => pkg.name))}`,
|
|
203
203
|
);
|
|
204
204
|
|
|
205
205
|
const currentVersions = Object.fromEntries(
|
|
206
|
-
await Promise.all(changed.map((pkg) => getCurrentVersion(pkg)))
|
|
206
|
+
await Promise.all(changed.map((pkg) => getCurrentVersion(pkg))),
|
|
207
207
|
);
|
|
208
208
|
|
|
209
209
|
/* Bump version in all changed packages */
|
package/lib/publish.js
CHANGED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build a set of nodes that are dependents of the input set.
|
|
3
|
+
*/
|
|
4
|
+
export function collectDependents(nodes) {
|
|
5
|
+
const collected = new Set();
|
|
6
|
+
|
|
7
|
+
nodes.forEach((currentNode) => {
|
|
8
|
+
if (currentNode.localDependents.size === 0) {
|
|
9
|
+
// no point diving into a non-existent tree
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// breadth-first search
|
|
14
|
+
const queue = [currentNode];
|
|
15
|
+
const seen = new Set();
|
|
16
|
+
|
|
17
|
+
const visit = (dependentNode, dependentName, siblingDependents) => {
|
|
18
|
+
if (seen.has(dependentNode)) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
seen.add(dependentNode);
|
|
23
|
+
|
|
24
|
+
if (dependentNode === currentNode || siblingDependents.has(currentNode.name)) {
|
|
25
|
+
// a direct or transitive cycle, skip it
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
collected.add(dependentNode);
|
|
30
|
+
queue.push(dependentNode);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
while (queue.length) {
|
|
34
|
+
const node = queue.shift();
|
|
35
|
+
|
|
36
|
+
node.localDependents.forEach(visit);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
return collected;
|
|
41
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { collectDependents } from "./collect-dependents.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Build a list of graph nodes, possibly including dependents, using predicate if available.
|
|
5
|
+
*/
|
|
6
|
+
export function collectPackages(
|
|
7
|
+
packages,
|
|
8
|
+
{ isCandidate = () => true, onInclude, excludeDependents } = {},
|
|
9
|
+
) {
|
|
10
|
+
const candidates = new Set();
|
|
11
|
+
|
|
12
|
+
packages.forEach((node, name) => {
|
|
13
|
+
if (isCandidate(node, name)) {
|
|
14
|
+
candidates.add(node);
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
if (!excludeDependents) {
|
|
19
|
+
collectDependents(candidates).forEach((node) => candidates.add(node));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// The result should always be in the same order as the input
|
|
23
|
+
const updates = [];
|
|
24
|
+
|
|
25
|
+
packages.forEach((node, name) => {
|
|
26
|
+
if (candidates.has(node)) {
|
|
27
|
+
if (onInclude) {
|
|
28
|
+
onInclude(name);
|
|
29
|
+
}
|
|
30
|
+
updates.push(node);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
return updates;
|
|
35
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { execaSync } from "execa";
|
|
2
|
+
import log from "npmlog";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Determine if any git tags are reachable.
|
|
6
|
+
* @param {import("execa").SyncOptions} [opts]
|
|
7
|
+
*/
|
|
8
|
+
export function hasTags(opts) {
|
|
9
|
+
log.silly("hasTags");
|
|
10
|
+
let result = false;
|
|
11
|
+
|
|
12
|
+
try {
|
|
13
|
+
result = !!execaSync("git", ["tag"], opts);
|
|
14
|
+
} catch (err) {
|
|
15
|
+
log.warn("ENOTAGS", "No git tags were reachable from this branch!");
|
|
16
|
+
log.verbose("hasTags error", err);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
log.verbose("hasTags", result);
|
|
20
|
+
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import path from "node:path/posix";
|
|
2
|
+
import { execaSync } from "execa";
|
|
3
|
+
import log from "npmlog";
|
|
4
|
+
import * as minimatch from "minimatch";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @param {string} committish
|
|
8
|
+
* @param {import("execa").SyncOptions} [execOpts]
|
|
9
|
+
* @param {string[]} ignorePatterns
|
|
10
|
+
*/
|
|
11
|
+
export function makeDiffPredicate(committish, execOpts, ignorePatterns = []) {
|
|
12
|
+
const ignoreFilters = new Set(
|
|
13
|
+
ignorePatterns.map((p) =>
|
|
14
|
+
minimatch.filter(`!${p}`, {
|
|
15
|
+
matchBase: true,
|
|
16
|
+
// dotfiles inside ignored directories should also match
|
|
17
|
+
dot: true,
|
|
18
|
+
}),
|
|
19
|
+
),
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
if (ignoreFilters.size) {
|
|
23
|
+
log.info("ignoring diff in paths matching", ignorePatterns);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return function hasDiffSinceThatIsntIgnored(node) {
|
|
27
|
+
const diff = diffSinceIn(committish, node.location, execOpts);
|
|
28
|
+
|
|
29
|
+
if (diff === "") {
|
|
30
|
+
log.silly("", "no diff found in %s", node.name);
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
log.silly("found diff in", diff);
|
|
35
|
+
let changedFiles = diff.split("\n");
|
|
36
|
+
|
|
37
|
+
if (ignoreFilters.size) {
|
|
38
|
+
for (const ignored of ignoreFilters) {
|
|
39
|
+
changedFiles = changedFiles.filter(ignored);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (changedFiles.length) {
|
|
44
|
+
log.verbose("filtered diff", changedFiles);
|
|
45
|
+
} else {
|
|
46
|
+
log.verbose("", "no diff found in %s (after filtering)", node.name);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return changedFiles.length > 0;
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @param {string} committish
|
|
55
|
+
* @param {string} location
|
|
56
|
+
* @param {import("execa").SyncOptions} [opts]
|
|
57
|
+
*/
|
|
58
|
+
function diffSinceIn(committish, location, opts) {
|
|
59
|
+
const args = ["diff", "--name-only", committish];
|
|
60
|
+
const formattedLocation = path.relative(opts.cwd, location);
|
|
61
|
+
|
|
62
|
+
if (formattedLocation) {
|
|
63
|
+
// avoid same-directory path.relative() === ""
|
|
64
|
+
args.push("--", formattedLocation);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
log.silly("checking diff", formattedLocation);
|
|
68
|
+
return execaSync("git", args, opts).stdout;
|
|
69
|
+
}
|
package/lib/verify-git.js
CHANGED
|
@@ -17,7 +17,7 @@ export default async function verifyGit(context) {
|
|
|
17
17
|
Object.entries(VALIDATORS).map(async ([name, validator]) => {
|
|
18
18
|
const details = await validator(context);
|
|
19
19
|
return [name, details];
|
|
20
|
-
})
|
|
20
|
+
}),
|
|
21
21
|
);
|
|
22
22
|
return result
|
|
23
23
|
.filter(([, details]) => details)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "semantic-release-lerna",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "semantic-release plugin to publish lerna monorepo packages to npm",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"npm",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"prettier:check": "prettier --check .",
|
|
40
40
|
"prettier:write": "prettier --write .",
|
|
41
41
|
"semantic-release": "semantic-release",
|
|
42
|
-
"pretest": "npm run eslint",
|
|
42
|
+
"pretest": "npm run eslint && npm run prettier:check",
|
|
43
43
|
"test": "jest --collectCoverage"
|
|
44
44
|
},
|
|
45
45
|
"prettier": "@html-validate/prettier-config",
|
|
@@ -48,8 +48,6 @@
|
|
|
48
48
|
"transformIgnorePatterns": []
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@lerna/child-process": "^7.0.0",
|
|
52
|
-
"@lerna/collect-updates": "^6.0.0",
|
|
53
51
|
"@lerna/package": "^6.0.0",
|
|
54
52
|
"@lerna/package-graph": "^6.0.0",
|
|
55
53
|
"@lerna/project": "^6.0.0",
|
|
@@ -64,33 +62,36 @@
|
|
|
64
62
|
"get-stream": "^8.0.0",
|
|
65
63
|
"into-stream": "^8.0.0",
|
|
66
64
|
"libnpmversion": "^5.0.0",
|
|
65
|
+
"minimatch": "^9.0.0",
|
|
66
|
+
"npmlog": "^7.0.0",
|
|
67
67
|
"read-pkg-up": "^10.0.0",
|
|
68
68
|
"semver": "^7.0.0",
|
|
69
69
|
"tempy": "^3.0.0",
|
|
70
70
|
"write-json-file": "^5.0.0"
|
|
71
71
|
},
|
|
72
72
|
"devDependencies": {
|
|
73
|
-
"@babel/core": "7.23.
|
|
74
|
-
"@babel/preset-env": "7.23.
|
|
75
|
-
"@html-validate/eslint-config": "5.
|
|
76
|
-
"@html-validate/eslint-config-jest": "5.
|
|
77
|
-
"@html-validate/prettier-config": "2.4.
|
|
78
|
-
"@semantic-release/npm": "11.0.
|
|
79
|
-
"@types/jest": "29.5.
|
|
73
|
+
"@babel/core": "7.23.9",
|
|
74
|
+
"@babel/preset-env": "7.23.9",
|
|
75
|
+
"@html-validate/eslint-config": "5.12.8",
|
|
76
|
+
"@html-validate/eslint-config-jest": "5.12.7",
|
|
77
|
+
"@html-validate/prettier-config": "2.4.10",
|
|
78
|
+
"@semantic-release/npm": "11.0.2",
|
|
79
|
+
"@types/jest": "29.5.11",
|
|
80
|
+
"@types/npmlog": "7.0.0",
|
|
80
81
|
"babel-plugin-transform-import-meta": "2.2.1",
|
|
81
82
|
"codecov": "3.8.3",
|
|
82
|
-
"fs-extra": "11.
|
|
83
|
+
"fs-extra": "11.2.0",
|
|
83
84
|
"jest": "29.7.0",
|
|
84
|
-
"lerna": "
|
|
85
|
-
"npm-pkg-lint": "2.0
|
|
86
|
-
"semantic-release": "
|
|
85
|
+
"lerna": "8.0.2",
|
|
86
|
+
"npm-pkg-lint": "2.1.0",
|
|
87
|
+
"semantic-release": "23.0.0",
|
|
87
88
|
"stream-buffers": "3.0.2",
|
|
88
|
-
"verdaccio": "5.
|
|
89
|
+
"verdaccio": "5.29.0"
|
|
89
90
|
},
|
|
90
91
|
"peerDependencies": {
|
|
91
92
|
"@semantic-release/npm": ">= 10",
|
|
92
|
-
"lerna": "^5 || ^6 || ^7",
|
|
93
|
-
"semantic-release": "22"
|
|
93
|
+
"lerna": "^5 || ^6 || ^7 || ^8",
|
|
94
|
+
"semantic-release": "^22 || ^23"
|
|
94
95
|
},
|
|
95
96
|
"engines": {
|
|
96
97
|
"node": ">= 18.17"
|
|
@@ -101,6 +102,20 @@
|
|
|
101
102
|
"renovate": {
|
|
102
103
|
"extends": [
|
|
103
104
|
"gitlab>html-validate/renovate-config"
|
|
105
|
+
],
|
|
106
|
+
"packageRules": [
|
|
107
|
+
{
|
|
108
|
+
"matchPackageNames": [
|
|
109
|
+
"lerna"
|
|
110
|
+
],
|
|
111
|
+
"matchUpdateTypes": [
|
|
112
|
+
"major"
|
|
113
|
+
],
|
|
114
|
+
"commitMessageAction": "support",
|
|
115
|
+
"commitMessageTopic": "{{depName}}",
|
|
116
|
+
"commitMessageExtra": "v{{newMajor}}",
|
|
117
|
+
"semanticCommitType": "feat"
|
|
118
|
+
}
|
|
104
119
|
]
|
|
105
120
|
}
|
|
106
121
|
}
|