diff --git a/docs/index.md b/docs/index.md index 4adc02b92..ebc822b46 100644 --- a/docs/index.md +++ b/docs/index.md @@ -11,6 +11,7 @@ - [auto version](pages/auto-version.md) - [auto changelog](pages/auto-changelog.md) - [auto release](pages/auto-release.md) + - [auto shipit](pages/auto-shipit.md) - [PR Interaction](pages/pr-interaction.md) - [auto label](pages/auto-label.md) - [auto pr](pages/auto-pr.md) diff --git a/docs/pages/auto-shipit.md b/docs/pages/auto-shipit.md new file mode 100644 index 000000000..4ae65d514 --- /dev/null +++ b/docs/pages/auto-shipit.md @@ -0,0 +1,7 @@ +# `auto shipit` + +Run the full auto-release project. Will detect if in a lerna project and publish accordingly. + +```sh +auto shipit +``` diff --git a/scripts/release.sh b/scripts/release.sh index 0d39516e7..ab2bbb52f 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -1,22 +1,6 @@ git config --global user.email "lisowski54@gmail.com" git config --global user.name "Andrew Lisowski" -git config --global push.default matching chmod +x ./dist/bin/auto.js -VERSION=`./dist/bin/auto.js version` - -if [ ! -z "$VERSION" ]; then - echo SemVer Bump: $VERSION - - ## Update Changelog - ./dist/bin/auto.js changelog - - ## Publish Package - npm version $VERSION -m "Bump version to: %s [skip ci]" - npm publish - - ## Create Gitub Release - git push --follow-tags --set-upstream origin $branch - ./dist/bin/auto.js release -fi \ No newline at end of file +./dist/bin/auto.js shipit \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index d1d498a30..7c6e69b7f 100644 --- a/src/main.ts +++ b/src/main.ts @@ -12,6 +12,7 @@ import GithubRelease, { IGithubReleaseOptions } from './github-release'; +import execPromise from './utils/exec-promise'; import createLog from './utils/logger'; const readFile = promisify(fs.readFile); @@ -26,6 +27,10 @@ const calcGreaterVersion = ( return localVersion > latestVersion ? localVersion : latestVersion; }; +function isMonorepo() { + return fs.existsSync('lerna.json'); +} + async function getCurrentVersion( prefixRelease: (release: string) => string, lastRelease: string, @@ -35,7 +40,7 @@ async function getCurrentVersion( let packageVersion = ''; let monorepoVersion = ''; - if (fs.existsSync('lerna.json')) { + if (isMonorepo()) { monorepoVersion = prefixRelease( JSON.parse(await readFile('lerna.json', 'utf-8')).version ); @@ -72,6 +77,97 @@ async function getCurrentVersion( return lastVersion; } +async function getVersion(githubRelease: GithubRelease, args: ArgsType) { + const lastRelease = await githubRelease.getLatestRelease(); + + return githubRelease.getSemverBump( + lastRelease, + undefined, + args.onlyPublishWithReleaseLabel + ); +} + +async function makeChangelog( + args: ArgsType, + githubRelease: GithubRelease, + log: signale.Signale, + prefixRelease: (release: string) => string, + veryVerbose: signale.Signale, + verbose: signale.Signale +) { + const lastRelease = args.from || (await githubRelease.getLatestRelease()); + const releaseNotes = await githubRelease.generateReleaseNotes( + lastRelease, + args.to || undefined + ); + + log.info('New Release Notes\n', releaseNotes); + + if (!args.dry_run) { + const currentVersion = await getCurrentVersion( + prefixRelease, + lastRelease, + veryVerbose + ); + + await githubRelease.addToChangelog( + releaseNotes, + currentVersion, + args.no_version_prefix, + args.message || undefined + ); + } else { + verbose.info('`changelog` dry run complete.'); + } +} + +async function makeRelease( + args: ArgsType, + githubRelease: GithubRelease, + log: signale.Signale, + prefixRelease: (release: string) => string, + veryVerbose: signale.Signale, + verbose: signale.Signale +) { + let lastRelease = await githubRelease.getLatestRelease(); + + // Find base commit or latest release to generate the changelog to HEAD (new tag) + veryVerbose.info(`Using ${lastRelease} as previous release.`); + + if (lastRelease.match(/\d+\.\d+\.\d+/)) { + lastRelease = prefixRelease(lastRelease); + } + + log.info('Last used release:', lastRelease); + + const releaseNotes = await githubRelease.generateReleaseNotes(lastRelease); + + log.info(`Using release notes:\n${releaseNotes}`); + + const version = + args.use_version || + (await getCurrentVersion(prefixRelease, lastRelease, veryVerbose)); + + if (!version) { + log.error('Could not calculate next version from last tag.'); + return; + } + + const prefixed = prefixRelease(version); + log.info(`Publishing ${prefixed} to Github.`); + + if (!args.dry_run) { + await githubRelease.publish(releaseNotes, prefixed); + + if (args.slack) { + log.info('Posting release to slack'); + await githubRelease.postToSlack(releaseNotes, prefixed); + } + } else { + verbose.info('Release dry run complete.'); + } +} + export async function run(args: ArgsType) { const logger = createLog( args.very_verbose ? 'veryVerbose' : args.verbose ? 'verbose' : undefined @@ -124,6 +220,48 @@ export async function run(args: ArgsType) { ); switch (args.command) { + case 'shipit': { + const version = await getVersion(githubRelease, args); + + if (version === '') { + return; + } + + await makeChangelog( + args, + githubRelease, + log, + prefixRelease, + veryVerbose, + verbose + ); + + if (isMonorepo) { + await execPromise( + `lerna publish --yes --force-publish=* ${version} -m '%v [skip ci]'` + ); + } else { + await execPromise( + `npm version ${version} -m "Bump version to: %s [skip ci]"` + ); + await execPromise('npm publish'); + await execPromise( + 'git push --follow-tags --set-upstream origin $branch' + ); + } + + await makeRelease( + args, + githubRelease, + log, + prefixRelease, + veryVerbose, + verbose + ); + + break; + } + // PR Interaction case 'label': { verbose.info("Using command: 'label'"); const labels = await githubRelease.getLabels(args.pr!); @@ -221,106 +359,57 @@ export async function run(args: ArgsType) { break; } - case 'release': { - verbose.info("Using command: 'release'"); - - let lastRelease = await githubRelease.getLatestRelease(); - - // Find base commit or latest release to generate the changelog to HEAD (new tag) - veryVerbose.info(`Using ${lastRelease} as previous release.`); - - if (lastRelease.match(/\d+\.\d+\.\d+/)) { - lastRelease = prefixRelease(lastRelease); - } - - log.info('Last used release:', lastRelease); + case 'comment': { + verbose.info("Using command: 'comment'"); - const releaseNotes = await githubRelease.generateReleaseNotes( - lastRelease + await githubRelease.createComment( + args.message!, + args.pr!, + args.context || undefined ); - log.info(`Using release notes:\n${releaseNotes}`); - - const version = - args.use_version || - (await getCurrentVersion(prefixRelease, lastRelease, veryVerbose)); - - if (!version) { - log.error('Could not calculate next version from last tag.'); - return; - } - - const prefixed = prefixRelease(version); - log.info(`Publishing ${prefixed} to Github.`); + log.success(`Commented on PR #${args.pr}`); + break; + } + // Release + case 'version': { + verbose.info("Using command: 'version'"); - if (!args.dry_run) { - await githubRelease.publish(releaseNotes, prefixed); + const bump = await getVersion(githubRelease, args); - if (args.slack) { - log.info('Posting release to slack'); - await githubRelease.postToSlack(releaseNotes, prefixed); - } - } else { - verbose.info('Release dry run complete.'); - } + console.log(bump); break; } case 'changelog': { verbose.info("Using command: 'changelog'"); - const lastRelease = args.from || (await githubRelease.getLatestRelease()); - const releaseNotes = await githubRelease.generateReleaseNotes( - lastRelease, - args.to || undefined + await makeChangelog( + args, + githubRelease, + log, + prefixRelease, + veryVerbose, + verbose ); - log.info('New Release Notes\n', releaseNotes); - - if (!args.dry_run) { - const currentVersion = await getCurrentVersion( - prefixRelease, - lastRelease, - veryVerbose - ); - await githubRelease.addToChangelog( - releaseNotes, - currentVersion, - args.no_version_prefix, - args.message || undefined - ); - } else { - verbose.info('`changelog` dry run complete.'); - } - break; } - case 'version': { - verbose.info("Using command: 'version'"); + case 'release': { + verbose.info("Using command: 'release'"); - const lastRelease = await githubRelease.getLatestRelease(); - const bump = await githubRelease.getSemverBump( - lastRelease, - undefined, - args.onlyPublishWithReleaseLabel + await makeRelease( + args, + githubRelease, + log, + prefixRelease, + veryVerbose, + verbose ); - console.log(bump); - break; } - case 'comment': { - verbose.info("Using command: 'comment'"); - await githubRelease.createComment( - args.message!, - args.pr!, - args.context || undefined - ); - - log.success(`Commented on PR #${args.pr}`); - break; - } default: throw new Error(`idk what i'm doing.`); }