style: prettier (#2624)

This commit is contained in:
Gregor Martynus
2022-11-23 16:02:51 -08:00
committed by GitHub
parent 8a0d8be51f
commit d13ea9280e
54 changed files with 3129 additions and 15324 deletions
+15 -9
View File
@@ -1,7 +1,7 @@
import debugCommits from 'debug';
import {getCommits} from './git.js';
import debugCommits from "debug";
import { getCommits } from "./git.js";
const debug = debugCommits('semantic-release:get-commits');
const debug = debugCommits("semantic-release:get-commits");
/**
* Retrieve the list of commits on the current branch since the commit sha associated with the last release, or all the commits of the current branch if there is no last released version.
@@ -10,16 +10,22 @@ const debug = debugCommits('semantic-release:get-commits');
*
* @return {Promise<Array<Object>>} The list of commits on the branch `branch` since the last release.
*/
export default async ({cwd, env, lastRelease: {gitHead: from}, nextRelease: {gitHead: to = 'HEAD'} = {}, logger}) => {
export default async ({
cwd,
env,
lastRelease: { gitHead: from },
nextRelease: { gitHead: to = "HEAD" } = {},
logger,
}) => {
if (from) {
debug('Use from: %s', from);
debug("Use from: %s", from);
} else {
logger.log('No previous release found, retrieving all commits');
logger.log("No previous release found, retrieving all commits");
}
const commits = await getCommits(from, to, {cwd, env});
const commits = await getCommits(from, to, { cwd, env });
logger.log(`Found ${commits.length} commits since last release`);
debug('Parsed commits: %o', commits);
debug("Parsed commits: %o", commits);
return commits;
}
};
+38 -38
View File
@@ -1,39 +1,39 @@
import {dirname, resolve} from 'node:path';
import {fileURLToPath} from 'node:url';
import {createRequire} from 'node:module';
import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import { createRequire } from "node:module";
import {castArray, isNil, isPlainObject, isString, pickBy} from 'lodash-es';
import {readPackageUp} from 'read-pkg-up';
import {cosmiconfig} from 'cosmiconfig';
import resolveFrom from 'resolve-from';
import debugConfig from 'debug';
import {repoUrl} from './git.js';
import PLUGINS_DEFINITIONS from './definitions/plugins.js';
import plugins from './plugins/index.js';
import {parseConfig, validatePlugin} from './plugins/utils.js';
import { castArray, isNil, isPlainObject, isString, pickBy } from "lodash-es";
import { readPackageUp } from "read-pkg-up";
import { cosmiconfig } from "cosmiconfig";
import resolveFrom from "resolve-from";
import debugConfig from "debug";
import { repoUrl } from "./git.js";
import PLUGINS_DEFINITIONS from "./definitions/plugins.js";
import plugins from "./plugins/index.js";
import { parseConfig, validatePlugin } from "./plugins/utils.js";
const debug = debugConfig('semantic-release:config');
const debug = debugConfig("semantic-release:config");
const __dirname = dirname(fileURLToPath(import.meta.url));
const require = createRequire(import.meta.url);
const CONFIG_NAME = 'release';
const CONFIG_NAME = "release";
export default async (context, cliOptions) => {
const {cwd, env} = context;
const {config, filepath} = (await cosmiconfig(CONFIG_NAME).search(cwd)) || {};
const { cwd, env } = context;
const { config, filepath } = (await cosmiconfig(CONFIG_NAME).search(cwd)) || {};
debug('load config from: %s', filepath);
debug("load config from: %s", filepath);
// Merge config file options and CLI/API options
let options = {...config, ...cliOptions};
let options = { ...config, ...cliOptions };
const pluginsPath = {};
let extendPaths;
({extends: extendPaths, ...options} = options);
({ extends: extendPaths, ...options } = options);
if (extendPaths) {
// If `extends` is defined, load and merge each shareable config with `options`
options = {
...await (castArray(extendPaths).reduce(async(eventualResult, extendPath) => {
...(await castArray(extendPaths).reduce(async (eventualResult, extendPath) => {
const result = await eventualResult;
const extendsOptions = require(resolveFrom.silent(__dirname, extendPath) || resolveFrom(cwd, extendPath));
@@ -43,7 +43,7 @@ export default async (context, cliOptions) => {
.filter(([, value]) => Boolean(value))
.reduce((pluginsPath, [option, value]) => {
castArray(value).forEach((plugin) => {
if (option === 'plugins' && validatePlugin(plugin)) {
if (option === "plugins" && validatePlugin(plugin)) {
pluginsPath[parseConfig(plugin)[0]] = extendPath;
} else if (
PLUGINS_DEFINITIONS[option] &&
@@ -55,7 +55,7 @@ export default async (context, cliOptions) => {
return pluginsPath;
}, pluginsPath);
return {...result, ...extendsOptions};
return { ...result, ...extendsOptions };
}, {})),
...options,
};
@@ -64,36 +64,36 @@ export default async (context, cliOptions) => {
// Set default options values if not defined yet
options = {
branches: [
'+([0-9])?(.{+([0-9]),x}).x',
'master',
'next',
'next-major',
{name: 'beta', prerelease: true},
{name: 'alpha', prerelease: true},
"+([0-9])?(.{+([0-9]),x}).x",
"master",
"next",
"next-major",
{ name: "beta", prerelease: true },
{ name: "alpha", prerelease: true },
],
repositoryUrl: (await pkgRepoUrl({normalize: false, cwd})) || (await repoUrl({cwd, env})),
repositoryUrl: (await pkgRepoUrl({ normalize: false, cwd })) || (await repoUrl({ cwd, env })),
tagFormat: `v\${version}`,
plugins: [
'@semantic-release/commit-analyzer',
'@semantic-release/release-notes-generator',
'@semantic-release/npm',
'@semantic-release/github',
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/npm",
"@semantic-release/github",
],
// Remove `null` and `undefined` options, so they can be replaced with default ones
...pickBy(options, (option) => !isNil(option)),
...(options.branches ? {branches: castArray(options.branches)} : {}),
...(options.branches ? { branches: castArray(options.branches) } : {}),
};
if (options.ci === false) {
options.noCi = true;
}
debug('options values: %O', options);
debug("options values: %O", options);
return {options, plugins: await plugins({...context, options}, pluginsPath)};
}
return { options, plugins: await plugins({ ...context, options }, pluginsPath) };
};
async function pkgRepoUrl(options) {
const {packageJson} = (await readPackageUp(options)) || {};
const { packageJson } = (await readPackageUp(options)) || {};
return packageJson && (isPlainObject(packageJson.repository) ? packageJson.repository.url : packageJson.repository);
}
+4 -4
View File
@@ -1,7 +1,7 @@
import SemanticReleaseError from '@semantic-release/error';
import * as ERROR_DEFINITIONS from './definitions/errors.js';
import SemanticReleaseError from "@semantic-release/error";
import * as ERROR_DEFINITIONS from "./definitions/errors.js";
export default (code, ctx = {}) => {
const {message, details} = ERROR_DEFINITIONS[code](ctx);
const { message, details } = ERROR_DEFINITIONS[code](ctx);
return new SemanticReleaseError(message, code, details);
}
};
+32 -32
View File
@@ -1,10 +1,10 @@
import {format, parse} from 'node:url';
import {isNil} from 'lodash-es';
import hostedGitInfo from 'hosted-git-info';
import debugAuthUrl from 'debug';
import {verifyAuth} from './git.js';
import { format, parse } from "node:url";
import { isNil } from "lodash-es";
import hostedGitInfo from "hosted-git-info";
import debugAuthUrl from "debug";
import { verifyAuth } from "./git.js";
const debug = debugAuthUrl('semantic-release:get-git-auth-url');
const debug = debugAuthUrl("semantic-release:get-git-auth-url");
/**
* Machinery to format a repository URL with the given credentials
@@ -18,15 +18,15 @@ const debug = debugAuthUrl('semantic-release:get-git-auth-url');
function formatAuthUrl(protocol, repositoryUrl, gitCredentials) {
const [match, auth, host, basePort, path] =
/^(?!.+:\/\/)(?:(?<auth>.*)@)?(?<host>.*?):(?<port>\d+)?:?\/?(?<path>.*)$/.exec(repositoryUrl) || [];
const {port, hostname, ...parsed} = parse(
match ? `ssh://${auth ? `${auth}@` : ''}${host}${basePort ? `:${basePort}` : ''}/${path}` : repositoryUrl
const { port, hostname, ...parsed } = parse(
match ? `ssh://${auth ? `${auth}@` : ""}${host}${basePort ? `:${basePort}` : ""}/${path}` : repositoryUrl
);
return format({
...parsed,
auth: gitCredentials,
host: `${hostname}${protocol === 'ssh:' ? '' : port ? `:${port}` : ''}`,
protocol: protocol && /http[^s]/.test(protocol) ? 'http' : 'https',
host: `${hostname}${protocol === "ssh:" ? "" : port ? `:${port}` : ""}`,
protocol: protocol && /http[^s]/.test(protocol) ? "http" : "https",
});
}
@@ -38,9 +38,9 @@ function formatAuthUrl(protocol, repositoryUrl, gitCredentials) {
*
* @return {String} The authUrl as is if the connection was successfull, null otherwise
*/
async function ensureValidAuthUrl({cwd, env, branch}, authUrl) {
async function ensureValidAuthUrl({ cwd, env, branch }, authUrl) {
try {
await verifyAuth(authUrl, branch.name, {cwd, env});
await verifyAuth(authUrl, branch.name, { cwd, env });
return authUrl;
} catch (error) {
debug(error);
@@ -60,44 +60,44 @@ async function ensureValidAuthUrl({cwd, env, branch}, authUrl) {
* @return {String} The formatted Git repository URL.
*/
export default async (context) => {
const {cwd, env, branch} = context;
const { cwd, env, branch } = context;
const GIT_TOKENS = {
GIT_CREDENTIALS: undefined,
GH_TOKEN: undefined,
// GitHub Actions require the "x-access-token:" prefix for git access
// https://developer.github.com/apps/building-github-apps/authenticating-with-github-apps/#http-based-git-access-by-an-installation
GITHUB_TOKEN: isNil(env.GITHUB_ACTION) ? undefined : 'x-access-token:',
GL_TOKEN: 'gitlab-ci-token:',
GITLAB_TOKEN: 'gitlab-ci-token:',
BB_TOKEN: 'x-token-auth:',
BITBUCKET_TOKEN: 'x-token-auth:',
BB_TOKEN_BASIC_AUTH: '',
BITBUCKET_TOKEN_BASIC_AUTH: '',
GITHUB_TOKEN: isNil(env.GITHUB_ACTION) ? undefined : "x-access-token:",
GL_TOKEN: "gitlab-ci-token:",
GITLAB_TOKEN: "gitlab-ci-token:",
BB_TOKEN: "x-token-auth:",
BITBUCKET_TOKEN: "x-token-auth:",
BB_TOKEN_BASIC_AUTH: "",
BITBUCKET_TOKEN_BASIC_AUTH: "",
};
let {repositoryUrl} = context.options;
const info = hostedGitInfo.fromUrl(repositoryUrl, {noGitPlus: true});
const {protocol, ...parsed} = parse(repositoryUrl);
let { repositoryUrl } = context.options;
const info = hostedGitInfo.fromUrl(repositoryUrl, { noGitPlus: true });
const { protocol, ...parsed } = parse(repositoryUrl);
if (info && info.getDefaultRepresentation() === 'shortcut') {
if (info && info.getDefaultRepresentation() === "shortcut") {
// Expand shorthand URLs (such as `owner/repo` or `gitlab:owner/repo`)
repositoryUrl = info.https();
} else if (protocol && protocol.includes('http')) {
} else if (protocol && protocol.includes("http")) {
// Replace `git+https` and `git+http` with `https` or `http`
repositoryUrl = format({...parsed, protocol: protocol.includes('https') ? 'https' : 'http', href: null});
repositoryUrl = format({ ...parsed, protocol: protocol.includes("https") ? "https" : "http", href: null });
}
// Test if push is allowed without transforming the URL (e.g. is ssh keys are set up)
try {
debug('Verifying ssh auth by attempting to push to %s', repositoryUrl);
await verifyAuth(repositoryUrl, branch.name, {cwd, env});
debug("Verifying ssh auth by attempting to push to %s", repositoryUrl);
await verifyAuth(repositoryUrl, branch.name, { cwd, env });
} catch {
debug('SSH key auth failed, falling back to https.');
debug("SSH key auth failed, falling back to https.");
const envVars = Object.keys(GIT_TOKENS).filter((envVar) => !isNil(env[envVar]));
// Skip verification if there is no ambiguity on which env var to use for authentication
if (envVars.length === 1) {
const gitCredentials = `${GIT_TOKENS[envVars[0]] || ''}${env[envVars[0]]}`;
const gitCredentials = `${GIT_TOKENS[envVars[0]] || ""}${env[envVars[0]]}`;
return formatAuthUrl(protocol, repositoryUrl, gitCredentials);
}
@@ -106,7 +106,7 @@ export default async (context) => {
const candidateRepositoryUrls = [];
for (const envVar of envVars) {
const gitCredentials = `${GIT_TOKENS[envVar] || ''}${env[envVar]}`;
const gitCredentials = `${GIT_TOKENS[envVar] || ""}${env[envVar]}`;
const authUrl = formatAuthUrl(protocol, repositoryUrl, gitCredentials);
candidateRepositoryUrls.push(ensureValidAuthUrl(context, authUrl));
}
@@ -121,4 +121,4 @@ export default async (context) => {
}
return repositoryUrl;
}
};
+8 -8
View File
@@ -1,6 +1,6 @@
import {isUndefined} from 'lodash-es';
import semver from 'semver';
import {isSameChannel, makeTag} from './utils.js';
import { isUndefined } from "lodash-es";
import semver from "semver";
import { isSameChannel, makeTag } from "./utils.js";
/**
* Last release.
@@ -26,19 +26,19 @@ import {isSameChannel, makeTag} from './utils.js';
*
* @return {LastRelease} The last tagged release or empty object if none is found.
*/
export default ({branch, options: {tagFormat}}, {before} = {}) => {
const [{version, gitTag, channels} = {}] = branch.tags
export default ({ branch, options: { tagFormat } }, { before } = {}) => {
const [{ version, gitTag, channels } = {}] = branch.tags
.filter(
(tag) =>
((branch.type === 'prerelease' && tag.channels.some((channel) => isSameChannel(branch.channel, channel))) ||
((branch.type === "prerelease" && tag.channels.some((channel) => isSameChannel(branch.channel, channel))) ||
!semver.prerelease(tag.version)) &&
(isUndefined(before) || semver.lt(tag.version, before))
)
.sort((a, b) => semver.rcompare(a.version, b.version));
if (gitTag) {
return {version, gitTag, channels, gitHead: gitTag, name: makeTag(tagFormat, version)};
return { version, gitTag, channels, gitHead: gitTag, name: makeTag(tagFormat, version) };
}
return {};
}
};
+10 -10
View File
@@ -1,18 +1,18 @@
import signale from 'signale';
import figures from 'figures';
import signale from "signale";
import figures from "figures";
const {Signale} = signale;
const { Signale } = signale;
export default ({stdout, stderr}) =>
export default ({ stdout, stderr }) =>
new Signale({
config: {displayTimestamp: true, underlineMessage: false, displayLabel: false},
config: { displayTimestamp: true, underlineMessage: false, displayLabel: false },
disabled: false,
interactive: false,
scope: 'semantic-release',
scope: "semantic-release",
stream: [stdout],
types: {
error: {badge: figures.cross, color: 'red', label: '', stream: [stderr]},
log: {badge: figures.info, color: 'magenta', label: '', stream: [stdout]},
success: {badge: figures.tick, color: 'green', label: '', stream: [stdout]},
error: { badge: figures.cross, color: "red", label: "", stream: [stderr] },
log: { badge: figures.info, color: "magenta", label: "", stream: [stdout] },
success: { badge: figures.tick, color: "green", label: "", stream: [stdout] },
},
})
});
+11 -11
View File
@@ -1,20 +1,20 @@
import semver from 'semver';
import {FIRST_RELEASE, FIRSTPRERELEASE} from './definitions/constants.js';
import {getLatestVersion, highest, isSameChannel, tagsToVersions} from './utils.js';
import semver from "semver";
import { FIRST_RELEASE, FIRSTPRERELEASE } from "./definitions/constants.js";
import { getLatestVersion, highest, isSameChannel, tagsToVersions } from "./utils.js";
export default ({branch, nextRelease: {type, channel}, lastRelease, logger}) => {
export default ({ branch, nextRelease: { type, channel }, lastRelease, logger }) => {
let version;
if (lastRelease.version) {
const {major, minor, patch} = semver.parse(lastRelease.version);
const { major, minor, patch } = semver.parse(lastRelease.version);
if (branch.type === 'prerelease') {
if (branch.type === "prerelease") {
if (
semver.prerelease(lastRelease.version) &&
lastRelease.channels.some((lastReleaseChannel) => isSameChannel(lastReleaseChannel, channel))
) {
version = highest(
semver.inc(lastRelease.version, 'prerelease'),
`${semver.inc(getLatestVersion(tagsToVersions(branch.tags), {withPrerelease: true}), type)}-${
semver.inc(lastRelease.version, "prerelease"),
`${semver.inc(getLatestVersion(tagsToVersions(branch.tags), { withPrerelease: true }), type)}-${
branch.prerelease
}.${FIRSTPRERELEASE}`
);
@@ -25,11 +25,11 @@ export default ({branch, nextRelease: {type, channel}, lastRelease, logger}) =>
version = semver.inc(lastRelease.version, type);
}
logger.log('The next release version is %s', version);
logger.log("The next release version is %s", version);
} else {
version = branch.type === 'prerelease' ? `${FIRST_RELEASE}-${branch.prerelease}.${FIRSTPRERELEASE}` : FIRST_RELEASE;
version = branch.type === "prerelease" ? `${FIRST_RELEASE}-${branch.prerelease}.${FIRSTPRERELEASE}` : FIRST_RELEASE;
logger.log(`There is no previous release, the next release version is ${version}`);
}
return version;
}
};
+17 -17
View File
@@ -1,8 +1,8 @@
import {intersection, uniqBy} from 'lodash-es';
import semver from 'semver';
import semverDiff from 'semver-diff';
import getLastRelease from './get-last-release.js';
import {getLowerBound, makeTag} from './utils.js';
import { intersection, uniqBy } from "lodash-es";
import semver from "semver";
import semverDiff from "semver-diff";
import getLastRelease from "./get-last-release.js";
import { getLowerBound, makeTag } from "./utils.js";
/**
* Find releases that have been merged from from a higher branch but not added on the channel of the current branch.
@@ -15,38 +15,38 @@ export default (context) => {
const {
branch,
branches,
options: {tagFormat},
options: { tagFormat },
} = context;
const higherChannels = branches
// Consider only releases of higher branches
.slice(branches.findIndex(({name}) => name === branch.name) + 1)
.slice(branches.findIndex(({ name }) => name === branch.name) + 1)
// Exclude prerelease branches
.filter(({type}) => type !== 'prerelease')
.map(({channel}) => channel || null);
.filter(({ type }) => type !== "prerelease")
.map(({ channel }) => channel || null);
const versiontoAdd = uniqBy(
branch.tags.filter(
({channels, version}) =>
({ channels, version }) =>
!channels.includes(branch.channel || null) &&
intersection(channels, higherChannels).length > 0 &&
(branch.type !== 'maintenance' || semver.gte(version, getLowerBound(branch.mergeRange)))
(branch.type !== "maintenance" || semver.gte(version, getLowerBound(branch.mergeRange)))
),
'version'
"version"
).sort((a, b) => semver.compare(b.version, a.version))[0];
if (versiontoAdd) {
const {version, gitTag, channels} = versiontoAdd;
const lastRelease = getLastRelease(context, {before: version});
const { version, gitTag, channels } = versiontoAdd;
const lastRelease = getLastRelease(context, { before: version });
if (semver.gt(getLastRelease(context).version, version)) {
return;
}
const type = lastRelease.version ? semverDiff(lastRelease.version, version) : 'major';
const type = lastRelease.version ? semverDiff(lastRelease.version, version) : "major";
const name = makeTag(tagFormat, version);
return {
lastRelease,
currentRelease: {type, version, channels, gitTag, name, gitHead: gitTag},
currentRelease: { type, version, channels, gitTag, name, gitHead: gitTag },
nextRelease: {
type,
version,
@@ -57,4 +57,4 @@ export default (context) => {
},
};
}
}
};
+41 -41
View File
@@ -1,12 +1,12 @@
import gitLogParser from 'git-log-parser';
import getStream from 'get-stream';
import {execa} from 'execa';
import debugGit from 'debug';
import {GIT_NOTE_REF} from './definitions/constants.js';
import gitLogParser from "git-log-parser";
import getStream from "get-stream";
import { execa } from "execa";
import debugGit from "debug";
import { GIT_NOTE_REF } from "./definitions/constants.js";
const debug = debugGit('semantic-release:git');
const debug = debugGit("semantic-release:git");
Object.assign(gitLogParser.fields, {hash: 'H', message: 'B', gitTags: 'd', committerDate: {key: 'ci', type: Date}});
Object.assign(gitLogParser.fields, { hash: "H", message: "B", gitTags: "d", committerDate: { key: "ci", type: Date } });
/**
* Get the commit sha for a given tag.
@@ -17,7 +17,7 @@ Object.assign(gitLogParser.fields, {hash: 'H', message: 'B', gitTags: 'd', commi
* @return {String} The commit sha of the tag in parameter or `null`.
*/
export async function getTagHead(tagName, execaOptions) {
return (await execa('git', ['rev-list', '-1', tagName], execaOptions)).stdout;
return (await execa("git", ["rev-list", "-1", tagName], execaOptions)).stdout;
}
/**
@@ -30,8 +30,8 @@ export async function getTagHead(tagName, execaOptions) {
* @throws {Error} If the `git` command fails.
*/
export async function getTags(branch, execaOptions) {
return (await execa('git', ['tag', '--merged', branch], execaOptions)).stdout
.split('\n')
return (await execa("git", ["tag", "--merged", branch], execaOptions)).stdout
.split("\n")
.map((tag) => tag.trim())
.filter(Boolean);
}
@@ -48,11 +48,11 @@ export async function getCommits(from, to, execaOptions) {
return (
await getStream.array(
gitLogParser.parse(
{_: `${from ? from + '..' : ''}${to}`},
{cwd: execaOptions.cwd, env: {...process.env, ...execaOptions.env}}
{ _: `${from ? from + ".." : ""}${to}` },
{ cwd: execaOptions.cwd, env: { ...process.env, ...execaOptions.env } }
)
)
).map(({message, gitTags, ...commit}) => ({...commit, message: message.trim(), gitTags: gitTags.trim()}));
).map(({ message, gitTags, ...commit }) => ({ ...commit, message: message.trim(), gitTags: gitTags.trim() }));
}
/**
@@ -65,8 +65,8 @@ export async function getCommits(from, to, execaOptions) {
* @throws {Error} If the `git` command fails.
*/
export async function getBranches(repositoryUrl, execaOptions) {
return (await execa('git', ['ls-remote', '--heads', repositoryUrl], execaOptions)).stdout
.split('\n')
return (await execa("git", ["ls-remote", "--heads", repositoryUrl], execaOptions)).stdout
.split("\n")
.filter(Boolean)
.map((branch) => branch.match(/^.+refs\/heads\/(?<branch>.+)$/)[1]);
}
@@ -81,7 +81,7 @@ export async function getBranches(repositoryUrl, execaOptions) {
*/
export async function isRefExists(ref, execaOptions) {
try {
return (await execa('git', ['rev-parse', '--verify', ref], execaOptions)).exitCode === 0;
return (await execa("git", ["rev-parse", "--verify", ref], execaOptions)).exitCode === 0;
} catch (error) {
debug(error);
}
@@ -103,30 +103,30 @@ export async function isRefExists(ref, execaOptions) {
*/
export async function fetch(repositoryUrl, branch, ciBranch, execaOptions) {
const isDetachedHead =
(await execa('git', ['rev-parse', '--abbrev-ref', 'HEAD'], {...execaOptions, reject: false})).stdout === 'HEAD';
(await execa("git", ["rev-parse", "--abbrev-ref", "HEAD"], { ...execaOptions, reject: false })).stdout === "HEAD";
try {
await execa(
'git',
"git",
[
'fetch',
'--unshallow',
'--tags',
"fetch",
"--unshallow",
"--tags",
...(branch === ciBranch && !isDetachedHead
? [repositoryUrl]
: ['--update-head-ok', repositoryUrl, `+refs/heads/${branch}:refs/heads/${branch}`]),
: ["--update-head-ok", repositoryUrl, `+refs/heads/${branch}:refs/heads/${branch}`]),
],
execaOptions
);
} catch {
await execa(
'git',
"git",
[
'fetch',
'--tags',
"fetch",
"--tags",
...(branch === ciBranch && !isDetachedHead
? [repositoryUrl]
: ['--update-head-ok', repositoryUrl, `+refs/heads/${branch}:refs/heads/${branch}`]),
: ["--update-head-ok", repositoryUrl, `+refs/heads/${branch}:refs/heads/${branch}`]),
],
execaOptions
);
@@ -142,12 +142,12 @@ export async function fetch(repositoryUrl, branch, ciBranch, execaOptions) {
export async function fetchNotes(repositoryUrl, execaOptions) {
try {
await execa(
'git',
['fetch', '--unshallow', repositoryUrl, `+refs/notes/${GIT_NOTE_REF}:refs/notes/${GIT_NOTE_REF}`],
"git",
["fetch", "--unshallow", repositoryUrl, `+refs/notes/${GIT_NOTE_REF}:refs/notes/${GIT_NOTE_REF}`],
execaOptions
);
} catch {
await execa('git', ['fetch', repositoryUrl, `+refs/notes/${GIT_NOTE_REF}:refs/notes/${GIT_NOTE_REF}`], {
await execa("git", ["fetch", repositoryUrl, `+refs/notes/${GIT_NOTE_REF}:refs/notes/${GIT_NOTE_REF}`], {
...execaOptions,
reject: false,
});
@@ -162,7 +162,7 @@ export async function fetchNotes(repositoryUrl, execaOptions) {
* @return {String} the sha of the HEAD commit.
*/
export async function getGitHead(execaOptions) {
return (await execa('git', ['rev-parse', 'HEAD'], execaOptions)).stdout;
return (await execa("git", ["rev-parse", "HEAD"], execaOptions)).stdout;
}
/**
@@ -174,7 +174,7 @@ export async function getGitHead(execaOptions) {
*/
export async function repoUrl(execaOptions) {
try {
return (await execa('git', ['config', '--get', 'remote.origin.url'], execaOptions)).stdout;
return (await execa("git", ["config", "--get", "remote.origin.url"], execaOptions)).stdout;
} catch (error) {
debug(error);
}
@@ -189,7 +189,7 @@ export async function repoUrl(execaOptions) {
*/
export async function isGitRepo(execaOptions) {
try {
return (await execa('git', ['rev-parse', '--git-dir'], execaOptions)).exitCode === 0;
return (await execa("git", ["rev-parse", "--git-dir"], execaOptions)).exitCode === 0;
} catch (error) {
debug(error);
}
@@ -206,7 +206,7 @@ export async function isGitRepo(execaOptions) {
*/
export async function verifyAuth(repositoryUrl, branch, execaOptions) {
try {
await execa('git', ['push', '--dry-run', '--no-verify', repositoryUrl, `HEAD:${branch}`], execaOptions);
await execa("git", ["push", "--dry-run", "--no-verify", repositoryUrl, `HEAD:${branch}`], execaOptions);
} catch (error) {
debug(error);
throw error;
@@ -223,7 +223,7 @@ export async function verifyAuth(repositoryUrl, branch, execaOptions) {
* @throws {Error} if the tag creation failed.
*/
export async function tag(tagName, ref, execaOptions) {
await execa('git', ['tag', tagName, ref], execaOptions);
await execa("git", ["tag", tagName, ref], execaOptions);
}
/**
@@ -235,7 +235,7 @@ export async function tag(tagName, ref, execaOptions) {
* @throws {Error} if the push failed.
*/
export async function push(repositoryUrl, execaOptions) {
await execa('git', ['push', '--tags', repositoryUrl], execaOptions);
await execa("git", ["push", "--tags", repositoryUrl], execaOptions);
}
/**
@@ -247,7 +247,7 @@ export async function push(repositoryUrl, execaOptions) {
* @throws {Error} if the push failed.
*/
export async function pushNotes(repositoryUrl, execaOptions) {
await execa('git', ['push', repositoryUrl, `refs/notes/${GIT_NOTE_REF}`], execaOptions);
await execa("git", ["push", repositoryUrl, `refs/notes/${GIT_NOTE_REF}`], execaOptions);
}
/**
@@ -260,7 +260,7 @@ export async function pushNotes(repositoryUrl, execaOptions) {
*/
export async function verifyTagName(tagName, execaOptions) {
try {
return (await execa('git', ['check-ref-format', `refs/tags/${tagName}`], execaOptions)).exitCode === 0;
return (await execa("git", ["check-ref-format", `refs/tags/${tagName}`], execaOptions)).exitCode === 0;
} catch (error) {
debug(error);
}
@@ -276,7 +276,7 @@ export async function verifyTagName(tagName, execaOptions) {
*/
export async function verifyBranchName(branch, execaOptions) {
try {
return (await execa('git', ['check-ref-format', `refs/heads/${branch}`], execaOptions)).exitCode === 0;
return (await execa("git", ["check-ref-format", `refs/heads/${branch}`], execaOptions)).exitCode === 0;
} catch (error) {
debug(error);
}
@@ -294,7 +294,7 @@ export async function verifyBranchName(branch, execaOptions) {
export async function isBranchUpToDate(repositoryUrl, branch, execaOptions) {
return (
(await getGitHead(execaOptions)) ===
(await execa('git', ['ls-remote', '--heads', repositoryUrl, branch], execaOptions)).stdout.match(/^(?<ref>\w+)?/)[1]
(await execa("git", ["ls-remote", "--heads", repositoryUrl, branch], execaOptions)).stdout.match(/^(?<ref>\w+)?/)[1]
);
}
@@ -308,7 +308,7 @@ export async function isBranchUpToDate(repositoryUrl, branch, execaOptions) {
*/
export async function getNote(ref, execaOptions) {
try {
return JSON.parse((await execa('git', ['notes', '--ref', GIT_NOTE_REF, 'show', ref], execaOptions)).stdout);
return JSON.parse((await execa("git", ["notes", "--ref", GIT_NOTE_REF, "show", ref], execaOptions)).stdout);
} catch (error) {
if (error.exitCode === 1) {
return {};
@@ -327,5 +327,5 @@ export async function getNote(ref, execaOptions) {
* @param {Object} [execaOpts] Options to pass to `execa`.
*/
export async function addNote(note, ref, execaOptions) {
await execa('git', ['notes', '--ref', GIT_NOTE_REF, 'add', '-f', '-m', JSON.stringify(note), ref], execaOptions);
await execa("git", ["notes", "--ref", GIT_NOTE_REF, "add", "-f", "-m", JSON.stringify(note), ref], execaOptions);
}
+6 -6
View File
@@ -1,10 +1,10 @@
import {escapeRegExp, isString, size} from 'lodash-es';
import {SECRET_MIN_SIZE, SECRET_REPLACEMENT} from './definitions/constants.js';
import { escapeRegExp, isString, size } from "lodash-es";
import { SECRET_MIN_SIZE, SECRET_REPLACEMENT } from "./definitions/constants.js";
export default (env) => {
const toReplace = Object.keys(env).filter((envVar) => {
// https://github.com/semantic-release/semantic-release/issues/1558
if (envVar === 'GOPRIVATE') {
if (envVar === "GOPRIVATE") {
return false;
}
@@ -12,9 +12,9 @@ export default (env) => {
});
const regexp = new RegExp(
toReplace.map((envVar) => `${escapeRegExp(env[envVar])}|${escapeRegExp(encodeURI(env[envVar]))}`).join('|'),
'g'
toReplace.map((envVar) => `${escapeRegExp(env[envVar])}|${escapeRegExp(encodeURI(env[envVar]))}`).join("|"),
"g"
);
return (output) =>
output && isString(output) && toReplace.length > 0 ? output.toString().replace(regexp, SECRET_REPLACEMENT) : output;
}
};
+12 -12
View File
@@ -1,6 +1,6 @@
import {isFunction, template, union} from 'lodash-es';
import semver from 'semver';
import hideSensitive from './hide-sensitive.js';
import { isFunction, template, union } from "lodash-es";
import semver from "semver";
import hideSensitive from "./hide-sensitive.js";
export function extractErrors(err) {
return err && err.errors ? [...err.errors] : [err];
@@ -19,7 +19,7 @@ export function hideSensitiveValues(env, objs) {
}
export function tagsToVersions(tags) {
return tags.map(({version}) => version);
return tags.map(({ version }) => version);
}
export function isMajorRange(range) {
@@ -33,16 +33,16 @@ export function isMaintenanceRange(range) {
export function getUpperBound(range) {
const result = semver.valid(range)
? range
: ((semver.validRange(range) || '').match(/<(?<upperBound>\d+\.\d+\.\d+(-\d+)?)$/) || [])[1];
: ((semver.validRange(range) || "").match(/<(?<upperBound>\d+\.\d+\.\d+(-\d+)?)$/) || [])[1];
return result
? // https://github.com/npm/node-semver/issues/322
result.replace(/-\d+$/, '')
result.replace(/-\d+$/, "")
: result;
}
export function getLowerBound(range) {
return ((semver.validRange(range) || '').match(/(?<lowerBound>\d+\.\d+\.\d+)/) || [])[1];
return ((semver.validRange(range) || "").match(/(?<lowerBound>\d+\.\d+\.\d+)/) || [])[1];
}
export function highest(version1, version2) {
@@ -53,16 +53,16 @@ export function lowest(version1, version2) {
return version1 && version2 ? (semver.lt(version1, version2) ? version1 : version2) : version1 || version2;
}
export function getLatestVersion(versions, {withPrerelease} = {}) {
export function getLatestVersion(versions, { withPrerelease } = {}) {
return versions.filter((version) => withPrerelease || !semver.prerelease(version)).sort(semver.rcompare)[0];
}
export function getEarliestVersion(versions, {withPrerelease} = {}) {
export function getEarliestVersion(versions, { withPrerelease } = {}) {
return versions.filter((version) => withPrerelease || !semver.prerelease(version)).sort(semver.compare)[0];
}
export function getFirstVersion(versions, lowerBranches) {
const lowerVersion = union(...lowerBranches.map(({tags}) => tagsToVersions(tags))).sort(semver.rcompare);
const lowerVersion = union(...lowerBranches.map(({ tags }) => tagsToVersions(tags))).sort(semver.rcompare);
if (lowerVersion[0]) {
return versions.sort(semver.compare).find((version) => semver.gt(version, lowerVersion[0]));
}
@@ -71,11 +71,11 @@ export function getFirstVersion(versions, lowerBranches) {
}
export function getRange(min, max) {
return `>=${min}${max ? ` <${max}` : ''}`;
return `>=${min}${max ? ` <${max}` : ""}`;
}
export function makeTag(tagFormat, version) {
return template(tagFormat)({version});
return template(tagFormat)({ version });
}
export function isSameChannel(channel, otherChannel) {
+14 -14
View File
@@ -1,43 +1,43 @@
import {isPlainObject, isString, template} from 'lodash-es';
import AggregateError from 'aggregate-error';
import {isGitRepo, verifyTagName} from './git.js';
import getError from './get-error.js';
import { isPlainObject, isString, template } from "lodash-es";
import AggregateError from "aggregate-error";
import { isGitRepo, verifyTagName } from "./git.js";
import getError from "./get-error.js";
export default async (context) => {
const {
cwd,
env,
options: {repositoryUrl, tagFormat, branches},
options: { repositoryUrl, tagFormat, branches },
} = context;
const errors = [];
if (!(await isGitRepo({cwd, env}))) {
errors.push(getError('ENOGITREPO', {cwd}));
if (!(await isGitRepo({ cwd, env }))) {
errors.push(getError("ENOGITREPO", { cwd }));
} else if (!repositoryUrl) {
errors.push(getError('ENOREPOURL'));
errors.push(getError("ENOREPOURL"));
}
// Verify that compiling the `tagFormat` produce a valid Git tag
if (!(await verifyTagName(template(tagFormat)({version: '0.0.0'})))) {
errors.push(getError('EINVALIDTAGFORMAT', context));
if (!(await verifyTagName(template(tagFormat)({ version: "0.0.0" })))) {
errors.push(getError("EINVALIDTAGFORMAT", context));
}
// Verify the `tagFormat` contains the variable `version` by compiling the `tagFormat` template
// with a space as the `version` value and verify the result contains the space.
// The space is used as it's an invalid tag character, so it's guaranteed to no be present in the `tagFormat`.
if ((template(tagFormat)({version: ' '}).match(/ /g) || []).length !== 1) {
errors.push(getError('ETAGNOVERSION', context));
if ((template(tagFormat)({ version: " " }).match(/ /g) || []).length !== 1) {
errors.push(getError("ETAGNOVERSION", context));
}
branches.forEach((branch) => {
if (
!((isString(branch) && branch.trim()) || (isPlainObject(branch) && isString(branch.name) && branch.name.trim()))
) {
errors.push(getError('EINVALIDBRANCH', {branch}));
errors.push(getError("EINVALIDBRANCH", { branch }));
}
});
if (errors.length > 0) {
throw new AggregateError(errors);
}
}
};