semantic-release-lerna 0.8.0 → 1.0.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/README.md CHANGED
@@ -70,15 +70,13 @@ The plugin can be configured in the [**semantic-release** configuration file](ht
70
70
  }
71
71
  ```
72
72
 
73
- To use legacy auth set `NPM_USERNAME`, `NPM_PASSWORD` and `NPM_EMAIL`.
74
-
75
73
  ## Options
76
74
 
77
- | Option | Description | Default |
78
- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- |
79
- | `npmVerifyAuth` | Set to `false` to disable verifying NPM registry credentials. | `true` |
75
+ | Option | Description | Default |
76
+ | --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- |
77
+ | `npmVerifyAuth` | Set to `false` to disable verifying NPM registry credentials. | `true` |
80
78
  | `latch` | Latches package versions together. If the version bump is at least the given version all packages will be bumped regardless if the package has been touched or not. `"major", "minor", "patch", "prerelease", "none"` | `"minor"` |
81
- | `rootVersion` | Allow to update version on root `package.json`. | `true` |
79
+ | `rootVersion` | Allow to update version on root `package.json`. | `true` |
82
80
 
83
81
  ## Troubleshooting
84
82
 
package/index.js CHANGED
@@ -1,16 +1,16 @@
1
- const AggregateError = require("aggregate-error");
2
- const tempy = require("tempy");
3
- const setLegacyToken = require("@semantic-release/npm/lib/set-legacy-token");
4
- const getPkg = require("@semantic-release/npm/lib/get-pkg");
5
- const verifyNpmConfig = require("@semantic-release/npm/lib/verify-config");
6
- const verifyNpmAuth = require("./lib/verify-auth");
7
- const verifyGit = require("./lib/verify-git");
8
- const prepareNpm = require("./lib/prepare");
9
- const publishNpm = require("./lib/publish");
10
- const generateNotes = require("./lib/generate-notes");
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
11
 
12
12
  let verified;
13
- const npmrc = tempy.file({ name: ".npmrc" });
13
+ const npmrc = temporaryFile({ name: ".npmrc" });
14
14
 
15
15
  const defaultConfig = {
16
16
  npmVerifyAuth: true,
@@ -30,7 +30,7 @@ function defaultTo(value, defaultValue) {
30
30
  return value === null || value === undefined ? defaultValue : value;
31
31
  }
32
32
 
33
- async function verifyConditions(pluginConfig, context) {
33
+ export async function verifyConditions(pluginConfig, context) {
34
34
  pluginConfig.npmVerifyAuth = defaultTo(pluginConfig.npmVerifyAuth, defaultConfig.npmVerifyAuth);
35
35
  pluginConfig.npmPublish = defaultTo(pluginConfig.npmPublish, defaultConfig.npmPublish);
36
36
  pluginConfig.tarballDir = defaultTo(pluginConfig.tarballDir, defaultConfig.tarballDir);
@@ -38,15 +38,13 @@ async function verifyConditions(pluginConfig, context) {
38
38
 
39
39
  const errors = [...verifyNpmConfig(pluginConfig), ...(await verifyGit(context))];
40
40
 
41
- setLegacyToken(context);
42
-
43
41
  try {
44
42
  if (pluginConfig.npmVerifyAuth) {
45
43
  const pkg = await getPkg(pluginConfig, context);
46
44
  await verifyNpmAuth(npmrc, pkg, context);
47
45
  }
48
46
  } catch (error) {
49
- errors.push(...error);
47
+ errors.push(...error.errors);
50
48
  }
51
49
 
52
50
  if (errors.length > 0) {
@@ -56,13 +54,11 @@ async function verifyConditions(pluginConfig, context) {
56
54
  verified = true;
57
55
  }
58
56
 
59
- async function prepare(pluginConfig, context) {
57
+ export async function prepare(pluginConfig, context) {
60
58
  pluginConfig.latch = defaultTo(pluginConfig.latch, defaultConfig.latch);
61
59
 
62
60
  const errors = verified ? [] : verifyNpmConfig(pluginConfig);
63
61
 
64
- setLegacyToken(context);
65
-
66
62
  try {
67
63
  if (pluginConfig.npmVerifyAuth) {
68
64
  const pkg = await getPkg(pluginConfig, context);
@@ -79,12 +75,10 @@ async function prepare(pluginConfig, context) {
79
75
  await prepareNpm(npmrc, pluginConfig, context);
80
76
  }
81
77
 
82
- async function publish(pluginConfig, context) {
78
+ export async function publish(pluginConfig, context) {
83
79
  let pkg;
84
80
  const errors = verified ? [] : verifyNpmConfig(pluginConfig);
85
81
 
86
- setLegacyToken(context);
87
-
88
82
  try {
89
83
  // Reload package.json in case a previous external step updated it
90
84
  pkg = await getPkg(pluginConfig, context);
@@ -101,10 +95,3 @@ async function publish(pluginConfig, context) {
101
95
 
102
96
  return publishNpm(npmrc, pluginConfig, pkg, context);
103
97
  }
104
-
105
- module.exports = {
106
- verifyConditions,
107
- prepare,
108
- publish,
109
- generateNotes,
110
- };
@@ -1,6 +1,6 @@
1
- module.exports = {
2
- EDIRTYWC: ({ files }) => ({
1
+ export function EDIRTYWC({ files }) {
2
+ return {
3
3
  message: "Dirty working copy.",
4
4
  details: `The git working copy must be clean before releasing:\n\n${files.join("\n")}\n`,
5
- }),
6
- };
5
+ };
6
+ }
@@ -1,15 +1,17 @@
1
- const { format } = require("url");
2
- const getStream = require("get-stream");
3
- const intoStream = require("into-stream");
4
- const parser = require("conventional-commits-parser").sync;
5
- const writer = require("conventional-changelog-writer");
6
- const filter = require("conventional-commits-filter");
7
- const readPkgUp = require("read-pkg-up");
8
- const debug = require("debug")("semantic-release:release-notes-generator");
9
- const loadChangelogConfig = require("@semantic-release/release-notes-generator/lib/load-changelog-config");
10
- const HOSTS_CONFIG = require("@semantic-release/release-notes-generator/lib/hosts-config");
11
- const { makeDiffPredicate } = require("@lerna/collect-updates/lib/make-diff-predicate");
12
- const { Project } = require("@lerna/project");
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 { makeDiffPredicate } from "@lerna/collect-updates/lib/make-diff-predicate.js";
12
+ import { Project } from "@lerna/project";
13
+
14
+ const debug = debugFactory("semantic-release:release-notes-generator");
13
15
 
14
16
  /**
15
17
  * Generate the changelog for all the commits in `options.commits`.
@@ -27,8 +29,8 @@ const { Project } = require("@lerna/project");
27
29
  *
28
30
  * @returns {String} The changelog for all the commits in `context.commits`.
29
31
  */
30
- /* eslint-disable-next-line complexity, sonarjs/cognitive-complexity */
31
- async function generateNotes(pluginConfig, context) {
32
+ /* eslint-disable-next-line complexity, sonarjs/cognitive-complexity -- technical debt */
33
+ export async function generateNotes(pluginConfig, context) {
32
34
  const { commits, lastRelease, nextRelease, options, cwd, logger } = context;
33
35
  const { generateNotes = false } = pluginConfig;
34
36
 
@@ -58,7 +60,7 @@ async function generateNotes(pluginConfig, context) {
58
60
  }
59
61
 
60
62
  const [match, auth, host, path] =
61
- /* eslint-disable-next-line security/detect-unsafe-regex */
63
+ /* eslint-disable-next-line security/detect-unsafe-regex -- technical debt */
62
64
  /^(?!.+:\/\/)(?:(?<auth>.*)@)?(?<host>.*?):(?<path>.*)$/.exec(repositoryUrl) || [];
63
65
  const authString = auth ? `${auth}@` : "";
64
66
  const url = new URL(match ? `ssh://${authString}${host}/${path}` : repositoryUrl);
@@ -66,7 +68,7 @@ async function generateNotes(pluginConfig, context) {
66
68
  let { port, protocol } = url;
67
69
  port = protocol.includes("ssh") ? "" : port;
68
70
  protocol = protocol && /http[^s]/.test(protocol) ? "http" : "https";
69
- /* eslint-disable-next-line security/detect-unsafe-regex */
71
+ /* eslint-disable-next-line security/detect-unsafe-regex -- technical debt */
70
72
  const [, owner, repository] = /^\/(?<owner>[^/]+)?\/?(?<repository>.+)?$/.exec(pathname);
71
73
 
72
74
  const { issue, commit, referenceActions, issuePrefixes } =
@@ -107,7 +109,7 @@ async function generateNotes(pluginConfig, context) {
107
109
  linkCompare: currentTag && previousTag,
108
110
  issue,
109
111
  commit,
110
- packageData: ((await readPkgUp({ normalize: false, cwd })) || {}).packageJson,
112
+ packageData: ((await readPackageUp({ normalize: false, cwd })) || {}).packageJson,
111
113
  };
112
114
  const userConfig = {
113
115
  host: hostConfig,
@@ -130,5 +132,3 @@ async function generateNotes(pluginConfig, context) {
130
132
 
131
133
  return getStream(intoStream.object(parsedCommits).pipe(writer(changelogContext, writerOpts)));
132
134
  }
133
-
134
- module.exports = generateNotes;
@@ -1,11 +1,11 @@
1
- const { format } = require("util");
2
- const { PackageGraph } = require("@lerna/package-graph");
3
- const { Project } = require("@lerna/project");
4
- const childProcess = require("@lerna/child-process");
5
- const { hasTags } = require("@lerna/collect-updates/lib/has-tags");
6
- const { collectPackages } = require("@lerna/collect-updates/lib/collect-packages");
7
- const { makeDiffPredicate } = require("@lerna/collect-updates/lib/make-diff-predicate");
8
- const shouldLatch = require("./should-latch");
1
+ import { format } from "node:util";
2
+ import { PackageGraph } from "@lerna/package-graph";
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";
8
+ import { shouldLatch } from "./should-latch.js";
9
9
 
10
10
  function describeRefSync(execOptions) {
11
11
  const args = [
@@ -37,7 +37,7 @@ function parse(stdout, options = {}) {
37
37
  return { refCount, sha, isDirty: Boolean(isDirty) };
38
38
  }
39
39
 
40
- /* eslint-disable-next-line security/detect-unsafe-regex */
40
+ /* eslint-disable-next-line security/detect-unsafe-regex -- technical debt */
41
41
  const result = /^((?:.*@)?(.*))-(\d+)-g([\da-f]+)(-dirty)?$/.exec(stdout) || [];
42
42
  const [, lastTagName, lastVersion, refCount, sha, isDirty] = result;
43
43
 
@@ -93,7 +93,7 @@ function collectUpdates(filteredPackages, packageGraph, execOptions, commandOpti
93
93
  * @param {any} context
94
94
  * @returns {Promise<any[]>}
95
95
  */
96
- async function getChangedPackages(latch, context) {
96
+ export default async function getChangedPackages(latch, context) {
97
97
  const { cwd, logger, version } = context;
98
98
  const project = new Project(cwd);
99
99
  const packages = await project.getPackages();
@@ -113,5 +113,3 @@ async function getChangedPackages(latch, context) {
113
113
 
114
114
  return updates.map((node) => packages.find((pkg) => pkg.name === node.name));
115
115
  }
116
-
117
- module.exports = getChangedPackages;
package/lib/get-error.js CHANGED
@@ -1,7 +1,8 @@
1
- const SemanticReleaseError = require("@semantic-release/error");
2
- const ERROR_DEFINITIONS = require("./definitions/errors");
1
+ import SemanticReleaseError from "@semantic-release/error";
2
+ import * as ERROR_DEFINITIONS from "./definitions/errors.js";
3
3
 
4
- module.exports = (code, ctx = {}) => {
4
+ export default function (code, ctx = {}) {
5
+ /* eslint-disable-next-line import/namespace -- this is how upstream does it */
5
6
  const { message, details } = ERROR_DEFINITIONS[code](ctx);
6
7
  return new SemanticReleaseError(message, code, details);
7
- };
8
+ }
package/lib/prepare.js CHANGED
@@ -1,21 +1,20 @@
1
- const path = require("path");
2
- const fs = require("fs").promises;
3
- const { existsSync } = require("fs");
4
- const { format } = require("util");
5
- const execa = require("execa");
6
- const npmVersion = require("libnpmversion");
7
- const { Project } = require("@lerna/project");
8
- const { Package } = require("@lerna/package");
9
- const writeJsonFile = require("write-json-file");
10
- const semverParse = require("semver/functions/parse");
11
- const getChangedPackages = require("./get-changed-packages");
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
12
 
13
13
  /**
14
14
  * @param {string} path
15
15
  * @returns {any}
16
16
  **/
17
17
  async function readJson(path) {
18
- /* eslint-disable-next-line security/detect-non-literal-fs-filename */
19
18
  return JSON.parse(await fs.readFile(path));
20
19
  }
21
20
 
@@ -180,7 +179,7 @@ async function getCurrentVersion(pkg) {
180
179
  * @param {any} context
181
180
  * @returns {Promise<void>}
182
181
  */
183
- module.exports = async (npmrc, pluginConfig, context) => {
182
+ export default async function (npmrc, pluginConfig, context) {
184
183
  const {
185
184
  cwd,
186
185
  nextRelease: { version },
@@ -209,8 +208,6 @@ module.exports = async (npmrc, pluginConfig, context) => {
209
208
 
210
209
  /* Bump version in all changed packages */
211
210
  for (const pkg of changed) {
212
- /* Want to perform version bumps in serial, disable eslint rule warning about it */
213
- /* eslint-disable-next-line no-await-in-loop */
214
211
  await updatePackage(npmrc, pkg, context, currentVersions);
215
212
  }
216
213
 
@@ -223,4 +220,4 @@ module.exports = async (npmrc, pluginConfig, context) => {
223
220
  } else {
224
221
  logger.log("Don't write version to root package.json");
225
222
  }
226
- };
223
+ }
package/lib/publish.js CHANGED
@@ -1,7 +1,8 @@
1
- const execa = require("execa");
2
- const getRegistry = require("@semantic-release/npm/lib/get-registry");
3
- const getChannel = require("@semantic-release/npm/lib/get-channel");
4
- const getReleaseInfo = require("@semantic-release/npm/lib/get-release-info");
1
+ import { createRequire } from "node:module";
2
+ import { execa } from "execa";
3
+ import getRegistry from "@semantic-release/npm/lib/get-registry.js";
4
+ import getChannel from "@semantic-release/npm/lib/get-channel.js";
5
+ import getReleaseInfo from "@semantic-release/npm/lib/get-release-info.js";
5
6
 
6
7
  /**
7
8
  * @param {string} npmrc
@@ -9,7 +10,7 @@ const getReleaseInfo = require("@semantic-release/npm/lib/get-release-info");
9
10
  * @param {any} pkg
10
11
  * @param {any} context
11
12
  */
12
- module.exports = async (npmrc, config, pkg, context) => {
13
+ export default async function (npmrc, config, pkg, context) {
13
14
  const { npmPublish } = config;
14
15
  const {
15
16
  cwd,
@@ -26,14 +27,7 @@ module.exports = async (npmrc, config, pkg, context) => {
26
27
 
27
28
  logger.log("Publishing version %s to npm registry", version);
28
29
 
29
- let legacyAuth = [];
30
- if (env.NPM_USERNAME && env.NPM_PASSWORD && env.NPM_EMAIL) {
31
- legacyAuth = [
32
- "--legacy-auth",
33
- Buffer.from(`${env.NPM_USERNAME}:${env.NPM_PASSWORD}`, "utf8").toString("base64"),
34
- ];
35
- }
36
-
30
+ const require = createRequire(import.meta.url);
37
31
  const lerna = require.resolve("lerna/cli");
38
32
  const result = execa(
39
33
  "node",
@@ -46,7 +40,6 @@ module.exports = async (npmrc, config, pkg, context) => {
46
40
  '--no-verify-access', // prepare step has already verify access and lerna doesn't properly pass authentication
47
41
  '--dist-tag', distTag,
48
42
  '--registry', registry,
49
- ...legacyAuth,
50
43
  ],
51
44
  {
52
45
  cwd,
@@ -68,4 +61,4 @@ module.exports = async (npmrc, config, pkg, context) => {
68
61
  logger.log(`Skip publishing to npm registry as npmPublish false`);
69
62
 
70
63
  return false;
71
- };
64
+ }
@@ -1,7 +1,7 @@
1
- /* eslint-disable security/detect-unsafe-regex */
1
+ /* eslint-disable security/detect-unsafe-regex -- technical debt */
2
2
  const latchMajor = /^\d+\.0\.0$/;
3
3
  const latchMinor = /^\d+\.\d+\.0$/;
4
- const latchPatch = /^\d+\.\d\.\d+$/;
4
+ const latchPatch = /^\d+\.\d+\.\d+$/;
5
5
  const latchPrerelease = /^\d+\.\d+\.\d+(-(.*\.)?\d+)?$/;
6
6
 
7
7
  /**
@@ -11,7 +11,7 @@ const latchPrerelease = /^\d+\.\d+\.\d+(-(.*\.)?\d+)?$/;
11
11
  * @param {"major" | "minor" | "patch" | "prerelease" | "none"} latch
12
12
  * @returns {boolean}
13
13
  */
14
- function shouldLatch(version, latch) {
14
+ export function shouldLatch(version, latch) {
15
15
  switch (latch) {
16
16
  case "major":
17
17
  return latchMajor.test(version);
@@ -25,5 +25,3 @@ function shouldLatch(version, latch) {
25
25
  return false;
26
26
  }
27
27
  }
28
-
29
- module.exports = shouldLatch;
@@ -1,10 +1,10 @@
1
- const execa = require("execa");
2
- const AggregateError = require("aggregate-error");
3
- const getError = require("@semantic-release/npm/lib/get-error");
4
- const getRegistry = require("@semantic-release/npm/lib/get-registry");
5
- const setNpmrcAuth = require("@semantic-release/npm/lib/set-npmrc-auth");
1
+ import { execa } from "execa";
2
+ import AggregateError from "aggregate-error";
3
+ import getError from "@semantic-release/npm/lib/get-error.js";
4
+ import getRegistry from "@semantic-release/npm/lib/get-registry.js";
5
+ import setNpmrcAuth from "@semantic-release/npm/lib/set-npmrc-auth.js";
6
6
 
7
- module.exports = async (npmrc, pkg, context) => {
7
+ export default async function (npmrc, pkg, context) {
8
8
  const { cwd, env, stdout, stderr } = context;
9
9
  const registry = getRegistry(pkg, context);
10
10
 
@@ -21,4 +21,4 @@ module.exports = async (npmrc, pkg, context) => {
21
21
  } catch {
22
22
  throw new AggregateError([getError("EINVALIDNPMTOKEN", { registry })]);
23
23
  }
24
- };
24
+ }
package/lib/verify-git.js CHANGED
@@ -1,5 +1,5 @@
1
- const execa = require("execa");
2
- const getError = require("./get-error");
1
+ import { execa } from "execa";
2
+ import getError from "./get-error.js";
3
3
 
4
4
  async function isDirty({ env }) {
5
5
  const { stdout: wc } = await execa("git", ["status", "--porcelain"], { env });
@@ -12,7 +12,7 @@ const VALIDATORS = {
12
12
  dirtyWc: isDirty,
13
13
  };
14
14
 
15
- async function verifyGit(context) {
15
+ export default async function verifyGit(context) {
16
16
  const result = await Promise.all(
17
17
  Object.entries(VALIDATORS).map(async ([name, validator]) => {
18
18
  const details = await validator(context);
@@ -23,5 +23,3 @@ async function verifyGit(context) {
23
23
  .filter(([, details]) => details)
24
24
  .map(([name, details]) => getError(`E${name.toUpperCase()}`, details));
25
25
  }
26
-
27
- module.exports = verifyGit;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "semantic-release-lerna",
3
- "version": "0.8.0",
3
+ "version": "1.0.0",
4
4
  "description": "semantic-release plugin to publish lerna monorepo packages to npm",
5
5
  "keywords": [
6
6
  "npm",
@@ -25,6 +25,7 @@
25
25
  "Stephan Bönnemann <stephan@boennemann.me> (http://boennemann.me)",
26
26
  "Gregor Martynus (https://twitter.com/gr2m)"
27
27
  ],
28
+ "type": "module",
28
29
  "main": "index.js",
29
30
  "files": [
30
31
  "lib",
@@ -33,8 +34,8 @@
33
34
  ],
34
35
  "scripts": {
35
36
  "codecov": "codecov -f coverage/coverage-final.json",
36
- "eslint": "eslint .",
37
- "eslint:fix": "eslint --fix .",
37
+ "eslint": "eslint --cache .",
38
+ "eslint:fix": "eslint --cache --fix .",
38
39
  "prettier:check": "prettier --check .",
39
40
  "prettier:write": "prettier --write .",
40
41
  "semantic-release": "semantic-release",
@@ -43,7 +44,8 @@
43
44
  },
44
45
  "prettier": "@html-validate/prettier-config",
45
46
  "jest": {
46
- "testTimeout": 10000
47
+ "testTimeout": 30000,
48
+ "transformIgnorePatterns": []
47
49
  },
48
50
  "dependencies": {
49
51
  "@lerna/child-process": "^6.0.0",
@@ -52,44 +54,47 @@
52
54
  "@lerna/package-graph": "^6.0.0",
53
55
  "@lerna/project": "^6.0.0",
54
56
  "@semantic-release/error": "^3.0.0",
55
- "@semantic-release/release-notes-generator": "^10.0.0",
56
- "aggregate-error": "^3.1.0",
57
+ "@semantic-release/release-notes-generator": "^11.0.0",
58
+ "aggregate-error": "^4.0.0",
57
59
  "conventional-changelog-writer": "^5.0.0",
58
60
  "conventional-commits-filter": "^2.0.0",
59
61
  "conventional-commits-parser": "^3.2.0",
60
62
  "debug": "^4.3.0",
61
- "execa": "^5.0.0",
63
+ "execa": "^7.0.0",
62
64
  "get-stream": "^6.0.0",
63
- "into-stream": "^6.0.0",
65
+ "into-stream": "^7.0.0",
64
66
  "libnpmversion": "^4.0.0",
65
- "read-pkg-up": "^7.0.0",
67
+ "read-pkg-up": "^9.0.0",
66
68
  "semver": "^7.0.0",
67
- "tempy": "^1.0.0",
68
- "write-json-file": "^4.0.0"
69
+ "tempy": "^3.0.0",
70
+ "write-json-file": "^5.0.0"
69
71
  },
70
72
  "devDependencies": {
71
- "@html-validate/eslint-config": "5.5.22",
72
- "@html-validate/eslint-config-jest": "5.5.18",
73
- "@html-validate/prettier-config": "2.3.4",
74
- "@semantic-release/npm": "9.0.2",
75
- "@types/jest": "29.4.0",
73
+ "@babel/core": "7.21.8",
74
+ "@babel/preset-env": "7.21.5",
75
+ "@html-validate/eslint-config": "5.9.4",
76
+ "@html-validate/eslint-config-jest": "5.9.0",
77
+ "@html-validate/prettier-config": "2.3.10",
78
+ "@semantic-release/npm": "10.0.3",
79
+ "@types/jest": "29.5.1",
80
+ "babel-plugin-transform-import-meta": "2.2.0",
76
81
  "codecov": "3.8.3",
77
- "fs-extra": "11.1.0",
78
- "got": "11.8.6",
79
- "jest": "29.4.2",
80
- "lerna": "6.4.1",
81
- "prettier": "2.8.4",
82
- "semantic-release": "20.1.0",
82
+ "fs-extra": "11.1.1",
83
+ "jest": "29.5.0",
84
+ "lerna": "6.6.2",
85
+ "npm-pkg-lint": "1.14.1",
86
+ "prettier": "2.8.8",
87
+ "semantic-release": "21.0.2",
83
88
  "stream-buffers": "3.0.2",
84
- "verdaccio": "5.19.1"
89
+ "verdaccio": "5.24.1"
85
90
  },
86
91
  "peerDependencies": {
87
- "@semantic-release/npm": ">= 7",
92
+ "@semantic-release/npm": ">= 10",
88
93
  "lerna": "^3.2 || ^4 || ^5 || ^6",
89
- "semantic-release": ">=15.0.0 <21.0.0"
94
+ "semantic-release": "^20.1 || 21"
90
95
  },
91
96
  "engines": {
92
- "node": ">= 14"
97
+ "node": ">= 18"
93
98
  },
94
99
  "publishConfig": {
95
100
  "access": "public"
@@ -1,477 +0,0 @@
1
- /* eslint-env jest */
2
- const path = require("path");
3
- const { outputJson, readJson } = require("fs-extra");
4
- const tempy = require("tempy");
5
- const execa = require("execa");
6
- const { WritableStreamBuffer } = require("stream-buffers");
7
- const prepare = require("./prepare");
8
-
9
- let context;
10
- let mockChangedPackages;
11
-
12
- jest.mock("../lib/get-changed-packages", () => {
13
- function getChangedPackagesMock() {
14
- return mockChangedPackages;
15
- }
16
-
17
- return getChangedPackagesMock;
18
- });
19
-
20
- async function createProject(cwd, version, pkgData) {
21
- const lernaPath = path.resolve(cwd, "lerna.json");
22
- const manifestLocation = path.resolve(cwd, "package.json");
23
- await outputJson(lernaPath, { version, packages: ["packages/*"] });
24
- await outputJson(manifestLocation, { name: "root-pkg", version, ...pkgData });
25
- return {
26
- lernaPath,
27
- manifestLocation,
28
- };
29
- }
30
-
31
- /* eslint-disable-next-line max-params */
32
- async function createPackage(cwd, name, version, options, pkgData) {
33
- const { changed = false } = options;
34
- const pkgRoot = `packages/${name}`;
35
- const location = path.resolve(cwd, pkgRoot);
36
- const manifestLocation = path.resolve(cwd, pkgRoot, "package.json");
37
- const pkg = {
38
- name,
39
- location,
40
- manifestLocation,
41
- shrinkwrapPath: path.resolve(cwd, pkgRoot, "npm-shrinkwrap.json"),
42
- lockfilePath: path.resolve(cwd, pkgRoot, "package-lock.json"),
43
- };
44
- await outputJson(manifestLocation, { name, version, ...pkgData });
45
- if (changed) {
46
- mockChangedPackages.push(pkg);
47
- }
48
-
49
- return pkg;
50
- }
51
-
52
- beforeEach(() => {
53
- const log = jest.fn();
54
- context = {
55
- log,
56
- logger: { log },
57
- stdout: new WritableStreamBuffer(),
58
- stderr: new WritableStreamBuffer(),
59
- };
60
- mockChangedPackages = [];
61
- });
62
-
63
- it("Update lerna.json and root package.json when no package has changed", async () => {
64
- expect.assertions(4);
65
- const cwd = tempy.directory();
66
- const npmrc = tempy.file({ name: ".npmrc" });
67
- const project = await createProject(cwd, "0.0.0");
68
-
69
- await prepare(
70
- npmrc,
71
- {},
72
- {
73
- cwd,
74
- env: {},
75
- stdout: context.stdout,
76
- stderr: context.stderr,
77
- nextRelease: { version: "1.0.0" },
78
- logger: context.logger,
79
- }
80
- );
81
-
82
- // Verify lerna.json has been updated
83
- expect(await readJson(project.lernaPath)).toEqual(
84
- expect.objectContaining({
85
- version: "1.0.0",
86
- })
87
- );
88
-
89
- // Verify root package.json has been updated
90
- expect(await readJson(project.manifestLocation)).toEqual(
91
- expect.objectContaining({
92
- version: "1.0.0",
93
- })
94
- );
95
-
96
- // Verify the logger has been called with the version updated
97
- expect(context.log).toHaveBeenCalledWith(
98
- "No packages changed, applying version bump on root package only"
99
- );
100
- expect(context.log).toHaveBeenCalledWith("Write version %s to lerna.json in %s", "1.0.0", cwd);
101
- });
102
-
103
- it("Update lerna.json and root package.json when one or more package has changed", async () => {
104
- expect.assertions(5);
105
- const cwd = tempy.directory();
106
- const npmrc = tempy.file({ name: ".npmrc" });
107
- const project = await createProject(cwd, "0.0.0");
108
- const pkg = await createPackage(cwd, "foo", "0.0.0", {
109
- changed: true,
110
- });
111
-
112
- await prepare(
113
- npmrc,
114
- {},
115
- {
116
- cwd,
117
- env: {},
118
- stdout: context.stdout,
119
- stderr: context.stderr,
120
- nextRelease: { version: "1.0.0" },
121
- logger: context.logger,
122
- }
123
- );
124
-
125
- // Verify lerna.json has been updated
126
- expect(await readJson(project.lernaPath)).toEqual(
127
- expect.objectContaining({
128
- version: "1.0.0",
129
- })
130
- );
131
-
132
- // Verify package.json has been updated
133
- expect(await readJson(project.manifestLocation)).toEqual(
134
- expect.objectContaining({
135
- version: "1.0.0",
136
- })
137
- );
138
-
139
- // Verify the logger has been called with the version updated
140
- expect(context.log).toHaveBeenCalledWith("1 package need version bump: [ 'foo' ]");
141
- expect(context.log).toHaveBeenCalledWith(
142
- "Write version %s to package.json in %s",
143
- "1.0.0",
144
- pkg.location
145
- );
146
- expect(context.log).toHaveBeenCalledWith("Write version %s to lerna.json in %s", "1.0.0", cwd);
147
- });
148
-
149
- it("Update only lerna.json when one or more package has changed when option `rootVersion` is `false`", async () => {
150
- expect.assertions(4);
151
- const cwd = tempy.directory();
152
- const npmrc = tempy.file({ name: ".npmrc" });
153
- const project = await createProject(cwd, "0.0.0");
154
-
155
- await createPackage(cwd, "foo", "0.0.0", {
156
- changed: true,
157
- });
158
-
159
- await prepare(
160
- npmrc,
161
- {
162
- rootVersion: false,
163
- },
164
- {
165
- cwd,
166
- env: {},
167
- stdout: context.stdout,
168
- stderr: context.stderr,
169
- nextRelease: { version: "1.0.0" },
170
- logger: context.logger,
171
- }
172
- );
173
-
174
- // Verify lerna.json has been updated
175
- expect(await readJson(project.lernaPath)).toEqual(
176
- expect.objectContaining({
177
- version: "1.0.0",
178
- })
179
- );
180
-
181
- // Verify the logger has been called with the version updated
182
- expect(context.log).toHaveBeenCalledWith("1 package need version bump: [ 'foo' ]");
183
- expect(context.log).toHaveBeenCalledWith("Write version %s to lerna.json in %s", "1.0.0", cwd);
184
- expect(context.log).toHaveBeenCalledWith("Don't write version to root package.json");
185
- });
186
-
187
- it("Update package.json in changed packages", async () => {
188
- expect.assertions(2);
189
- const cwd = tempy.directory();
190
- const npmrc = tempy.file({ name: ".npmrc" });
191
- await createProject(cwd, "0.0.0");
192
- const foo = await createPackage(cwd, "foo", "0.0.0", {
193
- changed: true,
194
- });
195
- const bar = await createPackage(cwd, "bar", "0.0.0", {
196
- changed: false,
197
- });
198
-
199
- await prepare(
200
- npmrc,
201
- {},
202
- {
203
- cwd,
204
- env: {},
205
- stdout: context.stdout,
206
- stderr: context.stderr,
207
- nextRelease: { version: "1.0.0" },
208
- logger: context.logger,
209
- }
210
- );
211
-
212
- // Verify foo/package.json has been updated
213
- expect(await readJson(foo.manifestLocation)).toEqual({
214
- name: "foo",
215
- version: "1.0.0",
216
- });
217
-
218
- // Verify bar/package.json has not been updated
219
- expect(await readJson(bar.manifestLocation)).toEqual({
220
- name: "bar",
221
- version: "0.0.0",
222
- });
223
- });
224
-
225
- it("Update npm-shrinkwrap.json if present", async () => {
226
- expect.assertions(2);
227
- const cwd = tempy.directory();
228
- const npmrc = tempy.file({ name: ".npmrc" });
229
- await createProject(cwd, "0.0.0");
230
- const pkg = await createPackage(cwd, "foo", "0.0.0", {
231
- changed: true,
232
- });
233
- // Create a npm-shrinkwrap.json file
234
- await execa("npm", ["shrinkwrap"], { cwd: pkg.location });
235
-
236
- await prepare(
237
- npmrc,
238
- {},
239
- {
240
- cwd,
241
- env: {},
242
- stdout: context.stdout,
243
- stderr: context.stderr,
244
- nextRelease: { version: "1.0.0" },
245
- logger: context.logger,
246
- }
247
- );
248
-
249
- // Verify foo/package.json has been updated
250
- expect(await readJson(pkg.manifestLocation)).toEqual({
251
- name: "foo",
252
- version: "1.0.0",
253
- });
254
-
255
- // Verify foo/npm-shrinkwrap.json has been updated
256
- expect(await readJson(pkg.shrinkwrapPath)).toEqual(
257
- expect.objectContaining({
258
- lockfileVersion: expect.anything(),
259
- name: "foo",
260
- version: "1.0.0",
261
- })
262
- );
263
- });
264
-
265
- it("Update package-lock.json if present", async () => {
266
- expect.assertions(2);
267
- const cwd = tempy.directory();
268
- const npmrc = tempy.file({ name: ".npmrc" });
269
- await createProject(cwd, "0.0.0");
270
- const pkg = await createPackage(cwd, "foo", "0.0.0", {
271
- changed: true,
272
- });
273
- // Create a package-lock.json file
274
- await execa("npm", ["install"], { cwd: pkg.location });
275
-
276
- await prepare(
277
- npmrc,
278
- {},
279
- {
280
- cwd,
281
- env: {},
282
- stdout: context.stdout,
283
- stderr: context.stderr,
284
- nextRelease: { version: "1.0.0" },
285
- logger: context.logger,
286
- }
287
- );
288
-
289
- // Verify foo/package.json has been updated
290
- expect(await readJson(pkg.manifestLocation)).toEqual({
291
- name: "foo",
292
- version: "1.0.0",
293
- });
294
-
295
- // Verify foo/package-lock.json has been updated
296
- expect(await readJson(pkg.lockfilePath)).toEqual(
297
- expect.objectContaining({
298
- lockfileVersion: expect.anything(),
299
- name: "foo",
300
- version: "1.0.0",
301
- })
302
- );
303
- });
304
-
305
- it("Update package.json dependency when using exact version", async () => {
306
- expect.assertions(1);
307
- const cwd = tempy.directory();
308
- const npmrc = tempy.file({ name: ".npmrc" });
309
- await createProject(cwd, "0.0.0");
310
- const foo = await createPackage(
311
- cwd,
312
- "foo",
313
- "0.0.0",
314
- {
315
- changed: true,
316
- },
317
- {
318
- dependencies: {
319
- a: "0.0.0",
320
- },
321
- devDependencies: {
322
- b: "0.0.0",
323
- },
324
- peerDependencies: {
325
- c: "0.0.0",
326
- },
327
- }
328
- );
329
- await createPackage(cwd, "a", "0.0.0", { changed: true });
330
- await createPackage(cwd, "b", "0.0.0", { changed: true });
331
- await createPackage(cwd, "c", "0.0.0", { changed: true });
332
-
333
- await prepare(
334
- npmrc,
335
- {},
336
- {
337
- cwd,
338
- env: {},
339
- stdout: context.stdout,
340
- stderr: context.stderr,
341
- nextRelease: { version: "0.0.1" },
342
- logger: context.logger,
343
- }
344
- );
345
-
346
- // Verify dependency has been updated
347
- expect(await readJson(foo.manifestLocation)).toEqual({
348
- name: "foo",
349
- version: "0.0.1",
350
- dependencies: {
351
- a: "0.0.1",
352
- },
353
- devDependencies: {
354
- b: "0.0.1",
355
- },
356
- peerDependencies: {
357
- c: "0.0.1",
358
- },
359
- });
360
- });
361
-
362
- it("Update package.json dependency when using hat", async () => {
363
- expect.assertions(1);
364
- const cwd = tempy.directory();
365
- const npmrc = tempy.file({ name: ".npmrc" });
366
- await createProject(cwd, "0.1.2");
367
- const foo = await createPackage(
368
- cwd,
369
- "foo",
370
- "0.1.2",
371
- {
372
- changed: true,
373
- },
374
- {
375
- dependencies: {
376
- a: "^0.1.2",
377
- b: "^0.1",
378
- c: "^0",
379
- },
380
- }
381
- );
382
-
383
- await createPackage(cwd, "a", "0.1.2", { changed: true });
384
- await createPackage(cwd, "b", "0.1.2", { changed: true });
385
- await createPackage(cwd, "c", "0.1.2", { changed: true });
386
-
387
- await prepare(
388
- npmrc,
389
- {},
390
- {
391
- cwd,
392
- env: {},
393
- stdout: context.stdout,
394
- stderr: context.stderr,
395
- nextRelease: { version: "1.0.0" },
396
- logger: context.logger,
397
- }
398
- );
399
-
400
- // Verify dependency has been updated
401
- expect(await readJson(foo.manifestLocation)).toEqual({
402
- name: "foo",
403
- version: "1.0.0",
404
- dependencies: {
405
- a: "^1.0.0",
406
- b: "^1.0",
407
- c: "^1",
408
- },
409
- });
410
- });
411
-
412
- it("Should not update other dependencies", async () => {
413
- expect.assertions(1);
414
- const cwd = tempy.directory();
415
- const npmrc = tempy.file({ name: ".npmrc" });
416
- await createProject(cwd, "0.0.0");
417
- const foo = await createPackage(
418
- cwd,
419
- "foo",
420
- "0.0.0",
421
- {
422
- changed: true,
423
- },
424
- {
425
- dependencies: {
426
- a: "0.0.0",
427
- },
428
- }
429
- );
430
-
431
- await prepare(
432
- npmrc,
433
- {},
434
- {
435
- cwd,
436
- env: {},
437
- stdout: context.stdout,
438
- stderr: context.stderr,
439
- nextRelease: { version: "0.0.1" },
440
- logger: context.logger,
441
- }
442
- );
443
-
444
- // Verify dependency has been updated
445
- expect(await readJson(foo.manifestLocation)).toEqual({
446
- name: "foo",
447
- version: "0.0.1",
448
- dependencies: {
449
- a: "0.0.0",
450
- },
451
- });
452
- });
453
-
454
- it("Handle dependencies from root package", async () => {
455
- expect.assertions(1);
456
- const cwd = tempy.directory();
457
- const npmrc = tempy.file({ name: ".npmrc" });
458
- await createProject(cwd, "0.0.1", {
459
- devDependencies: {
460
- "external-dependency": "1.2.3",
461
- },
462
- });
463
- expect(async () => {
464
- await prepare(
465
- npmrc,
466
- {},
467
- {
468
- cwd,
469
- env: {},
470
- stdout: context.stdout,
471
- stderr: context.stderr,
472
- nextRelease: { version: "0.0.2" },
473
- logger: context.logger,
474
- }
475
- );
476
- }).not.toThrow();
477
- });
@@ -1,71 +0,0 @@
1
- /* eslint-env jest */
2
-
3
- const semver = require("semver");
4
- const shouldLatch = require("./should-latch");
5
-
6
- const version = "1.0.0";
7
-
8
- describe("latch none", () => {
9
- it.each`
10
- bump | result | version | next
11
- ${"major"} | ${false} | ${version} | ${semver.inc(version, "major")}
12
- ${"minor"} | ${false} | ${version} | ${semver.inc(version, "minor")}
13
- ${"patch"} | ${false} | ${version} | ${semver.inc(version, "patch")}
14
- ${"prerelease"} | ${false} | ${version} | ${semver.inc(version, "prerelease")}
15
- `("should return $result when version bump is $bump ($version -> $next)", ({ result, next }) => {
16
- expect.assertions(1);
17
- expect(shouldLatch(next, "none")).toBe(result);
18
- });
19
- });
20
-
21
- describe("latch major", () => {
22
- it.each`
23
- bump | result | version | next
24
- ${"major"} | ${true} | ${version} | ${semver.inc(version, "major")}
25
- ${"minor"} | ${false} | ${version} | ${semver.inc(version, "minor")}
26
- ${"patch"} | ${false} | ${version} | ${semver.inc(version, "patch")}
27
- ${"prerelease"} | ${false} | ${version} | ${semver.inc(version, "prerelease")}
28
- `("should return $result when version bump is $bump ($version -> $next)", ({ result, next }) => {
29
- expect.assertions(1);
30
- expect(shouldLatch(next, "major")).toBe(result);
31
- });
32
- });
33
-
34
- describe("latch minor", () => {
35
- it.each`
36
- bump | result | version | next
37
- ${"major"} | ${true} | ${version} | ${semver.inc(version, "major")}
38
- ${"minor"} | ${true} | ${version} | ${semver.inc(version, "minor")}
39
- ${"patch"} | ${false} | ${version} | ${semver.inc(version, "patch")}
40
- ${"prerelease"} | ${false} | ${version} | ${semver.inc(version, "prerelease")}
41
- `("should return $result when version bump is $bump ($version -> $next)", ({ result, next }) => {
42
- expect.assertions(1);
43
- expect(shouldLatch(next, "minor")).toBe(result);
44
- });
45
- });
46
-
47
- describe("latch patch", () => {
48
- it.each`
49
- bump | result | version | next
50
- ${"major"} | ${true} | ${version} | ${semver.inc(version, "major")}
51
- ${"minor"} | ${true} | ${version} | ${semver.inc(version, "minor")}
52
- ${"patch"} | ${true} | ${version} | ${semver.inc(version, "patch")}
53
- ${"prerelease"} | ${false} | ${version} | ${semver.inc(version, "prerelease")}
54
- `("should return $result when version bump is $bump ($version -> $next)", ({ result, next }) => {
55
- expect.assertions(1);
56
- expect(shouldLatch(next, "patch")).toBe(result);
57
- });
58
- });
59
-
60
- describe("latch prerelease", () => {
61
- it.each`
62
- bump | result | version | next
63
- ${"major"} | ${true} | ${version} | ${semver.inc(version, "major")}
64
- ${"minor"} | ${true} | ${version} | ${semver.inc(version, "minor")}
65
- ${"patch"} | ${true} | ${version} | ${semver.inc(version, "patch")}
66
- ${"prerelease"} | ${true} | ${version} | ${semver.inc(version, "prerelease")}
67
- `("should return $result when version bump is $bump ($version -> $next)", ({ result, next }) => {
68
- expect.assertions(1);
69
- expect(shouldLatch(next, "prerelease")).toBe(result);
70
- });
71
- });
@@ -1,49 +0,0 @@
1
- /* eslint-env jest */
2
-
3
- jest.mock("execa");
4
-
5
- const execa = require("execa");
6
- const verifyGit = require("./verify-git");
7
-
8
- it("should return error if working copy is dirty", async () => {
9
- expect.assertions(2);
10
- execa.mockImplementation(() => ({ stdout: " M file.js\n" }));
11
- const errors = await verifyGit({});
12
- expect(errors).toHaveLength(1);
13
- expect(errors[0]).toMatchObject({
14
- code: "EDIRTYWC",
15
- details: `The git working copy must be clean before releasing:
16
-
17
- M file.js
18
- `,
19
- });
20
- });
21
-
22
- it("should return error when working copy has mixed dirty and untracked", async () => {
23
- expect.assertions(2);
24
- execa.mockImplementation(() => ({ stdout: " M file.js\n?? file.c" }));
25
- const errors = await verifyGit({});
26
- expect(errors).toHaveLength(1);
27
- expect(errors[0]).toMatchObject({
28
- code: "EDIRTYWC",
29
- details: `The git working copy must be clean before releasing:
30
-
31
- M file.js
32
- ?? file.c
33
- `,
34
- });
35
- });
36
-
37
- it("should ignore untracked files", async () => {
38
- expect.assertions(1);
39
- execa.mockImplementation(() => ({ stdout: "?? file.js\n" }));
40
- const errors = await verifyGit({});
41
- expect(errors).toHaveLength(0);
42
- });
43
-
44
- it("should not return error if working copy is clean", async () => {
45
- expect.assertions(1);
46
- execa.mockImplementation(() => ({ stdout: "" }));
47
- const errors = await verifyGit({});
48
- expect(errors).toHaveLength(0);
49
- });