Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

upgraded to next major version of the npm plugin #2741

Merged
merged 9 commits into from
Mar 24, 2023
2 changes: 2 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# style: prettier (#2670)
b06c9bbe4c6be121c5561b356d8c465c1cadffba
9 changes: 5 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ name: Release
- beta
- "*.x"
permissions:
contents: read # for checkout
contents: read # for checkout
jobs:
release:
permissions:
contents: write # to be able to publish a GitHub release
issues: write # to be able to comment on released issues
pull-requests: write # to be able to comment on released pull requests
contents: write # to be able to publish a GitHub release
issues: write # to be able to comment on released issues
pull-requests: write # to be able to comment on released pull requests
id-token: write # to enable use of OIDC for npm provenance
name: release
runs-on: ubuntu-latest
steps:
Expand Down
14 changes: 7 additions & 7 deletions lib/branches/expand.js
Original file line number Diff line number Diff line change
@@ -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)),
})),
],
[]
);
}
};
27 changes: 13 additions & 14 deletions lib/branches/get-tags.js
Original file line number Diff line number Diff line change
@@ -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 }];
},
[]
);
}
};
44 changes: 22 additions & 22 deletions lib/branches/index.js
Original file line number Diff line number Diff line change
@@ -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]
Expand All @@ -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));
}
});

Expand All @@ -68,4 +68,4 @@ export default async (repositoryUrl, ciBranch, context) => {
}

return [...result.maintenance, ...result.release, ...result.prerelease];
}
};
35 changes: 18 additions & 17 deletions lib/branches/normalize.js
Original file line number Diff line number Diff line change
@@ -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 =
Expand All @@ -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),
Expand All @@ -54,15 +55,15 @@ export function maintenance({maintenance, release}) {
});
}

export function release({release}) {
export function release({ release }) {
if (release.length === 0) {
return 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);
Expand All @@ -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,
Expand All @@ -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,
Expand Down
18 changes: 9 additions & 9 deletions lib/definitions/branches.js
Original file line number Diff line number Diff line change
@@ -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 = {
Expand Down
16 changes: 8 additions & 8 deletions lib/definitions/constants.js
Original file line number Diff line number Diff line change
@@ -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";