fix(deps): bump @semantic-release/npm to ^10.0.0-beta.1 (#2670)
This commit is contained in:
@@ -1,18 +1,18 @@
|
||||
import {isString, mapValues, omit, remove, template} from 'lodash-es';
|
||||
import micromatch from 'micromatch';
|
||||
import {getBranches} from '../git.js';
|
||||
import { isString, mapValues, omit, remove, template } from "lodash-es";
|
||||
import micromatch from "micromatch";
|
||||
import { getBranches } from "../git.js";
|
||||
|
||||
export default async (repositoryUrl, {cwd}, branches) => {
|
||||
const gitBranches = await getBranches(repositoryUrl, {cwd});
|
||||
export default async (repositoryUrl, { cwd }, branches) => {
|
||||
const gitBranches = await getBranches(repositoryUrl, { cwd });
|
||||
|
||||
return branches.reduce(
|
||||
(branches, branch) => [
|
||||
...branches,
|
||||
...remove(gitBranches, (name) => micromatch(gitBranches, branch.name).includes(name)).map((name) => ({
|
||||
name,
|
||||
...mapValues(omit(branch, 'name'), (value) => (isString(value) ? template(value)({name}) : value)),
|
||||
...mapValues(omit(branch, "name"), (value) => (isString(value) ? template(value)({ name }) : value)),
|
||||
})),
|
||||
],
|
||||
[]
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
+13
-14
@@ -1,36 +1,35 @@
|
||||
import {escapeRegExp, template} from 'lodash-es';
|
||||
import semver from 'semver';
|
||||
import pReduce from 'p-reduce';
|
||||
import debugTags from 'debug';
|
||||
import {getNote, getTags} from '../../lib/git.js';
|
||||
import { escapeRegExp, template } from "lodash-es";
|
||||
import semver from "semver";
|
||||
import pReduce from "p-reduce";
|
||||
import debugTags from "debug";
|
||||
import { getNote, getTags } from "../../lib/git.js";
|
||||
|
||||
const debug = debugTags('semantic-release:get-tags');
|
||||
const debug = debugTags("semantic-release:get-tags");
|
||||
|
||||
|
||||
export default async ({cwd, env, options: {tagFormat}}, branches) => {
|
||||
export default async ({ cwd, env, options: { tagFormat } }, branches) => {
|
||||
// Generate a regex to parse tags formatted with `tagFormat`
|
||||
// by replacing the `version` variable in the template by `(.+)`.
|
||||
// The `tagFormat` is compiled with space as the `version` as it's an invalid tag character,
|
||||
// so it's guaranteed to no be present in the `tagFormat`.
|
||||
const tagRegexp = `^${escapeRegExp(template(tagFormat)({version: ' '})).replace(' ', '(.+)')}`;
|
||||
const tagRegexp = `^${escapeRegExp(template(tagFormat)({ version: " " })).replace(" ", "(.+)")}`;
|
||||
|
||||
return pReduce(
|
||||
branches,
|
||||
async (branches, branch) => {
|
||||
const branchTags = await pReduce(
|
||||
await getTags(branch.name, {cwd, env}),
|
||||
await getTags(branch.name, { cwd, env }),
|
||||
async (branchTags, tag) => {
|
||||
const [, version] = tag.match(tagRegexp) || [];
|
||||
return version && semver.valid(semver.clean(version))
|
||||
? [...branchTags, {gitTag: tag, version, channels: (await getNote(tag, {cwd, env})).channels || [null]}]
|
||||
? [...branchTags, { gitTag: tag, version, channels: (await getNote(tag, { cwd, env })).channels || [null] }]
|
||||
: branchTags;
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
debug('found tags for branch %s: %o', branch.name, branchTags);
|
||||
return [...branches, {...branch, tags: branchTags}];
|
||||
debug("found tags for branch %s: %o", branch.name, branchTags);
|
||||
return [...branches, { ...branch, tags: branchTags }];
|
||||
},
|
||||
[]
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
+22
-22
@@ -1,51 +1,51 @@
|
||||
import {isRegExp, isString} from 'lodash-es';
|
||||
import AggregateError from 'aggregate-error';
|
||||
import pEachSeries from 'p-each-series';
|
||||
import * as DEFINITIONS from '../definitions/branches.js';
|
||||
import getError from '../get-error.js';
|
||||
import {fetch, fetchNotes, verifyBranchName} from '../git.js';
|
||||
import expand from './expand.js';
|
||||
import getTags from './get-tags.js';
|
||||
import * as normalize from './normalize.js';
|
||||
import { isRegExp, isString } from "lodash-es";
|
||||
import AggregateError from "aggregate-error";
|
||||
import pEachSeries from "p-each-series";
|
||||
import * as DEFINITIONS from "../definitions/branches.js";
|
||||
import getError from "../get-error.js";
|
||||
import { fetch, fetchNotes, verifyBranchName } from "../git.js";
|
||||
import expand from "./expand.js";
|
||||
import getTags from "./get-tags.js";
|
||||
import * as normalize from "./normalize.js";
|
||||
|
||||
export default async (repositoryUrl, ciBranch, context) => {
|
||||
const {cwd, env} = context;
|
||||
const { cwd, env } = context;
|
||||
|
||||
const remoteBranches = await expand(
|
||||
repositoryUrl,
|
||||
context,
|
||||
context.options.branches.map((branch) => (isString(branch) || isRegExp(branch) ? {name: branch} : branch))
|
||||
context.options.branches.map((branch) => (isString(branch) || isRegExp(branch) ? { name: branch } : branch))
|
||||
);
|
||||
|
||||
await pEachSeries(remoteBranches, async ({name}) => {
|
||||
await fetch(repositoryUrl, name, ciBranch, {cwd, env});
|
||||
await pEachSeries(remoteBranches, async ({ name }) => {
|
||||
await fetch(repositoryUrl, name, ciBranch, { cwd, env });
|
||||
});
|
||||
|
||||
await fetchNotes(repositoryUrl, {cwd, env});
|
||||
await fetchNotes(repositoryUrl, { cwd, env });
|
||||
|
||||
const branches = await getTags(context, remoteBranches);
|
||||
|
||||
const errors = [];
|
||||
const branchesByType = Object.entries(DEFINITIONS).reduce(
|
||||
// eslint-disable-next-line unicorn/no-fn-reference-in-iterator
|
||||
(branchesByType, [type, {filter}]) => ({[type]: branches.filter(filter), ...branchesByType}),
|
||||
(branchesByType, [type, { filter }]) => ({ [type]: branches.filter(filter), ...branchesByType }),
|
||||
{}
|
||||
);
|
||||
|
||||
const result = Object.entries(DEFINITIONS).reduce((result, [type, {branchesValidator, branchValidator}]) => {
|
||||
const result = Object.entries(DEFINITIONS).reduce((result, [type, { branchesValidator, branchValidator }]) => {
|
||||
branchesByType[type].forEach((branch) => {
|
||||
if (branchValidator && !branchValidator(branch)) {
|
||||
errors.push(getError(`E${type.toUpperCase()}BRANCH`, {branch}));
|
||||
errors.push(getError(`E${type.toUpperCase()}BRANCH`, { branch }));
|
||||
}
|
||||
});
|
||||
|
||||
const branchesOfType = normalize[type](branchesByType);
|
||||
|
||||
if (!branchesValidator(branchesOfType)) {
|
||||
errors.push(getError(`E${type.toUpperCase()}BRANCHES`, {branches: branchesOfType}));
|
||||
errors.push(getError(`E${type.toUpperCase()}BRANCHES`, { branches: branchesOfType }));
|
||||
}
|
||||
|
||||
return {...result, [type]: branchesOfType};
|
||||
return { ...result, [type]: branchesOfType };
|
||||
}, {});
|
||||
|
||||
const duplicates = [...branches]
|
||||
@@ -54,12 +54,12 @@ export default async (repositoryUrl, ciBranch, context) => {
|
||||
.filter((_, idx, array) => array[idx] === array[idx + 1] && array[idx] !== array[idx - 1]);
|
||||
|
||||
if (duplicates.length > 0) {
|
||||
errors.push(getError('EDUPLICATEBRANCHES', {duplicates}));
|
||||
errors.push(getError("EDUPLICATEBRANCHES", { duplicates }));
|
||||
}
|
||||
|
||||
await pEachSeries(branches, async (branch) => {
|
||||
if (!(await verifyBranchName(branch.name))) {
|
||||
errors.push(getError('EINVALIDBRANCHNAME', branch));
|
||||
errors.push(getError("EINVALIDBRANCHNAME", branch));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -68,4 +68,4 @@ export default async (repositoryUrl, ciBranch, context) => {
|
||||
}
|
||||
|
||||
return [...result.maintenance, ...result.release, ...result.prerelease];
|
||||
}
|
||||
};
|
||||
|
||||
+18
-17
@@ -1,27 +1,28 @@
|
||||
import {isNil, sortBy} from 'lodash-es';
|
||||
import semverDiff from 'semver-diff';
|
||||
import {FIRST_RELEASE, RELEASE_TYPE} from '../definitions/constants.js';
|
||||
import { isNil, sortBy } from "lodash-es";
|
||||
import semverDiff from "semver-diff";
|
||||
import { FIRST_RELEASE, RELEASE_TYPE } from "../definitions/constants.js";
|
||||
import {
|
||||
getFirstVersion,
|
||||
getLatestVersion,
|
||||
getLowerBound, getRange,
|
||||
getLowerBound,
|
||||
getRange,
|
||||
getUpperBound,
|
||||
highest,
|
||||
isMajorRange,
|
||||
lowest,
|
||||
tagsToVersions
|
||||
} from '../utils.js';
|
||||
tagsToVersions,
|
||||
} from "../utils.js";
|
||||
|
||||
export function maintenance({maintenance, release}) {
|
||||
export function maintenance({ maintenance, release }) {
|
||||
return sortBy(
|
||||
maintenance.map(({name, range, channel, ...rest}) => ({
|
||||
maintenance.map(({ name, range, channel, ...rest }) => ({
|
||||
...rest,
|
||||
name,
|
||||
range: range || name,
|
||||
channel: isNil(channel) ? name : channel,
|
||||
})),
|
||||
'range'
|
||||
).map(({name, range, tags, ...rest}, idx, branches) => {
|
||||
"range"
|
||||
).map(({ name, range, tags, ...rest }, idx, branches) => {
|
||||
const versions = tagsToVersions(tags);
|
||||
// Find the lower bound based on Maintenance branches
|
||||
const maintenanceMin =
|
||||
@@ -44,7 +45,7 @@ export function maintenance({maintenance, release}) {
|
||||
const diff = semverDiff(min, max);
|
||||
return {
|
||||
...rest,
|
||||
type: 'maintenance',
|
||||
type: "maintenance",
|
||||
name,
|
||||
tags,
|
||||
range: getRange(min, max),
|
||||
@@ -54,7 +55,7 @@ export function maintenance({maintenance, release}) {
|
||||
});
|
||||
}
|
||||
|
||||
export function release({release}) {
|
||||
export function release({ release }) {
|
||||
if (release.length === 0) {
|
||||
return release;
|
||||
}
|
||||
@@ -62,7 +63,7 @@ export function release({release}) {
|
||||
// The intial lastVersion is the last release from the base branch of `FIRST_RELEASE` (1.0.0)
|
||||
let lastVersion = getLatestVersion(tagsToVersions(release[0].tags)) || FIRST_RELEASE;
|
||||
|
||||
return release.map(({name, tags, channel, ...rest}, idx) => {
|
||||
return release.map(({ name, tags, channel, ...rest }, idx) => {
|
||||
const versions = tagsToVersions(tags);
|
||||
// The new lastVersion is the highest version between the current branch last release and the previous branch lastVersion
|
||||
lastVersion = highest(getLatestVersion(versions), lastVersion);
|
||||
@@ -79,7 +80,7 @@ export function release({release}) {
|
||||
...rest,
|
||||
channel: idx === 0 ? channel : isNil(channel) ? name : channel,
|
||||
tags,
|
||||
type: 'release',
|
||||
type: "release",
|
||||
name,
|
||||
range: getRange(lastVersion, bound),
|
||||
accept: bound ? RELEASE_TYPE.slice(0, RELEASE_TYPE.indexOf(diff)) : RELEASE_TYPE,
|
||||
@@ -88,13 +89,13 @@ export function release({release}) {
|
||||
});
|
||||
}
|
||||
|
||||
export function prerelease({prerelease}) {
|
||||
return prerelease.map(({name, prerelease, channel, tags, ...rest}) => {
|
||||
export function prerelease({ prerelease }) {
|
||||
return prerelease.map(({ name, prerelease, channel, tags, ...rest }) => {
|
||||
const preid = prerelease === true ? name : prerelease;
|
||||
return {
|
||||
...rest,
|
||||
channel: isNil(channel) ? name : channel,
|
||||
type: 'prerelease',
|
||||
type: "prerelease",
|
||||
name,
|
||||
prerelease: preid,
|
||||
tags,
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import {isNil, uniqBy} from 'lodash-es';
|
||||
import semver from 'semver';
|
||||
import {isMaintenanceRange} from '../utils.js';
|
||||
import { isNil, uniqBy } from "lodash-es";
|
||||
import semver from "semver";
|
||||
import { isMaintenanceRange } from "../utils.js";
|
||||
|
||||
export const maintenance = {
|
||||
filter: ({name, range}) => (!isNil(range) && range !== false) || isMaintenanceRange(name),
|
||||
branchValidator: ({range}) => (isNil(range) ? true : isMaintenanceRange(range)),
|
||||
branchesValidator: (branches) => uniqBy(branches, ({range}) => semver.validRange(range)).length === branches.length,
|
||||
filter: ({ name, range }) => (!isNil(range) && range !== false) || isMaintenanceRange(name),
|
||||
branchValidator: ({ range }) => (isNil(range) ? true : isMaintenanceRange(range)),
|
||||
branchesValidator: (branches) => uniqBy(branches, ({ range }) => semver.validRange(range)).length === branches.length,
|
||||
};
|
||||
|
||||
export const prerelease = {
|
||||
filter: ({prerelease}) => !isNil(prerelease) && prerelease !== false,
|
||||
branchValidator: ({name, prerelease}) =>
|
||||
filter: ({ prerelease }) => !isNil(prerelease) && prerelease !== false,
|
||||
branchValidator: ({ name, prerelease }) =>
|
||||
Boolean(prerelease) && Boolean(semver.valid(`1.0.0-${prerelease === true ? name : prerelease}.1`)),
|
||||
branchesValidator: (branches) => uniqBy(branches, 'prerelease').length === branches.length,
|
||||
branchesValidator: (branches) => uniqBy(branches, "prerelease").length === branches.length,
|
||||
};
|
||||
|
||||
export const release = {
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
export const RELEASE_TYPE = ['patch', 'minor', 'major'];
|
||||
export const RELEASE_TYPE = ["patch", "minor", "major"];
|
||||
|
||||
export const FIRST_RELEASE = '1.0.0';
|
||||
export const FIRST_RELEASE = "1.0.0";
|
||||
|
||||
export const FIRSTPRERELEASE = '1';
|
||||
export const FIRSTPRERELEASE = "1";
|
||||
|
||||
export const COMMIT_NAME = 'semantic-release-bot';
|
||||
export const COMMIT_NAME = "semantic-release-bot";
|
||||
|
||||
export const COMMIT_EMAIL = 'semantic-release-bot@martynus.net';
|
||||
export const COMMIT_EMAIL = "semantic-release-bot@martynus.net";
|
||||
|
||||
export const RELEASE_NOTES_SEPARATOR = '\n\n';
|
||||
export const RELEASE_NOTES_SEPARATOR = "\n\n";
|
||||
|
||||
export const SECRET_REPLACEMENT = '[secure]';
|
||||
export const SECRET_REPLACEMENT = "[secure]";
|
||||
|
||||
export const SECRET_MIN_SIZE = 5;
|
||||
|
||||
export const GIT_NOTE_REF = 'semantic-release';
|
||||
export const GIT_NOTE_REF = "semantic-release";
|
||||
|
||||
+81
-81
@@ -1,21 +1,21 @@
|
||||
import {inspect} from 'node:util';
|
||||
import {createRequire} from 'node:module';
|
||||
import {isString, toLower, trim} from 'lodash-es';
|
||||
import {RELEASE_TYPE} from './constants.js';
|
||||
import { inspect } from "node:util";
|
||||
import { createRequire } from "node:module";
|
||||
import { isString, toLower, trim } from "lodash-es";
|
||||
import { RELEASE_TYPE } from "./constants.js";
|
||||
|
||||
const require = createRequire(import.meta.url);
|
||||
const pkg = require('../../package.json');
|
||||
const pkg = require("../../package.json");
|
||||
|
||||
const [homepage] = pkg.homepage.split('#');
|
||||
const [homepage] = pkg.homepage.split("#");
|
||||
const stringify = (object) =>
|
||||
isString(object) ? object : inspect(object, {breakLength: Infinity, depth: 2, maxArrayLength: 5});
|
||||
isString(object) ? object : inspect(object, { breakLength: Infinity, depth: 2, maxArrayLength: 5 });
|
||||
const linkify = (file) => `${homepage}/blob/master/${file}`;
|
||||
const wordsList = (words) =>
|
||||
`${words.slice(0, -1).join(', ')}${words.length > 1 ? ` or ${words[words.length - 1]}` : trim(words[0])}`;
|
||||
`${words.slice(0, -1).join(", ")}${words.length > 1 ? ` or ${words[words.length - 1]}` : trim(words[0])}`;
|
||||
|
||||
export function ENOGITREPO({cwd}) {
|
||||
export function ENOGITREPO({ cwd }) {
|
||||
return {
|
||||
message: 'Not running from a git repository.',
|
||||
message: "Not running from a git repository.",
|
||||
details: `The \`semantic-release\` command must be executed from a Git repository.
|
||||
|
||||
The current working directory is \`${cwd}\`.
|
||||
@@ -26,76 +26,76 @@ Please verify your CI configuration to make sure the \`semantic-release\` comman
|
||||
|
||||
export function ENOREPOURL() {
|
||||
return {
|
||||
message: 'The `repositoryUrl` option is required.',
|
||||
message: "The `repositoryUrl` option is required.",
|
||||
details: `The [repositoryUrl option](${linkify(
|
||||
'docs/usage/configuration.md#repositoryurl'
|
||||
"docs/usage/configuration.md#repositoryurl"
|
||||
)}) cannot be determined from the semantic-release configuration, the \`package.json\` nor the [git origin url](https://git-scm.com/book/en/v2/Git-Basics-Working-with-Remotes).
|
||||
|
||||
Please make sure to add the \`repositoryUrl\` to the [semantic-release configuration] (${linkify(
|
||||
'docs/usage/configuration.md'
|
||||
"docs/usage/configuration.md"
|
||||
)}).`,
|
||||
};
|
||||
}
|
||||
|
||||
export function EGITNOPERMISSION({options: {repositoryUrl}, branch: {name}}) {
|
||||
export function EGITNOPERMISSION({ options: { repositoryUrl }, branch: { name } }) {
|
||||
return {
|
||||
message: 'Cannot push to the Git repository.',
|
||||
message: "Cannot push to the Git repository.",
|
||||
details: `**semantic-release** cannot push the version tag to the branch \`${name}\` on the remote Git repository with URL \`${repositoryUrl}\`.
|
||||
|
||||
This can be caused by:
|
||||
- a misconfiguration of the [repositoryUrl](${linkify('docs/usage/configuration.md#repositoryurl')}) option
|
||||
- a misconfiguration of the [repositoryUrl](${linkify("docs/usage/configuration.md#repositoryurl")}) option
|
||||
- the repository being unavailable
|
||||
- or missing push permission for the user configured via the [Git credentials on your CI environment](${linkify(
|
||||
'docs/usage/ci-configuration.md#authentication'
|
||||
)})`,
|
||||
"docs/usage/ci-configuration.md#authentication"
|
||||
)})`,
|
||||
};
|
||||
}
|
||||
|
||||
export function EINVALIDTAGFORMAT({options: {tagFormat}}) {
|
||||
export function EINVALIDTAGFORMAT({ options: { tagFormat } }) {
|
||||
return {
|
||||
message: 'Invalid `tagFormat` option.',
|
||||
message: "Invalid `tagFormat` option.",
|
||||
details: `The [tagFormat](${linkify(
|
||||
'docs/usage/configuration.md#tagformat'
|
||||
"docs/usage/configuration.md#tagformat"
|
||||
)}) must compile to a [valid Git reference](https://git-scm.com/docs/git-check-ref-format#_description).
|
||||
|
||||
Your configuration for the \`tagFormat\` option is \`${stringify(tagFormat)}\`.`,
|
||||
};
|
||||
}
|
||||
|
||||
export function ETAGNOVERSION({options: {tagFormat}}) {
|
||||
export function ETAGNOVERSION({ options: { tagFormat } }) {
|
||||
return {
|
||||
message: 'Invalid `tagFormat` option.',
|
||||
message: "Invalid `tagFormat` option.",
|
||||
details: `The [tagFormat](${linkify(
|
||||
'docs/usage/configuration.md#tagformat'
|
||||
"docs/usage/configuration.md#tagformat"
|
||||
)}) option must contain the variable \`version\` exactly once.
|
||||
|
||||
Your configuration for the \`tagFormat\` option is \`${stringify(tagFormat)}\`.`,
|
||||
};
|
||||
}
|
||||
|
||||
export function EPLUGINCONF({type, required, pluginConf}) {
|
||||
export function EPLUGINCONF({ type, required, pluginConf }) {
|
||||
return {
|
||||
message: `The \`${type}\` plugin configuration is invalid.`,
|
||||
details: `The [${type} plugin configuration](${linkify(`docs/usage/plugins.md#${toLower(type)}-plugin`)}) ${
|
||||
required ? 'is required and ' : ''
|
||||
required ? "is required and " : ""
|
||||
} must be a single or an array of plugins definition. A plugin definition is an npm module name, optionally wrapped in an array with an object.
|
||||
|
||||
Your configuration for the \`${type}\` plugin is \`${stringify(pluginConf)}\`.`,
|
||||
};
|
||||
}
|
||||
|
||||
export function EPLUGINSCONF({plugin}) {
|
||||
export function EPLUGINSCONF({ plugin }) {
|
||||
return {
|
||||
message: 'The `plugins` configuration is invalid.',
|
||||
message: "The `plugins` configuration is invalid.",
|
||||
details: `The [plugins](${linkify(
|
||||
'docs/usage/configuration.md#plugins'
|
||||
"docs/usage/configuration.md#plugins"
|
||||
)}) option must be an array of plugin definitions. A plugin definition is an npm module name, optionally wrapped in an array with an object.
|
||||
|
||||
The invalid configuration is \`${stringify(plugin)}\`.`,
|
||||
};
|
||||
}
|
||||
|
||||
export function EPLUGIN({pluginName, type}) {
|
||||
export function EPLUGIN({ pluginName, type }) {
|
||||
return {
|
||||
message: `A plugin configured in the step ${type} is not a valid semantic-release plugin.`,
|
||||
details: `A valid \`${type}\` **semantic-release** plugin must be a function or an object with a function in the property \`${type}\`.
|
||||
@@ -103,17 +103,17 @@ export function EPLUGIN({pluginName, type}) {
|
||||
The plugin \`${pluginName}\` doesn't have the property \`${type}\` and cannot be used for the \`${type}\` step.
|
||||
|
||||
Please refer to the \`${pluginName}\` and [semantic-release plugins configuration](${linkify(
|
||||
'docs/usage/plugins.md'
|
||||
"docs/usage/plugins.md"
|
||||
)}) documentation for more details.`,
|
||||
};
|
||||
}
|
||||
|
||||
export function EANALYZECOMMITSOUTPUT({result, pluginName}) {
|
||||
export function EANALYZECOMMITSOUTPUT({ result, pluginName }) {
|
||||
return {
|
||||
message: 'The `analyzeCommits` plugin returned an invalid value. It must return a valid semver release type.',
|
||||
message: "The `analyzeCommits` plugin returned an invalid value. It must return a valid semver release type.",
|
||||
details: `The \`analyzeCommits\` plugin must return a valid [semver](https://semver.org) release type. The valid values are: ${RELEASE_TYPE.map(
|
||||
(type) => `\`${type}\``
|
||||
).join(', ')}.
|
||||
).join(", ")}.
|
||||
|
||||
The \`analyzeCommits\` function of the \`${pluginName}\` returned \`${stringify(result)}\` instead.
|
||||
|
||||
@@ -121,15 +121,15 @@ We recommend to report the issue to the \`${pluginName}\` authors, providing the
|
||||
- The **semantic-release** version: \`${pkg.version}\`
|
||||
- The **semantic-release** logs from your CI job
|
||||
- The value returned by the plugin: \`${stringify(result)}\`
|
||||
- A link to the **semantic-release** plugin developer guide: [${linkify('docs/developer-guide/plugin.md')}](${linkify(
|
||||
'docs/developer-guide/plugin.md'
|
||||
- A link to the **semantic-release** plugin developer guide: [${linkify("docs/developer-guide/plugin.md")}](${linkify(
|
||||
"docs/developer-guide/plugin.md"
|
||||
)})`,
|
||||
};
|
||||
}
|
||||
|
||||
export function EGENERATENOTESOUTPUT({result, pluginName}) {
|
||||
export function EGENERATENOTESOUTPUT({ result, pluginName }) {
|
||||
return {
|
||||
message: 'The `generateNotes` plugin returned an invalid value. It must return a `String`.',
|
||||
message: "The `generateNotes` plugin returned an invalid value. It must return a `String`.",
|
||||
details: `The \`generateNotes\` plugin must return a \`String\`.
|
||||
|
||||
The \`generateNotes\` function of the \`${pluginName}\` returned \`${stringify(result)}\` instead.
|
||||
@@ -138,15 +138,15 @@ We recommend to report the issue to the \`${pluginName}\` authors, providing the
|
||||
- The **semantic-release** version: \`${pkg.version}\`
|
||||
- The **semantic-release** logs from your CI job
|
||||
- The value returned by the plugin: \`${stringify(result)}\`
|
||||
- A link to the **semantic-release** plugin developer guide: [${linkify('docs/developer-guide/plugin.md')}](${linkify(
|
||||
'docs/developer-guide/plugin.md'
|
||||
- A link to the **semantic-release** plugin developer guide: [${linkify("docs/developer-guide/plugin.md")}](${linkify(
|
||||
"docs/developer-guide/plugin.md"
|
||||
)})`,
|
||||
};
|
||||
}
|
||||
|
||||
export function EPUBLISHOUTPUT({result, pluginName}) {
|
||||
export function EPUBLISHOUTPUT({ result, pluginName }) {
|
||||
return {
|
||||
message: 'A `publish` plugin returned an invalid value. It must return an `Object`.',
|
||||
message: "A `publish` plugin returned an invalid value. It must return an `Object`.",
|
||||
details: `The \`publish\` plugins must return an \`Object\`.
|
||||
|
||||
The \`publish\` function of the \`${pluginName}\` returned \`${stringify(result)}\` instead.
|
||||
@@ -155,15 +155,15 @@ We recommend to report the issue to the \`${pluginName}\` authors, providing the
|
||||
- The **semantic-release** version: \`${pkg.version}\`
|
||||
- The **semantic-release** logs from your CI job
|
||||
- The value returned by the plugin: \`${stringify(result)}\`
|
||||
- A link to the **semantic-release** plugin developer guide: [${linkify('docs/developer-guide/plugin.md')}](${linkify(
|
||||
'docs/developer-guide/plugin.md'
|
||||
- A link to the **semantic-release** plugin developer guide: [${linkify("docs/developer-guide/plugin.md")}](${linkify(
|
||||
"docs/developer-guide/plugin.md"
|
||||
)})`,
|
||||
};
|
||||
}
|
||||
|
||||
export function EADDCHANNELOUTPUT({result, pluginName}) {
|
||||
export function EADDCHANNELOUTPUT({ result, pluginName }) {
|
||||
return {
|
||||
message: 'A `addChannel` plugin returned an invalid value. It must return an `Object`.',
|
||||
message: "A `addChannel` plugin returned an invalid value. It must return an `Object`.",
|
||||
details: `The \`addChannel\` plugins must return an \`Object\`.
|
||||
|
||||
The \`addChannel\` function of the \`${pluginName}\` returned \`${stringify(result)}\` instead.
|
||||
@@ -172,72 +172,72 @@ We recommend to report the issue to the \`${pluginName}\` authors, providing the
|
||||
- The **semantic-release** version: \`${pkg.version}\`
|
||||
- The **semantic-release** logs from your CI job
|
||||
- The value returned by the plugin: \`${stringify(result)}\`
|
||||
- A link to the **semantic-release** plugin developer guide: [${linkify('docs/developer-guide/plugin.md')}](${linkify(
|
||||
'docs/developer-guide/plugin.md'
|
||||
- A link to the **semantic-release** plugin developer guide: [${linkify("docs/developer-guide/plugin.md")}](${linkify(
|
||||
"docs/developer-guide/plugin.md"
|
||||
)})`,
|
||||
};
|
||||
}
|
||||
|
||||
export function EINVALIDBRANCH({branch}) {
|
||||
export function EINVALIDBRANCH({ branch }) {
|
||||
return {
|
||||
message: 'A branch is invalid in the `branches` configuration.',
|
||||
message: "A branch is invalid in the `branches` configuration.",
|
||||
details: `Each branch in the [branches configuration](${linkify(
|
||||
'docs/usage/configuration.md#branches'
|
||||
"docs/usage/configuration.md#branches"
|
||||
)}) must be either a string, a regexp or an object with a \`name\` property.
|
||||
|
||||
Your configuration for the problematic branch is \`${stringify(branch)}\`.`,
|
||||
};
|
||||
}
|
||||
|
||||
export function EINVALIDBRANCHNAME({branch}) {
|
||||
export function EINVALIDBRANCHNAME({ branch }) {
|
||||
return {
|
||||
message: 'A branch name is invalid in the `branches` configuration.',
|
||||
message: "A branch name is invalid in the `branches` configuration.",
|
||||
details: `Each branch in the [branches configuration](${linkify(
|
||||
'docs/usage/configuration.md#branches'
|
||||
"docs/usage/configuration.md#branches"
|
||||
)}) must be a [valid Git reference](https://git-scm.com/docs/git-check-ref-format#_description).
|
||||
|
||||
Your configuration for the problematic branch is \`${stringify(branch)}\`.`,
|
||||
};
|
||||
}
|
||||
|
||||
export function EDUPLICATEBRANCHES({duplicates}) {
|
||||
export function EDUPLICATEBRANCHES({ duplicates }) {
|
||||
return {
|
||||
message: 'The `branches` configuration has duplicate branches.',
|
||||
message: "The `branches` configuration has duplicate branches.",
|
||||
details: `Each branch in the [branches configuration](${linkify(
|
||||
'docs/usage/configuration.md#branches'
|
||||
"docs/usage/configuration.md#branches"
|
||||
)}) must havea unique name.
|
||||
|
||||
Your configuration contains duplicates for the following branch names: \`${stringify(duplicates)}\`.`,
|
||||
};
|
||||
}
|
||||
|
||||
export function EMAINTENANCEBRANCH({branch}) {
|
||||
export function EMAINTENANCEBRANCH({ branch }) {
|
||||
return {
|
||||
message: 'A maintenance branch is invalid in the `branches` configuration.',
|
||||
message: "A maintenance branch is invalid in the `branches` configuration.",
|
||||
details: `Each maintenance branch in the [branches configuration](${linkify(
|
||||
'docs/usage/configuration.md#branches'
|
||||
"docs/usage/configuration.md#branches"
|
||||
)}) must have a \`range\` property formatted like \`N.x\`, \`N.x.x\` or \`N.N.x\` (\`N\` is a number).
|
||||
|
||||
Your configuration for the problematic branch is \`${stringify(branch)}\`.`,
|
||||
};
|
||||
}
|
||||
|
||||
export function EMAINTENANCEBRANCHES({branches}) {
|
||||
export function EMAINTENANCEBRANCHES({ branches }) {
|
||||
return {
|
||||
message: 'The maintenance branches are invalid in the `branches` configuration.',
|
||||
message: "The maintenance branches are invalid in the `branches` configuration.",
|
||||
details: `Each maintenance branch in the [branches configuration](${linkify(
|
||||
'docs/usage/configuration.md#branches'
|
||||
"docs/usage/configuration.md#branches"
|
||||
)}) must have a unique \`range\` property.
|
||||
|
||||
Your configuration for the problematic branches is \`${stringify(branches)}\`.`,
|
||||
};
|
||||
}
|
||||
|
||||
export function ERELEASEBRANCHES({branches}) {
|
||||
export function ERELEASEBRANCHES({ branches }) {
|
||||
return {
|
||||
message: 'The release branches are invalid in the `branches` configuration.',
|
||||
message: "The release branches are invalid in the `branches` configuration.",
|
||||
details: `A minimum of 1 and a maximum of 3 release branches are required in the [branches configuration](${linkify(
|
||||
'docs/usage/configuration.md#branches'
|
||||
"docs/usage/configuration.md#branches"
|
||||
)}).
|
||||
|
||||
This may occur if your repository does not have a release branch, such as \`master\`.
|
||||
@@ -246,53 +246,53 @@ Your configuration for the problematic branches is \`${stringify(branches)}\`.`,
|
||||
};
|
||||
}
|
||||
|
||||
export function EPRERELEASEBRANCH({branch}) {
|
||||
export function EPRERELEASEBRANCH({ branch }) {
|
||||
return {
|
||||
message: 'A pre-release branch configuration is invalid in the `branches` configuration.',
|
||||
message: "A pre-release branch configuration is invalid in the `branches` configuration.",
|
||||
details: `Each pre-release branch in the [branches configuration](${linkify(
|
||||
'docs/usage/configuration.md#branches'
|
||||
"docs/usage/configuration.md#branches"
|
||||
)}) must have a \`prerelease\` property valid per the [Semantic Versioning Specification](https://semver.org/#spec-item-9). If the \`prerelease\` property is set to \`true\`, then the \`name\` property is used instead.
|
||||
|
||||
Your configuration for the problematic branch is \`${stringify(branch)}\`.`,
|
||||
};
|
||||
}
|
||||
|
||||
export function EPRERELEASEBRANCHES({branches}) {
|
||||
export function EPRERELEASEBRANCHES({ branches }) {
|
||||
return {
|
||||
message: 'The pre-release branches are invalid in the `branches` configuration.',
|
||||
message: "The pre-release branches are invalid in the `branches` configuration.",
|
||||
details: `Each pre-release branch in the [branches configuration](${linkify(
|
||||
'docs/usage/configuration.md#branches'
|
||||
"docs/usage/configuration.md#branches"
|
||||
)}) must have a unique \`prerelease\` property. If the \`prerelease\` property is set to \`true\`, then the \`name\` property is used instead.
|
||||
|
||||
Your configuration for the problematic branches is \`${stringify(branches)}\`.`,
|
||||
};
|
||||
}
|
||||
|
||||
export function EINVALIDNEXTVERSION({nextRelease: {version}, branch: {name, range}, commits, validBranches}) {
|
||||
export function EINVALIDNEXTVERSION({ nextRelease: { version }, branch: { name, range }, commits, validBranches }) {
|
||||
return {
|
||||
message: `The release \`${version}\` on branch \`${name}\` cannot be published as it is out of range.`,
|
||||
details: `Based on the releases published on other branches, only versions within the range \`${range}\` can be published from branch \`${name}\`.
|
||||
|
||||
The following commit${commits.length > 1 ? 's are' : ' is'} responsible for the invalid release:
|
||||
${commits.map(({commit: {short}, subject}) => `- ${subject} (${short})`).join('\n')}
|
||||
The following commit${commits.length > 1 ? "s are" : " is"} responsible for the invalid release:
|
||||
${commits.map(({ commit: { short }, subject }) => `- ${subject} (${short})`).join("\n")}
|
||||
|
||||
${
|
||||
commits.length > 1 ? 'Those commits' : 'This commit'
|
||||
} should be moved to a valid branch with [git merge](https://git-scm.com/docs/git-merge) or [git cherry-pick](https://git-scm.com/docs/git-cherry-pick) and removed from branch \`${name}\` with [git revert](https://git-scm.com/docs/git-revert) or [git reset](https://git-scm.com/docs/git-reset).
|
||||
commits.length > 1 ? "Those commits" : "This commit"
|
||||
} should be moved to a valid branch with [git merge](https://git-scm.com/docs/git-merge) or [git cherry-pick](https://git-scm.com/docs/git-cherry-pick) and removed from branch \`${name}\` with [git revert](https://git-scm.com/docs/git-revert) or [git reset](https://git-scm.com/docs/git-reset).
|
||||
|
||||
A valid branch could be ${wordsList(validBranches.map(({name}) => `\`${name}\``))}.
|
||||
A valid branch could be ${wordsList(validBranches.map(({ name }) => `\`${name}\``))}.
|
||||
|
||||
See the [workflow configuration documentation](${linkify('docs/usage/workflow-configuration.md')}) for more details.`,
|
||||
See the [workflow configuration documentation](${linkify("docs/usage/workflow-configuration.md")}) for more details.`,
|
||||
};
|
||||
}
|
||||
|
||||
export function EINVALIDMAINTENANCEMERGE({nextRelease: {channel, gitTag, version}, branch: {mergeRange, name}}) {
|
||||
export function EINVALIDMAINTENANCEMERGE({ nextRelease: { channel, gitTag, version }, branch: { mergeRange, name } }) {
|
||||
return {
|
||||
message: `The release \`${version}\` on branch \`${name}\` cannot be published as it is out of range.`,
|
||||
details: `Only releases within the range \`${mergeRange}\` can be merged into the maintenance branch \`${name}\` and published to the \`${channel}\` distribution channel.
|
||||
|
||||
The branch \`${name}\` head should be [reset](https://git-scm.com/docs/git-reset) to a previous commit so the commit with tag \`${gitTag}\` is removed from the branch history.
|
||||
|
||||
See the [workflow configuration documentation](${linkify('docs/usage/workflow-configuration.md')}) for more details.`,
|
||||
See the [workflow configuration documentation](${linkify("docs/usage/workflow-configuration.md")}) for more details.`,
|
||||
};
|
||||
}
|
||||
|
||||
+20
-20
@@ -1,23 +1,23 @@
|
||||
/* eslint require-atomic-updates: off */
|
||||
|
||||
import {isPlainObject, isString} from 'lodash-es';
|
||||
import {getGitHead} from '../git.js';
|
||||
import hideSensitive from '../hide-sensitive.js';
|
||||
import {hideSensitiveValues} from '../utils.js';
|
||||
import {RELEASE_NOTES_SEPARATOR, RELEASE_TYPE} from './constants.js';
|
||||
import { isPlainObject, isString } from "lodash-es";
|
||||
import { getGitHead } from "../git.js";
|
||||
import hideSensitive from "../hide-sensitive.js";
|
||||
import { hideSensitiveValues } from "../utils.js";
|
||||
import { RELEASE_NOTES_SEPARATOR, RELEASE_TYPE } from "./constants.js";
|
||||
|
||||
export default {
|
||||
verifyConditions: {
|
||||
required: false,
|
||||
dryRun: true,
|
||||
pipelineConfig: () => ({settleAll: true}),
|
||||
pipelineConfig: () => ({ settleAll: true }),
|
||||
},
|
||||
analyzeCommits: {
|
||||
default: ['@semantic-release/commit-analyzer'],
|
||||
default: ["@semantic-release/commit-analyzer"],
|
||||
required: true,
|
||||
dryRun: true,
|
||||
outputValidator: (output) => !output || RELEASE_TYPE.includes(output),
|
||||
preprocess: ({commits, ...inputs}) => ({
|
||||
preprocess: ({ commits, ...inputs }) => ({
|
||||
...inputs,
|
||||
commits: commits.filter((commit) => !/\[skip\s+release]|\[release\s+skip]/i.test(commit.message)),
|
||||
}),
|
||||
@@ -32,29 +32,29 @@ export default {
|
||||
verifyRelease: {
|
||||
required: false,
|
||||
dryRun: true,
|
||||
pipelineConfig: () => ({settleAll: true}),
|
||||
pipelineConfig: () => ({ settleAll: true }),
|
||||
},
|
||||
generateNotes: {
|
||||
required: false,
|
||||
dryRun: true,
|
||||
outputValidator: (output) => !output || isString(output),
|
||||
pipelineConfig: () => ({
|
||||
getNextInput: ({nextRelease, ...context}, notes) => ({
|
||||
getNextInput: ({ nextRelease, ...context }, notes) => ({
|
||||
...context,
|
||||
nextRelease: {
|
||||
...nextRelease,
|
||||
notes: `${nextRelease.notes ? `${nextRelease.notes}${RELEASE_NOTES_SEPARATOR}` : ''}${notes}`,
|
||||
notes: `${nextRelease.notes ? `${nextRelease.notes}${RELEASE_NOTES_SEPARATOR}` : ""}${notes}`,
|
||||
},
|
||||
}),
|
||||
}),
|
||||
postprocess: (results, {env}) => hideSensitive(env)(results.filter(Boolean).join(RELEASE_NOTES_SEPARATOR)),
|
||||
postprocess: (results, { env }) => hideSensitive(env)(results.filter(Boolean).join(RELEASE_NOTES_SEPARATOR)),
|
||||
},
|
||||
prepare: {
|
||||
required: false,
|
||||
dryRun: false,
|
||||
pipelineConfig: ({generateNotes}) => ({
|
||||
pipelineConfig: ({ generateNotes }) => ({
|
||||
getNextInput: async (context) => {
|
||||
const newGitHead = await getGitHead({cwd: context.cwd});
|
||||
const newGitHead = await getGitHead({ cwd: context.cwd });
|
||||
// If previous prepare plugin has created a commit (gitHead changed)
|
||||
if (context.nextRelease.gitHead !== newGitHead) {
|
||||
context.nextRelease.gitHead = newGitHead;
|
||||
@@ -73,7 +73,7 @@ export default {
|
||||
outputValidator: (output) => !output || isPlainObject(output),
|
||||
pipelineConfig: () => ({
|
||||
// Add `nextRelease` and plugin properties to published release
|
||||
transform: (release, step, {nextRelease}) => ({
|
||||
transform: (release, step, { nextRelease }) => ({
|
||||
...(release === false ? {} : nextRelease),
|
||||
...release,
|
||||
...step,
|
||||
@@ -86,7 +86,7 @@ export default {
|
||||
outputValidator: (output) => !output || isPlainObject(output),
|
||||
pipelineConfig: () => ({
|
||||
// Add `nextRelease` and plugin properties to published release
|
||||
transform: (release, step, {nextRelease}) => ({
|
||||
transform: (release, step, { nextRelease }) => ({
|
||||
...(release === false ? {} : nextRelease),
|
||||
...release,
|
||||
...step,
|
||||
@@ -96,13 +96,13 @@ export default {
|
||||
success: {
|
||||
required: false,
|
||||
dryRun: false,
|
||||
pipelineConfig: () => ({settleAll: true}),
|
||||
preprocess: ({releases, env, ...inputs}) => ({...inputs, env, releases: hideSensitiveValues(env, releases)}),
|
||||
pipelineConfig: () => ({ settleAll: true }),
|
||||
preprocess: ({ releases, env, ...inputs }) => ({ ...inputs, env, releases: hideSensitiveValues(env, releases) }),
|
||||
},
|
||||
fail: {
|
||||
required: false,
|
||||
dryRun: false,
|
||||
pipelineConfig: () => ({settleAll: true}),
|
||||
preprocess: ({errors, env, ...inputs}) => ({...inputs, env, errors: hideSensitiveValues(env, errors)}),
|
||||
pipelineConfig: () => ({ settleAll: true }),
|
||||
preprocess: ({ errors, env, ...inputs }) => ({ ...inputs, env, errors: hideSensitiveValues(env, errors) }),
|
||||
},
|
||||
};
|
||||
|
||||
+18
-18
@@ -1,13 +1,13 @@
|
||||
import {castArray, identity, isNil, isPlainObject, isString, omit} from 'lodash-es';
|
||||
import AggregateError from 'aggregate-error';
|
||||
import getError from '../get-error.js';
|
||||
import PLUGINS_DEFINITIONS from '../definitions/plugins.js';
|
||||
import {loadPlugin, parseConfig, validatePlugin, validateStep} from './utils.js';
|
||||
import pipeline from './pipeline.js';
|
||||
import normalize from './normalize.js';
|
||||
import { castArray, identity, isNil, isPlainObject, isString, omit } from "lodash-es";
|
||||
import AggregateError from "aggregate-error";
|
||||
import getError from "../get-error.js";
|
||||
import PLUGINS_DEFINITIONS from "../definitions/plugins.js";
|
||||
import { loadPlugin, parseConfig, validatePlugin, validateStep } from "./utils.js";
|
||||
import pipeline from "./pipeline.js";
|
||||
import normalize from "./normalize.js";
|
||||
|
||||
export default async (context, pluginsPath) => {
|
||||
let {options, logger} = context;
|
||||
let { options, logger } = context;
|
||||
const errors = [];
|
||||
|
||||
const plugins = options.plugins
|
||||
@@ -20,8 +20,8 @@ export default async (context, pluginsPath) => {
|
||||
if (isPlainObject(plugin)) {
|
||||
Object.entries(plugin).forEach(([type, func]) => {
|
||||
if (PLUGINS_DEFINITIONS[type]) {
|
||||
Reflect.defineProperty(func, 'pluginName', {
|
||||
value: isPlainObject(name) ? 'Inline plugin' : name,
|
||||
Reflect.defineProperty(func, "pluginName", {
|
||||
value: isPlainObject(name) ? "Inline plugin" : name,
|
||||
writable: false,
|
||||
enumerable: true,
|
||||
});
|
||||
@@ -29,10 +29,10 @@ export default async (context, pluginsPath) => {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
errors.push(getError('EPLUGINSCONF', {plugin}));
|
||||
errors.push(getError("EPLUGINSCONF", { plugin }));
|
||||
}
|
||||
} else {
|
||||
errors.push(getError('EPLUGINSCONF', {plugin}));
|
||||
errors.push(getError("EPLUGINSCONF", { plugin }));
|
||||
}
|
||||
|
||||
return pluginsList;
|
||||
@@ -43,12 +43,12 @@ export default async (context, pluginsPath) => {
|
||||
throw new AggregateError(errors);
|
||||
}
|
||||
|
||||
options = {...plugins, ...options};
|
||||
options = { ...plugins, ...options };
|
||||
|
||||
const pluginsConfig = await Object.entries(PLUGINS_DEFINITIONS).reduce(
|
||||
async (
|
||||
eventualPluginsConfigAccumulator,
|
||||
[type, {required, default: def, pipelineConfig, postprocess = identity, preprocess = identity}]
|
||||
[type, { required, default: def, pipelineConfig, postprocess = identity, preprocess = identity }]
|
||||
) => {
|
||||
let pluginOptions;
|
||||
const pluginsConfigAccumulator = await eventualPluginsConfigAccumulator;
|
||||
@@ -63,8 +63,8 @@ export default async (context, pluginsPath) => {
|
||||
);
|
||||
}
|
||||
|
||||
if (!validateStep({required}, options[type])) {
|
||||
errors.push(getError('EPLUGINCONF', {type, required, pluginConf: options[type]}));
|
||||
if (!validateStep({ required }, options[type])) {
|
||||
errors.push(getError("EPLUGINCONF", { type, required, pluginConf: options[type] }));
|
||||
return pluginsConfigAccumulator;
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ export default async (context, pluginsPath) => {
|
||||
const steps = await Promise.all(
|
||||
castArray(pluginOptions).map(async (pluginOpt) =>
|
||||
normalize(
|
||||
{...context, options: omit(options, Object.keys(PLUGINS_DEFINITIONS), 'plugins')},
|
||||
{ ...context, options: omit(options, Object.keys(PLUGINS_DEFINITIONS), "plugins") },
|
||||
type,
|
||||
pluginOpt,
|
||||
pluginsPath
|
||||
@@ -100,4 +100,4 @@ export default async (context, pluginsPath) => {
|
||||
}
|
||||
|
||||
return pluginsConfig;
|
||||
}
|
||||
};
|
||||
|
||||
+17
-17
@@ -1,14 +1,14 @@
|
||||
import {cloneDeep, isFunction, isPlainObject, noop, omit} from 'lodash-es';
|
||||
import debugPlugins from 'debug';
|
||||
import getError from '../get-error.js';
|
||||
import {extractErrors} from '../utils.js';
|
||||
import PLUGINS_DEFINITIONS from '../definitions/plugins.js';
|
||||
import {loadPlugin, parseConfig} from './utils.js';
|
||||
import { cloneDeep, isFunction, isPlainObject, noop, omit } from "lodash-es";
|
||||
import debugPlugins from "debug";
|
||||
import getError from "../get-error.js";
|
||||
import { extractErrors } from "../utils.js";
|
||||
import PLUGINS_DEFINITIONS from "../definitions/plugins.js";
|
||||
import { loadPlugin, parseConfig } from "./utils.js";
|
||||
|
||||
const debug = debugPlugins('semantic-release:plugins');
|
||||
const debug = debugPlugins("semantic-release:plugins");
|
||||
|
||||
export default async (context, type, pluginOpt, pluginsPath) => {
|
||||
const {stdout, stderr, options, logger} = context;
|
||||
const { stdout, stderr, options, logger } = context;
|
||||
if (!pluginOpt) {
|
||||
return noop;
|
||||
}
|
||||
@@ -21,26 +21,26 @@ export default async (context, type, pluginOpt, pluginsPath) => {
|
||||
|
||||
let func;
|
||||
if (isFunction(plugin)) {
|
||||
func = plugin.bind(null, cloneDeep({...options, ...config}));
|
||||
func = plugin.bind(null, cloneDeep({ ...options, ...config }));
|
||||
} else if (isPlainObject(plugin) && plugin[type] && isFunction(plugin[type])) {
|
||||
func = plugin[type].bind(null, cloneDeep({...options, ...config}));
|
||||
func = plugin[type].bind(null, cloneDeep({ ...options, ...config }));
|
||||
} else {
|
||||
throw getError('EPLUGIN', {type, pluginName});
|
||||
throw getError("EPLUGIN", { type, pluginName });
|
||||
}
|
||||
|
||||
const validator = async (input) => {
|
||||
const {dryRun, outputValidator} = PLUGINS_DEFINITIONS[type] || {};
|
||||
const { dryRun, outputValidator } = PLUGINS_DEFINITIONS[type] || {};
|
||||
try {
|
||||
if (!input.options.dryRun || dryRun) {
|
||||
logger.log(`Start step "${type}" of plugin "${pluginName}"`);
|
||||
const result = await func({
|
||||
...cloneDeep(omit(input, ['stdout', 'stderr', 'logger'])),
|
||||
...cloneDeep(omit(input, ["stdout", "stderr", "logger"])),
|
||||
stdout,
|
||||
stderr,
|
||||
logger: logger.scope(logger.scopeName, pluginName),
|
||||
});
|
||||
if (outputValidator && !outputValidator(result)) {
|
||||
throw getError(`E${type.toUpperCase()}OUTPUT`, {result, pluginName});
|
||||
throw getError(`E${type.toUpperCase()}OUTPUT`, { result, pluginName });
|
||||
}
|
||||
|
||||
logger.success(`Completed step "${type}" of plugin "${pluginName}"`);
|
||||
@@ -50,12 +50,12 @@ export default async (context, type, pluginOpt, pluginsPath) => {
|
||||
logger.warn(`Skip step "${type}" of plugin "${pluginName}" in dry-run mode`);
|
||||
} catch (error) {
|
||||
logger.error(`Failed step "${type}" of plugin "${pluginName}"`);
|
||||
extractErrors(error).forEach((err) => Object.assign(err, {pluginName}));
|
||||
extractErrors(error).forEach((err) => Object.assign(err, { pluginName }));
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
Reflect.defineProperty(validator, 'pluginName', {value: pluginName, writable: false, enumerable: true});
|
||||
Reflect.defineProperty(validator, "pluginName", { value: pluginName, writable: false, enumerable: true });
|
||||
|
||||
if (!isFunction(pluginOpt)) {
|
||||
if (pluginsPath[name]) {
|
||||
@@ -66,4 +66,4 @@ export default async (context, type, pluginOpt, pluginsPath) => {
|
||||
}
|
||||
|
||||
return validator;
|
||||
}
|
||||
};
|
||||
|
||||
+33
-32
@@ -1,7 +1,7 @@
|
||||
import {identity} from 'lodash-es';
|
||||
import pReduce from 'p-reduce';
|
||||
import AggregateError from 'aggregate-error';
|
||||
import {extractErrors} from '../utils.js';
|
||||
import { identity } from "lodash-es";
|
||||
import pReduce from "p-reduce";
|
||||
import AggregateError from "aggregate-error";
|
||||
import { extractErrors } from "../utils.js";
|
||||
|
||||
/**
|
||||
* A Function that execute a list of function sequencially. If at least one Function ins the pipeline throws an Error or rejects, the pipeline function rejects as well.
|
||||
@@ -25,34 +25,35 @@ import {extractErrors} from '../utils.js';
|
||||
*
|
||||
* @return {Pipeline} A Function that execute the `steps` sequentially
|
||||
*/
|
||||
export default (steps, {settleAll = false, getNextInput = identity, transform = identity} = {}) => async (input) => {
|
||||
const results = [];
|
||||
const errors = [];
|
||||
await pReduce(
|
||||
steps,
|
||||
async (lastInput, step) => {
|
||||
let result;
|
||||
try {
|
||||
// Call the step with the input computed at the end of the previous iteration and save intermediary result
|
||||
result = await transform(await step(lastInput), step, lastInput);
|
||||
results.push(result);
|
||||
} catch (error) {
|
||||
if (settleAll) {
|
||||
errors.push(...extractErrors(error));
|
||||
result = error;
|
||||
} else {
|
||||
throw error;
|
||||
export default (steps, { settleAll = false, getNextInput = identity, transform = identity } = {}) =>
|
||||
async (input) => {
|
||||
const results = [];
|
||||
const errors = [];
|
||||
await pReduce(
|
||||
steps,
|
||||
async (lastInput, step) => {
|
||||
let result;
|
||||
try {
|
||||
// Call the step with the input computed at the end of the previous iteration and save intermediary result
|
||||
result = await transform(await step(lastInput), step, lastInput);
|
||||
results.push(result);
|
||||
} catch (error) {
|
||||
if (settleAll) {
|
||||
errors.push(...extractErrors(error));
|
||||
result = error;
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Prepare input for the next step, passing the input of the last iteration (or initial parameter for the first iteration) and the result of the current one
|
||||
return getNextInput(lastInput, result);
|
||||
},
|
||||
input
|
||||
);
|
||||
if (errors.length > 0) {
|
||||
throw new AggregateError(errors);
|
||||
}
|
||||
// Prepare input for the next step, passing the input of the last iteration (or initial parameter for the first iteration) and the result of the current one
|
||||
return getNextInput(lastInput, result);
|
||||
},
|
||||
input
|
||||
);
|
||||
if (errors.length > 0) {
|
||||
throw new AggregateError(errors);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
+20
-9
@@ -1,7 +1,7 @@
|
||||
import {dirname} from 'node:path';
|
||||
import {fileURLToPath} from 'node:url';
|
||||
import {castArray, isArray, isFunction, isNil, isPlainObject, isString} from 'lodash-es';
|
||||
import resolveFrom from 'resolve-from';
|
||||
import { dirname } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { castArray, isArray, isFunction, isNil, isPlainObject, isString } from "lodash-es";
|
||||
import resolveFrom from "resolve-from";
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
@@ -38,7 +38,7 @@ export function validatePlugin(conf) {
|
||||
);
|
||||
}
|
||||
|
||||
export function validateStep({required}, conf) {
|
||||
export function validateStep({ required }, conf) {
|
||||
conf = castArray(conf).filter(Boolean);
|
||||
if (required) {
|
||||
return conf.length >= 1 && validateSteps(conf);
|
||||
@@ -47,14 +47,25 @@ export function validateStep({required}, conf) {
|
||||
return conf.length === 0 || validateSteps(conf);
|
||||
}
|
||||
|
||||
export async function loadPlugin({cwd}, name, pluginsPath) {
|
||||
export async function loadPlugin({ cwd }, name, pluginsPath) {
|
||||
const basePath = pluginsPath[name]
|
||||
? dirname(resolveFrom.silent(__dirname, pluginsPath[name]) || resolveFrom(cwd, pluginsPath[name]))
|
||||
: __dirname;
|
||||
|
||||
// See https://github.com/mysticatea/eslint-plugin-node/issues/250
|
||||
// eslint-disable-next-line node/no-unsupported-features/es-syntax
|
||||
return isFunction(name) ? name : (await import(resolveFrom.silent(basePath, name) || resolveFrom(cwd, name))).default;
|
||||
if (isFunction(name)) {
|
||||
return name;
|
||||
}
|
||||
|
||||
const { default: cjsExport, ...esmNamedExports } = await import(
|
||||
resolveFrom.silent(basePath, name) || resolveFrom(cwd, name)
|
||||
);
|
||||
|
||||
if (cjsExport) {
|
||||
return cjsExport;
|
||||
}
|
||||
|
||||
return esmNamedExports;
|
||||
}
|
||||
|
||||
export function parseConfig(plugin) {
|
||||
@@ -63,7 +74,7 @@ export function parseConfig(plugin) {
|
||||
if (isArray(plugin)) {
|
||||
[path, config] = plugin;
|
||||
} else if (isPlainObject(plugin) && !isNil(plugin.path)) {
|
||||
({path, ...config} = plugin);
|
||||
({ path, ...config } = plugin);
|
||||
} else {
|
||||
path = plugin;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user