comty/scripts/release.js
2020-12-14 20:29:29 +01:00

185 lines
5.3 KiB
JavaScript

const { yParser, execa, chalk } = require('@nodecorejs/libs');
const { getDevRuntimeEnvs } = require('@nodecorejs/dot-runtime');
const { join } = require('path');
const { writeFileSync } = require('fs');
const newGithubReleaseUrl = require('new-github-release-url');
const open = require('open');
const exec = require('./utils/exec');
const getPackages = require('./utils/getPackages');
const isNextVersion = require('./utils/isNextVersion');
const { getChangelog } = require('./utils/changelog');
const { bumpVersion, parsedVersionToString } = require('./updateVersion')
const cwd = process.cwd();
const args = yParser(process.argv.slice(2));
const lernaCli = require.resolve('lerna/cli');
function printErrorAndExit(message) {
console.error(chalk.red(message));
process.exit(1);
}
function logStep(name) {
console.log(`${chalk.gray('>> Release:')} ${chalk.magenta.bold(name)}`);
}
async function release() {
// Check git status
if (!args.skipGitStatusCheck) {
const gitStatus = execa.sync('git', ['status', '--porcelain']).stdout;
if (gitStatus.length) {
printErrorAndExit(`Your git status is not clean. Aborting.`);
}
} else {
logStep(
'git status check is skipped, since --skip-git-status-check is supplied',
);
}
// get release notes
logStep('get release notes');
const releaseNotes = await getChangelog();
console.log(releaseNotes(''));
// Check npm registry
logStep('check npm registry');
const userRegistry = execa.sync(/^win/.test(process.platform) ? 'npm.cmd' : 'npm', ['config', 'get', 'registry']).stdout;
if (userRegistry.includes('https://registry.yarnpkg.com/')) {
printErrorAndExit(
`Release failed, please use ${chalk.blue('npm run release')}.`,
);
}
if (!userRegistry.includes('https://registry.npmjs.org/')) {
const registry = chalk.blue('https://registry.npmjs.org/');
printErrorAndExit(`Release failed, npm registry must be ${registry}.`);
}
let updated = null;
if (!args.publishOnly) {
// Get updated packages
logStep('check updated packages');
const updatedStdout = execa.sync(lernaCli, ['changed']).stdout;
updated = updatedStdout
.split('\n')
.map((pkg) => {
if (pkg === 'nodecore') return pkg;
else return pkg.split('/')[1];
})
.filter(Boolean);
if (!updated.length) {
printErrorAndExit('Release failed, no updated package is updated.');
}
// Clean
logStep('clean');
// Build
if (!args.skipBuild) {
logStep('build');
await exec('npm', ['run', 'build']);
require('./tsIngoreDefineConfig');
} else {
logStep('build is skipped, since args.skipBuild is supplied');
}
// Bump version
bumpVersion(["minor"])
const currVersion = require('../.version');
// Sync version to root package.json
logStep('sync version to root package.json');
const rootPkg = require('../package');
Object.keys(rootPkg.devDependencies).forEach((name) => {
if (
name.startsWith('@nodecorejs/') &&
!name.startsWith('@nodecorejs/p')
) {
rootPkg.devDependencies[name] = currVersion;
}
});
writeFileSync(
join(__dirname, '..', 'package.json'),
JSON.stringify(rootPkg, null, 2) + '\n',
'utf-8',
);
// Commit
const commitMessage = `release: v${currVersion}`;
logStep(`git commit with ${chalk.blue(commitMessage)}`);
await exec('git', ['commit', '--all', '--message', commitMessage]);
// Git Tag
logStep(`git tag v${currVersion}`);
await exec('git', ['tag', `v${currVersion}`]);
// Push
logStep(`git push`);
await exec('git', ['push', 'origin', 'master', '--tags']);
}
// Publish
// Umi must be the latest.
const runtimeEnvs = getDevRuntimeEnvs()
if (!runtimeEnvs.headPackage) {
return printErrorAndExit(`headPackage is missing on runtime`);
}
const pkgs = args.publishOnly ? getPackages() : updated;
logStep(`publish packages: ${chalk.blue(pkgs.join(', '))}`);
const currVersion = require('../lerna').version;
const isNext = isNextVersion(currVersion);
pkgs.sort((a) => {
return a === runtimeEnvs.headPackage ? 1 : -1;
})
.forEach((pkg, index) => {
const pkgPath = join(cwd, 'packages', pkg);
const { name, version } = require(join(pkgPath, 'package.json'));
if (version === currVersion) {
console.log(
`[${index + 1}/${pkgs.length}] Publish package ${name} ${isNext ? 'with next tag' : ''
}`,
);
const cliArgs = isNext ? ['publish', '--tag', 'next'] : ['publish'];
try {
const { stdout } = execa.sync('npm', cliArgs, {
cwd: pkgPath,
})
console.log(stdout);
} catch (error) {
console.log(`❌ Failed to publish > ${pkg} >`, err)
}
}
});
if (!runtimeEnvs.originGit) {
return printErrorAndExit(`originGit is missing on runtime`);
}
logStep('create github release');
const tag = `v${currVersion}`;
const changelog = releaseNotes(tag);
console.log(changelog);
const url = newGithubReleaseUrl({
repoUrl: runtimeEnvs.originGit,
tag,
body: changelog,
isPrerelease: isNext,
});
try {
await open(url);
} catch (error) {
console.log("Try opening url >", url)
}
logStep('done');
}
release().catch((err) => {
console.error(err);
process.exit(1);
});