semantic-release-lerna 1.0.3 → 2.1.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.
@@ -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 childProcess from "@lerna/child-process";
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 = childProcess.execSync("git", args, execOptions);
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
@@ -49,7 +49,7 @@ export default async function (npmrc, config, pkg, context) {
49
49
  /* Lerna does not support --userconfig */
50
50
  NPM_CONFIG_USERCONFIG: npmrc,
51
51
  },
52
- }
52
+ },
53
53
  );
54
54
  result.stdout.pipe(stdout, { end: false });
55
55
  result.stderr.pipe(stderr, { end: false });
@@ -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,3 @@
1
+ export { collectPackages } from "./collect-packages.js";
2
+ export { hasTags } from "./has-tags.js";
3
+ export { makeDiffPredicate } from "./make-diff-predicate.js";
@@ -0,0 +1,69 @@
1
+ import path from "node:path/posix";
2
+ import { execaSync } from "execa";
3
+ import log from "npmlog";
4
+ import 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": "1.0.3",
3
+ "version": "2.1.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,52 +48,53 @@
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",
56
54
  "@semantic-release/error": "^4.0.0",
57
- "@semantic-release/release-notes-generator": "^11.0.0",
58
- "aggregate-error": "^4.0.0",
59
- "conventional-changelog-writer": "^6.0.0",
60
- "conventional-commits-filter": "^3.0.0",
61
- "conventional-commits-parser": "^4.0.0",
55
+ "@semantic-release/release-notes-generator": "^12.0.0",
56
+ "aggregate-error": "^5.0.0",
57
+ "conventional-changelog-writer": "^7.0.0",
58
+ "conventional-commits-filter": "^4.0.0",
59
+ "conventional-commits-parser": "^5.0.0",
62
60
  "debug": "^4.3.0",
63
- "execa": "^7.0.0",
61
+ "execa": "^8.0.0",
64
62
  "get-stream": "^8.0.0",
65
63
  "into-stream": "^8.0.0",
66
- "libnpmversion": "^4.0.0",
64
+ "libnpmversion": "^5.0.0",
65
+ "minimatch": "^3.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.22.10",
74
- "@babel/preset-env": "7.22.10",
75
- "@html-validate/eslint-config": "5.10.7",
76
- "@html-validate/eslint-config-jest": "5.10.0",
77
- "@html-validate/prettier-config": "2.4.5",
78
- "@semantic-release/npm": "10.0.4",
79
- "@types/jest": "29.5.3",
73
+ "@babel/core": "7.23.5",
74
+ "@babel/preset-env": "7.23.5",
75
+ "@html-validate/eslint-config": "5.12.2",
76
+ "@html-validate/eslint-config-jest": "5.12.0",
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.1.1",
83
- "jest": "29.6.2",
84
- "lerna": "7.1.5",
85
- "npm-pkg-lint": "2.0.1",
86
- "semantic-release": "21.0.7",
83
+ "fs-extra": "11.2.0",
84
+ "jest": "29.7.0",
85
+ "lerna": "8.0.0",
86
+ "npm-pkg-lint": "2.1.0",
87
+ "semantic-release": "22.0.10",
87
88
  "stream-buffers": "3.0.2",
88
- "verdaccio": "5.26.1"
89
+ "verdaccio": "5.29.0"
89
90
  },
90
91
  "peerDependencies": {
91
92
  "@semantic-release/npm": ">= 10",
92
- "lerna": "^3.2 || ^4 || ^5 || ^6 || ^7",
93
- "semantic-release": "^20.1 || 21"
93
+ "lerna": "^5 || ^6 || ^7 || ^8",
94
+ "semantic-release": "22"
94
95
  },
95
96
  "engines": {
96
- "node": ">= 18"
97
+ "node": ">= 18.17"
97
98
  },
98
99
  "publishConfig": {
99
100
  "access": "public"
@@ -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
  }