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

feat(esm): convert to esm #2569

Merged
merged 21 commits into from Nov 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
21a7b60
wip(esm): initial module type conversion
travi Aug 27, 2022
38ac59d
wip(esm): updated dynamic imports in tests and updated testdouble stubs
travi Aug 27, 2022
2736244
wip(esm): updated the cli module
travi Aug 27, 2022
23862f7
Merge branch 'master' of github.com:semantic-release/semantic-release…
travi Sep 18, 2022
7532da6
fix(cli): imported debug properly
travi Sep 18, 2022
1303626
fix(dependencies): upgraded most of the dependencies that are now esm…
travi Sep 23, 2022
c3d0d4e
fix(tempy): upgraded to the esm version
travi Sep 24, 2022
e572643
fix(aggregate-error): accounted for `.errors` when extracting errors
travi Sep 25, 2022
43adf8b
test(aggregate-error): accounted for `.errors` for plugins
travi Sep 25, 2022
6e8863d
test(aggregate-error): accounted for `.errors` for config verification
travi Sep 25, 2022
00683dc
chore(ava): upgraded to the latest version
travi Sep 25, 2022
56a6679
test(branches): made the tests run serially since the stub setup was …
travi Oct 7, 2022
f27131b
test(plugins): focused plugin loading on cjs plugins for the time being
travi Oct 7, 2022
5b064cd
fix(env-ci): upgraded to the ESM-only beta version of env-ci
travi Oct 7, 2022
1e424a0
test(plugins): referenced plugins with extension in the tests for nor…
travi Oct 7, 2022
0a14f4f
refactor(bin): updated the binary file to esm
travi Oct 8, 2022
6005f8c
test(get-config): fixed stubbing of the plugins module
travi Nov 4, 2022
75c6750
fix(get-config): loaded config with require rather than import
travi Nov 4, 2022
0739d7d
fix(get-config): awaited the the loading of extended config
travi Nov 5, 2022
9ab2669
docs(contributors): added myself to the contributors list
travi Nov 5, 2022
e53693b
Merge branch 'master' of github.com:semantic-release/semantic-release…
travi Nov 9, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
28 changes: 15 additions & 13 deletions bin/semantic-release.js
@@ -1,20 +1,22 @@
#!/usr/bin/env node

// Bad news: We have to write plain ES5 in this file
// Good news: It's the only file of the entire project

/* eslint-disable no-var */

var semver = require('semver');
var execa = require('execa');
var findVersions = require('find-versions');
var pkg = require('../package.json');
import semver from 'semver';
import { execa } from 'execa';
import findVersions from 'find-versions';
import cli from '../cli.js';
import {createRequire} from 'node:module';

const require = createRequire(import.meta.url);
const { engines } = require('../package.json');
const { satisfies, lt } = semver;

var MIN_GIT_VERSION = '2.7.1';
const MIN_GIT_VERSION = '2.7.1';

if (!semver.satisfies(process.version, pkg.engines.node)) {
if (!satisfies(process.version, engines.node)) {
console.error(
`[semantic-release]: node version ${pkg.engines.node} is required. Found ${process.version}.
`[semantic-release]: node version ${engines.node} is required. Found ${process.version}.

See https://github.com/semantic-release/semantic-release/blob/master/docs/support/node-version.md for more details and solutions.`
);
Expand All @@ -23,8 +25,8 @@ See https://github.com/semantic-release/semantic-release/blob/master/docs/suppor

execa('git', ['--version'])
.then(({stdout}) => {
var gitVersion = findVersions(stdout)[0];
if (semver.lt(gitVersion, MIN_GIT_VERSION)) {
const gitVersion = findVersions(stdout)[0];
if (lt(gitVersion, MIN_GIT_VERSION)) {
console.error(`[semantic-release]: Git version ${MIN_GIT_VERSION} is required. Found ${gitVersion}.`);
process.exit(1);
}
Expand All @@ -36,7 +38,7 @@ execa('git', ['--version'])
});

// Node 10+ from this point on
require('../cli')()
cli()
.then((exitCode) => {
process.exitCode = exitCode;
})
Expand Down
22 changes: 11 additions & 11 deletions cli.js
@@ -1,6 +1,7 @@
const {argv, env, stderr} = require('process'); // eslint-disable-line node/prefer-global/process
const util = require('util');
const hideSensitive = require('./lib/hide-sensitive');
import util from 'node:util';
import yargs from 'yargs';
import {hideBin} from 'yargs/helpers';
import hideSensitive from './lib/hide-sensitive.js';

const stringList = {
type: 'string',
Expand All @@ -11,8 +12,8 @@ const stringList = {
: values.reduce((values, value) => values.concat(value.split(',').map((value) => value.trim())), []),
};

module.exports = async () => {
const cli = require('yargs')
export default async () => {
const cli = yargs(hideBin(process.argv))
.command('$0', 'Run automated package publishing', (yargs) => {
yargs.demandCommand(0, 0).usage(`Run automated package publishing

Expand All @@ -36,29 +37,28 @@ Usage:
.option('debug', {describe: 'Output debugging information', type: 'boolean', group: 'Options'})
.option('d', {alias: 'dry-run', describe: 'Skip publishing', type: 'boolean', group: 'Options'})
.option('h', {alias: 'help', group: 'Options'})
.option('v', {alias: 'version', group: 'Options'})
.strict(false)
.exitProcess(false);

try {
const {help, version, ...options} = cli.parse(argv.slice(2));
const {help, version, ...options} = cli.parse(process.argv.slice(2));

if (Boolean(help) || Boolean(version)) {
return 0;
}

if (options.debug) {
// Debug must be enabled before other requires in order to work
require('debug').enable('semantic-release:*');
(await import('debug')).default.enable('semantic-release:*');
}

await require('.')(options);
await (await import('./index.js')).default(options);
return 0;
} catch (error) {
if (error.name !== 'YError') {
stderr.write(hideSensitive(env)(util.inspect(error, {colors: true})));
process.stderr.write(hideSensitive(process.env)(util.inspect(error, {colors: true})));
}

return 1;
}
};
}
51 changes: 27 additions & 24 deletions index.js
@@ -1,24 +1,27 @@
const {pick} = require('lodash');
const marked = require('marked');
const envCi = require('env-ci');
const hookStd = require('hook-std');
const semver = require('semver');
const AggregateError = require('aggregate-error');
import {createRequire} from 'node:module';
import {pick} from 'lodash-es';
import * as marked from 'marked';
import envCi from 'env-ci';
import {hookStdout} from 'hook-std';
import semver from 'semver';
import AggregateError from 'aggregate-error';
import hideSensitive from './lib/hide-sensitive.js';
import getConfig from './lib/get-config.js';
import verify from './lib/verify.js';
import getNextVersion from './lib/get-next-version.js';
import getCommits from './lib/get-commits.js';
import getLastRelease from './lib/get-last-release.js';
import getReleaseToAdd from './lib/get-release-to-add.js';
import {extractErrors, makeTag} from './lib/utils.js';
import getGitAuthUrl from './lib/get-git-auth-url.js';
import getBranches from './lib/branches/index.js';
import getLogger from './lib/get-logger.js';
import {addNote, getGitHead, getTagHead, isBranchUpToDate, push, pushNotes, tag, verifyAuth} from './lib/git.js';
import getError from './lib/get-error.js';
import {COMMIT_EMAIL, COMMIT_NAME} from './lib/definitions/constants.js';

const require = createRequire(import.meta.url);
const pkg = require('./package.json');
const hideSensitive = require('./lib/hide-sensitive');
const getConfig = require('./lib/get-config');
const verify = require('./lib/verify');
const getNextVersion = require('./lib/get-next-version');
const getCommits = require('./lib/get-commits');
const getLastRelease = require('./lib/get-last-release');
const getReleaseToAdd = require('./lib/get-release-to-add');
const {extractErrors, makeTag} = require('./lib/utils');
const getGitAuthUrl = require('./lib/get-git-auth-url');
const getBranches = require('./lib/branches');
const getLogger = require('./lib/get-logger');
const {verifyAuth, isBranchUpToDate, getGitHead, tag, push, pushNotes, getTagHead, addNote} = require('./lib/git');
const getError = require('./lib/get-error');
const {COMMIT_NAME, COMMIT_EMAIL} = require('./lib/definitions/constants');

let markedOptionsSet = false;
async function terminalOutput(text) {
Expand All @@ -41,7 +44,7 @@ async function run(context, plugins) {
logger.warn('This run was not triggered in a known CI environment, running in dry-run mode.');
options.dryRun = true;
} else {
// When running on CI, set the commits author and commiter info and prevent the `git` CLI to prompt for username/password. See #703.
// When running on CI, set the commits author and committer info and prevent the `git` CLI to prompt for username/password. See #703.
Object.assign(env, {
GIT_AUTHOR_NAME: COMMIT_NAME,
GIT_AUTHOR_EMAIL: COMMIT_EMAIL,
Expand Down Expand Up @@ -247,8 +250,8 @@ async function callFail(context, plugins, err) {
}
}

module.exports = async (cliOptions = {}, {cwd = process.cwd(), env = process.env, stdout, stderr} = {}) => {
const {unhook} = hookStd(
export default async (cliOptions = {}, {cwd = process.cwd(), env = process.env, stdout, stderr} = {}) => {
const {unhook} = hookStdout(
{silent: false, streams: [process.stdout, process.stderr, stdout, stderr].filter(Boolean)},
hideSensitive(env)
);
Expand Down Expand Up @@ -278,4 +281,4 @@ module.exports = async (cliOptions = {}, {cwd = process.cwd(), env = process.env
unhook();
throw error;
}
};
}
10 changes: 5 additions & 5 deletions lib/branches/expand.js
@@ -1,8 +1,8 @@
const {isString, remove, omit, mapValues, template} = require('lodash');
const micromatch = require('micromatch');
const {getBranches} = require('../git');
import {isString, mapValues, omit, remove, template} from 'lodash-es';
import micromatch from 'micromatch';
import {getBranches} from '../git.js';

module.exports = async (repositoryUrl, {cwd}, branches) => {
export default async (repositoryUrl, {cwd}, branches) => {
const gitBranches = await getBranches(repositoryUrl, {cwd});

return branches.reduce(
Expand All @@ -15,4 +15,4 @@ module.exports = async (repositoryUrl, {cwd}, branches) => {
],
[]
);
};
}
17 changes: 10 additions & 7 deletions lib/branches/get-tags.js
@@ -1,10 +1,13 @@
const {template, escapeRegExp} = require('lodash');
const semver = require('semver');
const pReduce = require('p-reduce');
const debug = require('debug')('semantic-release:get-tags');
const {getTags, getNote} = require('../../lib/git');
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';

module.exports = async ({cwd, env, options: {tagFormat}}, branches) => {
const debug = debugTags('semantic-release:get-tags');


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,
Expand All @@ -30,4 +33,4 @@ module.exports = async ({cwd, env, options: {tagFormat}}, branches) => {
},
[]
);
};
}
22 changes: 11 additions & 11 deletions lib/branches/index.js
@@ -1,14 +1,14 @@
const {isString, isRegExp} = require('lodash');
const AggregateError = require('aggregate-error');
const pEachSeries = require('p-each-series');
const DEFINITIONS = require('../definitions/branches');
const getError = require('../get-error');
const {fetch, fetchNotes, verifyBranchName} = require('../git');
const expand = require('./expand');
const getTags = require('./get-tags');
const normalize = require('./normalize');
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';

module.exports = async (repositoryUrl, ciBranch, context) => {
export default async (repositoryUrl, ciBranch, context) => {
const {cwd, env} = context;

const remoteBranches = await expand(
Expand Down Expand Up @@ -68,4 +68,4 @@ module.exports = async (repositoryUrl, ciBranch, context) => {
}

return [...result.maintenance, ...result.release, ...result.prerelease];
};
}
29 changes: 13 additions & 16 deletions lib/branches/normalize.js
@@ -1,19 +1,18 @@
const {sortBy, isNil} = require('lodash');
const semverDiff = require('semver-diff');
const {FIRST_RELEASE, RELEASE_TYPE} = require('../definitions/constants');
const {
tagsToVersions,
isMajorRange,
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,
getUpperBound,
getLowerBound,
highest,
isMajorRange,
lowest,
getLatestVersion,
getFirstVersion,
getRange,
} = require('../utils');
tagsToVersions
} from '../utils.js';

function maintenance({maintenance, release}) {
export function maintenance({maintenance, release}) {
return sortBy(
maintenance.map(({name, range, channel, ...rest}) => ({
...rest,
Expand Down Expand Up @@ -55,7 +54,7 @@ function maintenance({maintenance, release}) {
});
}

function release({release}) {
export function release({release}) {
if (release.length === 0) {
return release;
}
Expand Down Expand Up @@ -89,7 +88,7 @@ function release({release}) {
});
}

function prerelease({prerelease}) {
export function prerelease({prerelease}) {
return prerelease.map(({name, prerelease, channel, tags, ...rest}) => {
const preid = prerelease === true ? name : prerelease;
return {
Expand All @@ -102,5 +101,3 @@ function prerelease({prerelease}) {
};
});
}

module.exports = {maintenance, release, prerelease};
14 changes: 6 additions & 8 deletions lib/definitions/branches.js
@@ -1,24 +1,22 @@
const {isNil, uniqBy} = require('lodash');
const semver = require('semver');
const {isMaintenanceRange} = require('../utils');
import {isNil, uniqBy} from 'lodash-es';
import semver from 'semver';
import {isMaintenanceRange} from '../utils.js';

const maintenance = {
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,
};

const prerelease = {
export const 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,
};

const release = {
export const release = {
// eslint-disable-next-line unicorn/no-fn-reference-in-iterator
filter: (branch) => !maintenance.filter(branch) && !prerelease.filter(branch),
branchesValidator: (branches) => branches.length <= 3 && branches.length > 0,
};

module.exports = {maintenance, prerelease, release};
30 changes: 9 additions & 21 deletions lib/definitions/constants.js
@@ -1,29 +1,17 @@
const RELEASE_TYPE = ['patch', 'minor', 'major'];
export const RELEASE_TYPE = ['patch', 'minor', 'major'];

const FIRST_RELEASE = '1.0.0';
export const FIRST_RELEASE = '1.0.0';

const FIRSTPRERELEASE = '1';
export const FIRSTPRERELEASE = '1';

const COMMIT_NAME = 'semantic-release-bot';
export const COMMIT_NAME = 'semantic-release-bot';

const COMMIT_EMAIL = 'semantic-release-bot@martynus.net';
export const COMMIT_EMAIL = 'semantic-release-bot@martynus.net';

const RELEASE_NOTES_SEPARATOR = '\n\n';
export const RELEASE_NOTES_SEPARATOR = '\n\n';

const SECRET_REPLACEMENT = '[secure]';
export const SECRET_REPLACEMENT = '[secure]';

const SECRET_MIN_SIZE = 5;
export const SECRET_MIN_SIZE = 5;

const GIT_NOTE_REF = 'semantic-release';

module.exports = {
RELEASE_TYPE,
FIRST_RELEASE,
FIRSTPRERELEASE,
COMMIT_NAME,
COMMIT_EMAIL,
RELEASE_NOTES_SEPARATOR,
SECRET_REPLACEMENT,
SECRET_MIN_SIZE,
GIT_NOTE_REF,
};
export const GIT_NOTE_REF = 'semantic-release';