98 lines
3.5 KiB
JavaScript
98 lines
3.5 KiB
JavaScript
const marked = require('marked');
|
||
const TerminalRenderer = require('marked-terminal');
|
||
const envCi = require('env-ci');
|
||
const getConfig = require('./lib/get-config');
|
||
const getNextVersion = require('./lib/get-next-version');
|
||
const getCommits = require('./lib/get-commits');
|
||
const logger = require('./lib/logger');
|
||
const {gitHead: getGitHead, isGitRepo} = require('./lib/git');
|
||
|
||
module.exports = async opts => {
|
||
const {isCi, branch, isPr} = envCi();
|
||
|
||
if (!isCi && !opts.dryRun && !opts.noCi) {
|
||
logger.log('This run was not triggered in a known CI environment, running in dry-run mode.');
|
||
opts.dryRun = true;
|
||
}
|
||
|
||
if (isCi && isPr && !opts.noCi) {
|
||
logger.log("This run was triggered by a pull request and therefore a new version won't be published.");
|
||
return;
|
||
}
|
||
|
||
if (!await isGitRepo()) {
|
||
logger.error('Semantic-release must run from a git repository.');
|
||
return;
|
||
}
|
||
|
||
const config = await getConfig(opts, logger);
|
||
const {plugins, options} = config;
|
||
|
||
if (branch !== options.branch) {
|
||
logger.log(
|
||
`This test run was triggered on the branch ${branch}, while semantic-release is configured to only publish from ${
|
||
options.branch
|
||
}, therefore a new version won’t be published.`
|
||
);
|
||
return;
|
||
}
|
||
|
||
logger.log('Run automated release from branch %s', options.branch);
|
||
|
||
logger.log('Call plugin %s', 'verify-conditions');
|
||
await plugins.verifyConditions({options, logger});
|
||
|
||
logger.log('Call plugin %s', 'get-last-release');
|
||
const {commits, lastRelease} = await getCommits(
|
||
await plugins.getLastRelease({options, logger}),
|
||
options.branch,
|
||
logger
|
||
);
|
||
|
||
logger.log('Call plugin %s', 'analyze-commits');
|
||
const type = await plugins.analyzeCommits({
|
||
options,
|
||
logger,
|
||
lastRelease,
|
||
commits: commits.filter(commit => !/\[skip\s+release\]|\[release\s+skip\]/i.test(commit.message)),
|
||
});
|
||
if (!type) {
|
||
logger.log('There are no relevant changes, so no new version is released.');
|
||
return;
|
||
}
|
||
const version = getNextVersion(type, lastRelease, logger);
|
||
const nextRelease = {type, version, gitHead: await getGitHead(), gitTag: `v${version}`};
|
||
|
||
logger.log('Call plugin %s', 'verify-release');
|
||
await plugins.verifyRelease({options, logger, lastRelease, commits, nextRelease});
|
||
|
||
const generateNotesParam = {options, logger, lastRelease, commits, nextRelease};
|
||
|
||
if (options.dryRun) {
|
||
logger.log('Call plugin %s', 'generate-notes');
|
||
const notes = await plugins.generateNotes(generateNotesParam);
|
||
marked.setOptions({renderer: new TerminalRenderer()});
|
||
logger.log('Release note for version %s:\n', nextRelease.version);
|
||
process.stdout.write(`${marked(notes)}\n`);
|
||
} else {
|
||
logger.log('Call plugin %s', 'generateNotes');
|
||
nextRelease.notes = await plugins.generateNotes(generateNotesParam);
|
||
|
||
logger.log('Call plugin %s', 'publish');
|
||
await plugins.publish({options, logger, lastRelease, commits, nextRelease}, async prevInput => {
|
||
const newGitHead = await getGitHead();
|
||
// If previous publish plugin has created a commit (gitHead changed)
|
||
if (prevInput.nextRelease.gitHead !== newGitHead) {
|
||
nextRelease.gitHead = newGitHead;
|
||
// Regenerate the release notes
|
||
logger.log('Call plugin %s', 'generateNotes');
|
||
nextRelease.notes = await plugins.generateNotes(generateNotesParam);
|
||
}
|
||
// Call the next publish plugin with the updated `nextRelease`
|
||
return {options, logger, lastRelease, commits, nextRelease};
|
||
});
|
||
logger.log('Published release: %s', nextRelease.version);
|
||
}
|
||
return true;
|
||
};
|