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/dist/index.js +39380 -0
- package/package.json +10 -73
- package/index.js +0 -97
- package/lib/definitions/errors.js +0 -6
- package/lib/generate-notes.js +0 -134
- package/lib/get-changed-packages.js +0 -113
- package/lib/get-error.js +0 -8
- package/lib/prepare.js +0 -223
- package/lib/publish.js +0 -64
- package/lib/should-latch.js +0 -27
- package/lib/utils/collect-dependents.js +0 -41
- package/lib/utils/collect-packages.js +0 -35
- package/lib/utils/has-tags.js +0 -22
- package/lib/utils/index.js +0 -3
- package/lib/utils/make-diff-predicate.js +0 -69
- package/lib/verify-auth.js +0 -24
- package/lib/verify-git.js +0 -25
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "semantic-release-lerna",
|
|
3
|
-
"version": "2.
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
-
}
|
package/lib/generate-notes.js
DELETED
|
@@ -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
|
-
}
|