semantic-release-lerna 2.2.0 → 2.4.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "semantic-release-lerna",
3
- "version": "2.2.0",
3
+ "version": "2.4.0",
4
4
  "description": "semantic-release plugin to publish lerna monorepo packages to npm",
5
5
  "keywords": [
6
6
  "npm",
@@ -26,96 +26,33 @@
26
26
  "Gregor Martynus (https://twitter.com/gr2m)"
27
27
  ],
28
28
  "type": "module",
29
- "main": "index.js",
29
+ "main": "dist/index.js",
30
30
  "files": [
31
- "lib",
32
- "index.js",
33
- "!*.test.js"
31
+ "dist"
34
32
  ],
35
- "scripts": {
36
- "codecov": "codecov -f coverage/coverage-final.json",
37
- "eslint": "eslint --cache .",
38
- "eslint:fix": "eslint --cache --fix .",
39
- "prettier:check": "prettier --check .",
40
- "prettier:write": "prettier --write .",
41
- "semantic-release": "semantic-release",
42
- "pretest": "npm run eslint && npm run prettier:check",
43
- "test": "jest --collectCoverage"
44
- },
45
- "prettier": "@html-validate/prettier-config",
46
- "jest": {
47
- "testTimeout": 30000,
48
- "transformIgnorePatterns": []
49
- },
50
33
  "dependencies": {
51
- "@lerna/package": "^6.0.0",
52
- "@lerna/package-graph": "^6.0.0",
53
- "@lerna/project": "^6.0.0",
54
34
  "@semantic-release/error": "^4.0.0",
55
35
  "@semantic-release/release-notes-generator": "^12.0.0",
56
- "aggregate-error": "^5.0.0",
57
36
  "conventional-changelog-writer": "^7.0.0",
58
37
  "conventional-commits-filter": "^4.0.0",
59
38
  "conventional-commits-parser": "^5.0.0",
60
- "debug": "^4.3.0",
61
- "execa": "^8.0.0",
62
- "get-stream": "^8.0.0",
63
- "into-stream": "^8.0.0",
39
+ "cosmiconfig": "^7.0.0",
64
40
  "libnpmversion": "^5.0.0",
65
- "minimatch": "^9.0.0",
66
- "npmlog": "^7.0.0",
67
- "read-pkg-up": "^10.0.0",
68
- "semver": "^7.0.0",
69
- "tempy": "^3.0.0",
70
- "write-json-file": "^5.0.0"
71
- },
72
- "devDependencies": {
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",
81
- "babel-plugin-transform-import-meta": "2.2.1",
82
- "codecov": "3.8.3",
83
- "fs-extra": "11.2.0",
84
- "jest": "29.7.0",
85
- "lerna": "8.0.2",
86
- "npm-pkg-lint": "2.1.0",
87
- "semantic-release": "23.0.0",
88
- "stream-buffers": "3.0.2",
89
- "verdaccio": "5.29.0"
41
+ "registry-auth-token": "^5.0.0"
90
42
  },
91
43
  "peerDependencies": {
92
- "@semantic-release/npm": ">= 10",
93
44
  "lerna": "^5 || ^6 || ^7 || ^8",
94
45
  "semantic-release": "^22 || ^23"
95
46
  },
47
+ "peerDependenciesMeta": {
48
+ "lerna": {
49
+ "optional": true
50
+ }
51
+ },
96
52
  "engines": {
97
53
  "node": ">= 18.17"
98
54
  },
99
55
  "publishConfig": {
100
56
  "access": "public"
101
- },
102
- "renovate": {
103
- "extends": [
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
- }
119
- ]
120
57
  }
121
58
  }
package/index.js DELETED
@@ -1,97 +0,0 @@
1
- import AggregateError from "aggregate-error";
2
- import { temporaryFile } from "tempy";
3
- import getPkg from "@semantic-release/npm/lib/get-pkg.js";
4
- import verifyNpmConfig from "@semantic-release/npm/lib/verify-config.js";
5
- import verifyNpmAuth from "./lib/verify-auth.js";
6
- import verifyGit from "./lib/verify-git.js";
7
- import prepareNpm from "./lib/prepare.js";
8
- import publishNpm from "./lib/publish.js";
9
-
10
- export { generateNotes } from "./lib/generate-notes.js";
11
-
12
- let verified;
13
- const npmrc = temporaryFile({ name: ".npmrc" });
14
-
15
- const defaultConfig = {
16
- npmVerifyAuth: true,
17
- npmPublish: undefined,
18
- tarballDir: undefined,
19
- pkgRoot: undefined,
20
- latch: "minor",
21
- };
22
-
23
- /**
24
- * @template T
25
- * @param {T} value
26
- * @param {T} defaultValue
27
- * @returns {T}
28
- */
29
- function defaultTo(value, defaultValue) {
30
- return value === null || value === undefined ? defaultValue : value;
31
- }
32
-
33
- export async function verifyConditions(pluginConfig, context) {
34
- pluginConfig.npmVerifyAuth = defaultTo(pluginConfig.npmVerifyAuth, defaultConfig.npmVerifyAuth);
35
- pluginConfig.npmPublish = defaultTo(pluginConfig.npmPublish, defaultConfig.npmPublish);
36
- pluginConfig.tarballDir = defaultTo(pluginConfig.tarballDir, defaultConfig.tarballDir);
37
- pluginConfig.pkgRoot = defaultTo(pluginConfig.pkgRoot, defaultConfig.pkgRoot);
38
-
39
- const errors = [...verifyNpmConfig(pluginConfig), ...(await verifyGit(context))];
40
-
41
- try {
42
- if (pluginConfig.npmVerifyAuth) {
43
- const pkg = await getPkg(pluginConfig, context);
44
- await verifyNpmAuth(npmrc, pkg, context);
45
- }
46
- } catch (error) {
47
- errors.push(...error.errors);
48
- }
49
-
50
- if (errors.length > 0) {
51
- throw new AggregateError(errors);
52
- }
53
-
54
- verified = true;
55
- }
56
-
57
- export async function prepare(pluginConfig, context) {
58
- pluginConfig.latch = defaultTo(pluginConfig.latch, defaultConfig.latch);
59
-
60
- const errors = verified ? [] : verifyNpmConfig(pluginConfig);
61
-
62
- try {
63
- if (pluginConfig.npmVerifyAuth) {
64
- const pkg = await getPkg(pluginConfig, context);
65
- await verifyNpmAuth(npmrc, pkg, context);
66
- }
67
- } catch (error) {
68
- errors.push(...error);
69
- }
70
-
71
- if (errors.length > 0) {
72
- throw new AggregateError(errors);
73
- }
74
-
75
- await prepareNpm(npmrc, pluginConfig, context);
76
- }
77
-
78
- export async function publish(pluginConfig, context) {
79
- let pkg;
80
- const errors = verified ? [] : verifyNpmConfig(pluginConfig);
81
-
82
- try {
83
- // Reload package.json in case a previous external step updated it
84
- pkg = await getPkg(pluginConfig, context);
85
- if (!verified && pluginConfig.npmPublish !== false && pkg.private !== true) {
86
- await verifyNpmAuth(npmrc, pkg, context);
87
- }
88
- } catch (error) {
89
- errors.push(...error);
90
- }
91
-
92
- if (errors.length > 0) {
93
- throw new AggregateError(errors);
94
- }
95
-
96
- return publishNpm(npmrc, pluginConfig, pkg, context);
97
- }
@@ -1,6 +0,0 @@
1
- export function EDIRTYWC({ files }) {
2
- return {
3
- message: "Dirty working copy.",
4
- details: `The git working copy must be clean before releasing:\n\n${files.join("\n")}\n`,
5
- };
6
- }
@@ -1,134 +0,0 @@
1
- import { format } from "node:url";
2
- import getStream from "get-stream";
3
- import intoStream from "into-stream";
4
- import { sync as parser } from "conventional-commits-parser";
5
- import writer from "conventional-changelog-writer";
6
- import filter from "conventional-commits-filter";
7
- import { readPackageUp } from "read-pkg-up";
8
- import debugFactory from "debug";
9
- import loadChangelogConfig from "@semantic-release/release-notes-generator/lib/load-changelog-config.js";
10
- import HOSTS_CONFIG from "@semantic-release/release-notes-generator/lib/hosts-config.js";
11
- import { Project } from "@lerna/project";
12
- import { makeDiffPredicate } from "./utils/index.js";
13
-
14
- const debug = debugFactory("semantic-release:release-notes-generator");
15
-
16
- /**
17
- * Generate the changelog for all the commits in `options.commits`.
18
- *
19
- * @param {Object} pluginConfig The plugin configuration.
20
- * @param {String} pluginConfig.preset conventional-changelog preset ('angular', 'atom', 'codemirror', 'ember', 'eslint', 'express', 'jquery', 'jscs', 'jshint').
21
- * @param {String} pluginConfig.config Requierable npm package with a custom conventional-changelog preset
22
- * @param {Object} pluginConfig.parserOpts Additional `conventional-changelog-parser` options that will overwrite ones loaded by `preset` or `config`.
23
- * @param {Object} pluginConfig.writerOpts Additional `conventional-changelog-writer` options that will overwrite ones loaded by `preset` or `config`.
24
- * @param {Object} context The semantic-release context.
25
- * @param {Array<Object>} context.commits The commits to analyze.
26
- * @param {Object} context.lastRelease The last release with `gitHead` corresponding to the commit hash used to make the last release and `gitTag` corresponding to the git tag associated with `gitHead`.
27
- * @param {Object} context.nextRelease The next release with `gitHead` corresponding to the commit hash used to make the release, the release `version` and `gitTag` corresponding to the git tag associated with `gitHead`.
28
- * @param {Object} context.options.repositoryUrl The git repository URL.
29
- *
30
- * @returns {String} The changelog for all the commits in `context.commits`.
31
- */
32
- /* eslint-disable-next-line complexity, sonarjs/cognitive-complexity -- technical debt */
33
- export async function generateNotes(pluginConfig, context) {
34
- const { commits, lastRelease, nextRelease, options, cwd, logger } = context;
35
- const { generateNotes = false } = pluginConfig;
36
-
37
- if (!generateNotes) {
38
- logger.log(`Release notes scope disabled, skipping`);
39
- return "";
40
- }
41
-
42
- const repositoryUrl = options.repositoryUrl.replace(/\.git$/i, "");
43
- const { parserOpts, writerOpts } = await loadChangelogConfig(pluginConfig, context);
44
-
45
- const project = new Project(cwd);
46
- const packages = await project.getPackages();
47
-
48
- function fillScope(parsedCommit) {
49
- if (parsedCommit.scope) {
50
- return parsedCommit;
51
- }
52
-
53
- const hasDiff = makeDiffPredicate(`${parsedCommit.hash}^!`, { cwd });
54
- const scope = packages.filter((pkg) => !pkg.private && hasDiff(pkg)).map((pkg) => pkg.name);
55
- if (scope.length > 0) {
56
- parsedCommit.scope = scope.join(", ");
57
- }
58
-
59
- return parsedCommit;
60
- }
61
-
62
- const [match, auth, host, path] =
63
- /* eslint-disable-next-line security/detect-unsafe-regex -- technical debt */
64
- /^(?!.+:\/\/)(?:(?<auth>.*)@)?(?<host>.*?):(?<path>.*)$/.exec(repositoryUrl) || [];
65
- const authString = auth ? `${auth}@` : "";
66
- const url = new URL(match ? `ssh://${authString}${host}/${path}` : repositoryUrl);
67
- const { hostname, pathname } = url;
68
- let { port, protocol } = url;
69
- port = protocol.includes("ssh") ? "" : port;
70
- protocol = protocol && /http[^s]/.test(protocol) ? "http" : "https";
71
- /* eslint-disable-next-line security/detect-unsafe-regex -- technical debt */
72
- const [, owner, repository] = /^\/(?<owner>[^/]+)?\/?(?<repository>.+)?$/.exec(pathname);
73
-
74
- const { issue, commit, referenceActions, issuePrefixes } =
75
- Object.values(HOSTS_CONFIG).find((conf) => conf.hostname === hostname) || HOSTS_CONFIG.default;
76
- const parsedCommits = filter(
77
- commits
78
- .filter(({ message, hash }) => {
79
- if (!message.trim()) {
80
- debug("Skip commit %s with empty message", hash);
81
- return false;
82
- }
83
-
84
- return true;
85
- })
86
- .map((rawCommit) =>
87
- fillScope({
88
- ...rawCommit,
89
- ...parser(rawCommit.message, { referenceActions, issuePrefixes, ...parserOpts }),
90
- }),
91
- ),
92
- );
93
- const previousTag = lastRelease.gitTag || lastRelease.gitHead;
94
- const currentTag = nextRelease.gitTag || nextRelease.gitHead;
95
- const {
96
- host: hostConfig,
97
- linkCompare,
98
- linkReferences,
99
- commit: commitConfig,
100
- issue: issueConfig,
101
- } = pluginConfig;
102
- const defaultContext = {
103
- version: nextRelease.version,
104
- host: format({ protocol, hostname, port }),
105
- owner,
106
- repository,
107
- previousTag,
108
- currentTag,
109
- linkCompare: currentTag && previousTag,
110
- issue,
111
- commit,
112
- packageData: ((await readPackageUp({ normalize: false, cwd })) || {}).packageJson,
113
- };
114
- const userConfig = {
115
- host: hostConfig,
116
- linkCompare,
117
- linkReferences,
118
- commit: commitConfig,
119
- issue: issueConfig,
120
- };
121
- const changelogContext = { ...defaultContext, ...userConfig };
122
-
123
- debug("version: %o", changelogContext.version);
124
- debug("host: %o", changelogContext.hostname);
125
- debug("owner: %o", changelogContext.owner);
126
- debug("repository: %o", changelogContext.repository);
127
- debug("previousTag: %o", changelogContext.previousTag);
128
- debug("currentTag: %o", changelogContext.currentTag);
129
- debug("linkReferences: %o", changelogContext.linkReferences);
130
- debug("issue: %o", changelogContext.issue);
131
- debug("commit: %o", changelogContext.commit);
132
-
133
- return getStream(intoStream.object(parsedCommits).pipe(writer(changelogContext, writerOpts)));
134
- }
@@ -1,113 +0,0 @@
1
- import { format } from "node:util";
2
- import { PackageGraph } from "@lerna/package-graph";
3
- import { Project } from "@lerna/project";
4
- import { execaSync } from "execa";
5
- import { shouldLatch } from "./should-latch.js";
6
- import { collectPackages, hasTags, makeDiffPredicate } from "./utils/index.js";
7
-
8
- function describeRefSync(execOptions) {
9
- const args = [
10
- "describe",
11
- "--tags",
12
- // Fallback to short sha if no tags located
13
- "--always",
14
- // Always return full result, helps identify existing release
15
- "--long",
16
- // Annotate if uncommitted changes present
17
- "--dirty",
18
- // Prefer tags originating on upstream branch
19
- "--first-parent",
20
- ];
21
- const { stdout } = execaSync("git", args, execOptions);
22
- return parse(stdout, execOptions);
23
- }
24
-
25
- function parse(stdout, options = {}) {
26
- const minimalShaRegex = /^([\da-f]{7,40})(-dirty)?$/;
27
- // When git describe fails to locate tags, it returns only the minimal sha
28
- if (minimalShaRegex.test(stdout)) {
29
- // Repo might still be dirty
30
- const [, sha, isDirty] = minimalShaRegex.exec(stdout);
31
-
32
- // Count number of commits since beginning of time
33
- const refCount = childProcess.execSync("git", ["rev-list", "--count", sha], options);
34
-
35
- return { refCount, sha, isDirty: Boolean(isDirty) };
36
- }
37
-
38
- /* eslint-disable-next-line security/detect-unsafe-regex -- technical debt */
39
- const result = /^((?:.*@)?(.*))-(\d+)-g([\da-f]+)(-dirty)?$/.exec(stdout) || [];
40
- const [, lastTagName, lastVersion, refCount, sha, isDirty] = result;
41
-
42
- return { lastTagName, lastVersion, refCount, sha, isDirty: Boolean(isDirty) };
43
- }
44
-
45
- function collectUpdates(filteredPackages, packageGraph, execOptions, commandOptions) {
46
- const { version, logger, latch } = commandOptions;
47
-
48
- const packages =
49
- filteredPackages.length === packageGraph.size
50
- ? packageGraph
51
- : new Map(filteredPackages.map(({ name }) => [name, packageGraph.get(name)]));
52
-
53
- let committish;
54
-
55
- if (hasTags(execOptions)) {
56
- // Describe the last annotated tag in the current branch
57
- const { refCount, lastTagName } = describeRefSync(execOptions);
58
-
59
- if (refCount === "0" && !committish) {
60
- // No commits since previous release
61
- logger.warn("", "Current HEAD is already released, skipping change detection.");
62
-
63
- return [];
64
- }
65
-
66
- // If no tags found, this will be undefined and we'll use the initial commit
67
- committish = lastTagName;
68
- }
69
-
70
- if (shouldLatch(version, latch)) {
71
- logger.log(`Bumping all packages because configuration is set to latch on ${latch} and higher`);
72
- return collectPackages(packages);
73
- }
74
-
75
- if (!committish) {
76
- logger.log("Failed to find last release tag, assuming all packages changed");
77
- return collectPackages(packages);
78
- }
79
-
80
- logger.log(`Looking for changed packages since ${committish}`);
81
-
82
- const hasDiff = makeDiffPredicate(committish, execOptions, commandOptions.ignoreChanges);
83
-
84
- return collectPackages(packages, {
85
- isCandidate: (node) => hasDiff(node),
86
- });
87
- }
88
-
89
- /**
90
- * @param {"major" | "minor" | "patch" | "prerelease" | "none"} latch
91
- * @param {any} context
92
- * @returns {Promise<any[]>}
93
- */
94
- export default async function getChangedPackages(latch, context) {
95
- const { cwd, logger, version } = context;
96
- const project = new Project(cwd);
97
- const packages = await project.getPackages();
98
- const packageGraph = new PackageGraph(packages);
99
- logger.log(
100
- `%d package${packages.length === 1 ? "" : "s"} found: %s`,
101
- packages.length,
102
- format(packages.map((pkg) => pkg.name)),
103
- );
104
-
105
- const updates = collectUpdates(
106
- packageGraph.rawPackageList,
107
- packageGraph,
108
- { cwd },
109
- { logger, version, latch },
110
- );
111
-
112
- return updates.map((node) => packages.find((pkg) => pkg.name === node.name));
113
- }
package/lib/get-error.js DELETED
@@ -1,8 +0,0 @@
1
- import SemanticReleaseError from "@semantic-release/error";
2
- import * as ERROR_DEFINITIONS from "./definitions/errors.js";
3
-
4
- export default function (code, ctx = {}) {
5
- /* eslint-disable-next-line import/namespace -- this is how upstream does it */
6
- const { message, details } = ERROR_DEFINITIONS[code](ctx);
7
- return new SemanticReleaseError(message, code, details);
8
- }
package/lib/prepare.js DELETED
@@ -1,223 +0,0 @@
1
- import path from "node:path";
2
- import fs from "node:fs/promises";
3
- import { existsSync } from "node:fs";
4
- import { format } from "node:util";
5
- import { execa } from "execa";
6
- import npmVersion from "libnpmversion";
7
- import { Project } from "@lerna/project";
8
- import { Package } from "@lerna/package";
9
- import { writeJsonFile } from "write-json-file";
10
- import semverParse from "semver/functions/parse.js";
11
- import getChangedPackages from "./get-changed-packages.js";
12
-
13
- /**
14
- * @param {string} path
15
- * @returns {any}
16
- **/
17
- async function readJson(path) {
18
- return JSON.parse(await fs.readFile(path));
19
- }
20
-
21
- /**
22
- * Bump version in "lerna.json".
23
- *
24
- * @param {string} basePath
25
- * @param {any} context
26
- * @returns {Promise<void>}
27
- */
28
- async function updateLernaJson(basePath, context) {
29
- const {
30
- logger,
31
- nextRelease: { version },
32
- } = context;
33
- logger.log("Write version %s to lerna.json in %s", version, basePath);
34
- const project = new Project(basePath);
35
- project.version = version;
36
- await project.serializeConfig();
37
- }
38
-
39
- /**
40
- * Bump version in a single package "package.json".
41
- *
42
- * @param {string} npmrc
43
- * @param {Package} pkg
44
- * @param {any} context
45
- * @param {Record<string, string>} currentVersions
46
- * @returns {Promise<void>}
47
- */
48
- async function updatePackage(npmrc, pkg, context, currentVersions) {
49
- const {
50
- nextRelease: { version },
51
- logger,
52
- } = context;
53
- logger.log("Write version %s to package.json in %s", version, pkg.location);
54
-
55
- await npmVersion(version, {
56
- path: pkg.location,
57
- allowSameVersion: true,
58
- commitHooks: false,
59
- gitTagVersion: false,
60
- signGitCommit: false,
61
- signGitTag: false,
62
- force: false,
63
- ignoreScripts: false,
64
- silent: false,
65
- });
66
-
67
- /* Bump dependencies */
68
- if (currentVersions) {
69
- await updatePackageDependencies(pkg, version, currentVersions);
70
- }
71
- }
72
-
73
- /**
74
- * Bump version in a single package "package-lock.json".
75
- *
76
- * Noop if "package-lock.json" does not exist.
77
- *
78
- * @param {string} npmrc
79
- * @param {Package} pkg
80
- * @param {any} context
81
- * @returns {Promise<void>}
82
- */
83
- async function updateLockfile(npmrc, pkg, context) {
84
- const { env, stdout, stderr, logger } = context;
85
-
86
- const lockfile = path.join(pkg.location, "package-lock.json");
87
- if (!existsSync(lockfile)) {
88
- return;
89
- }
90
-
91
- logger.log("Update package-lock.json in %s", pkg.location);
92
-
93
- const versionResult = execa(
94
- "npm",
95
- ["install", "--package-lock-only", "--ignore-scripts", "--no-audit", "--userconfig", npmrc],
96
- {
97
- cwd: pkg.location,
98
- env,
99
- },
100
- );
101
- versionResult.stdout.pipe(stdout, { end: false });
102
- versionResult.stderr.pipe(stderr, { end: false });
103
- await versionResult;
104
- }
105
-
106
- /**
107
- * @param {Record<string, string>} dependencies
108
- * @param {string} newVersion
109
- * @param {Record<string, string>} currentVersions
110
- * @returns {void}
111
- */
112
- function bumpDependency(dependencies, newVersion, currentVersions) {
113
- const newParsed = semverParse(newVersion);
114
- if (!newParsed) {
115
- return;
116
- }
117
- for (const [dep, range] of Object.entries(dependencies)) {
118
- if (!currentVersions[dep]) {
119
- continue;
120
- }
121
-
122
- const version = currentVersions[dep];
123
- const parsed = semverParse(version);
124
- if (!parsed) {
125
- continue;
126
- }
127
-
128
- /* Exact versions */
129
- if (range === version) {
130
- dependencies[dep] = newVersion;
131
- }
132
-
133
- /* Hat ^x.y.z */
134
- if (range === `^${version}`) {
135
- dependencies[dep] = `^${newVersion}`;
136
- }
137
-
138
- /* Hat ^x.y */
139
- if (range === `^${parsed.major}.${parsed.minor}`) {
140
- dependencies[dep] = `^${newParsed.major}.${newParsed.minor}`;
141
- }
142
-
143
- /* Hat ^x */
144
- if (range === `^${parsed.major}`) {
145
- dependencies[dep] = `^${newParsed.major}`;
146
- }
147
- }
148
- }
149
-
150
- /**
151
- * @param {Package} pkg
152
- * @param {string} newVersion
153
- * @param {Record<string, string>} currentVersions
154
- * @returns {Promise<void>}
155
- */
156
- async function updatePackageDependencies(pkg, newVersion, currentVersions) {
157
- const pkgData = await readJson(pkg.manifestLocation);
158
-
159
- bumpDependency(pkgData.dependencies || {}, newVersion, currentVersions);
160
- bumpDependency(pkgData.devDependencies || {}, newVersion, currentVersions);
161
- bumpDependency(pkgData.peerDependencies || {}, newVersion, currentVersions);
162
-
163
- await writeJsonFile(pkg.manifestLocation, pkgData, { indent: 2, detectIndent: true });
164
- }
165
-
166
- /**
167
- * Get current version from `package.json`.
168
- *
169
- * @param {Package} pkg
170
- * @returns {Promise<[string, string]>}
171
- */
172
- async function getCurrentVersion(pkg) {
173
- const pkgData = await readJson(pkg.manifestLocation);
174
- return [pkgData.name, pkgData.version];
175
- }
176
-
177
- /**
178
- * @param {string} npmrc
179
- * @param {any} context
180
- * @returns {Promise<void>}
181
- */
182
- export default async function (npmrc, pluginConfig, context) {
183
- const {
184
- cwd,
185
- nextRelease: { version },
186
- logger,
187
- } = context;
188
- const basePath = pluginConfig.pkgRoot ? path.resolve(cwd, pluginConfig.pkgRoot) : cwd;
189
- const rootPkg = new Package(readJson(path.join(basePath, "package.json")), basePath);
190
- const { rootVersion = true } = pluginConfig;
191
-
192
- const changed = await getChangedPackages(pluginConfig.latch, { cwd, logger, version });
193
- if (changed.length === 0) {
194
- logger.log("No packages changed, applying version bump on root package only");
195
- await updateLernaJson(basePath, context);
196
- await updatePackage(npmrc, rootPkg, context);
197
- return;
198
- }
199
-
200
- const s = changed.length > 1 ? "s" : "";
201
- logger.log(
202
- `${changed.length} package${s} need version bump: ${format(changed.map((pkg) => pkg.name))}`,
203
- );
204
-
205
- const currentVersions = Object.fromEntries(
206
- await Promise.all(changed.map((pkg) => getCurrentVersion(pkg))),
207
- );
208
-
209
- /* Bump version in all changed packages */
210
- for (const pkg of changed) {
211
- await updatePackage(npmrc, pkg, context, currentVersions);
212
- }
213
-
214
- /* Bump version in "lerna.json" */
215
- await updateLernaJson(basePath, context);
216
-
217
- if (rootVersion) {
218
- await updatePackage(npmrc, rootPkg, context);
219
- await updateLockfile(npmrc, rootPkg, context);
220
- } else {
221
- logger.log("Don't write version to root package.json");
222
- }
223
- }