Release Lifecycle Hooks
The following hooks are all called during various release commands (ex: latest, next, canary, shipit).
These hooks is where the publishing of your package actually happens.
prCheck
Called before auto pr-check is ran/
Context Object:
pr- All github information related to the PR
auto.hooks.prCheck.tapPromise("NPM", async ({ pr }) => { // Do stuff });auto.hooks.prCheck.tapPromise("NPM", async ({ pr }) => { // Do stuff });
beforeShipIt
Happens before shipit is run.
This is a great way to throw an error if a token or key is not present.
Context Object:
releaseType(latest|old|next|canary) - The type of releaseshipitwill attempt to make.dryRun- Whether the run is a dry run
auto.hooks.beforeShipIt.tapPromise("NPM", async (context) => { if (!process.env.NPM_TOKEN) { throw new Error("NPM Token is needed for the NPM plugin!"); } });auto.hooks.beforeShipIt.tapPromise("NPM", async (context) => { if (!process.env.NPM_TOKEN) { throw new Error("NPM Token is needed for the NPM plugin!"); } });
Other examples:
- all-contributors - Manage manual contribution additions in PRs
- gh-pages - Publishes your docs to GitHub pages on a
latestrelease - npm - Exits early when lerna won't need to make a release
beforeCommitChangelog
Ran before the changelog command commits the new release notes to CHANGELOG.md.
Useful for modifying the changelog as a whole or creating extra changelog files.
These files can be apart of the commit that updates the changelog.
bump- the semver bumpcommits- the commits in the changelogcurrentVersion- version that was just releasedlastRelease- the version before the current versionreleaseNotes- generated release notes for the release
auto.hooks.beforeCommitChangelog.tap( "MyPlugin", async ({ currentVersion, commits, releaseNotes, lastRelease }) => { // do something } );auto.hooks.beforeCommitChangelog.tap( "MyPlugin", async ({ currentVersion, commits, releaseNotes, lastRelease }) => { // do something } );
Other examples:
- In Core: Create major version branches when
majorhappens - npm - Create sub-package changelogs
afterChangelog
Ran after the changelog command adds the new release notes to CHANGELOG.md.
Useful for getting extra commits into a release before publishing.
bump- the semver bumpcommits- the commits in the changelogcurrentVersion- version that was just releasedlastRelease- the version before the current versionreleaseNotes- generated release notes for the release
auto.hooks.afterChangelog.tap( "MyPlugin", async ({ currentVersion, commits, releaseNotes, lastRelease }) => { // do something } );auto.hooks.afterChangelog.tap( "MyPlugin", async ({ currentVersion, commits, releaseNotes, lastRelease }) => { // do something } );
Other examples:
- all-contributors - Make a commit for new contributions
version
Increment the version the package.
This is a good opportunity to git tag the release also.
This hooks is required for plugin that facilitate publishing.
Here npm does it for us.
auto.hooks.version.tapPromise("NPM", async ({ bump, dryRun, quiet }) => { if (dryRun) { const { version } = await loadPackageJson(); console.log(inc(version, bump)); return; } await execPromise("npm", [ "version", bump, "-m", "Bump version to: %s [skip ci]", ]); });auto.hooks.version.tapPromise("NPM", async ({ bump, dryRun, quiet }) => { if (dryRun) { const { version } = await loadPackageJson(); console.log(inc(version, bump)); return; } await execPromise("npm", [ "version", bump, "-m", "Bump version to: %s [skip ci]", ]); });
If you're implementing this hook for a publishing plugin you must commit (with
[skip ci]in the message) and tag the version.
afterVersion
Ran after the package has been versioned.
Examples:
- In Core: Used to exit early is new commits are detected on the remote
- brew - Create a new brew formula once the package a=has been versioned
auto.hooks.afterVersion.tapPromise("NPM", async ({ dryRun }) => {});auto.hooks.afterVersion.tapPromise("NPM", async ({ dryRun }) => {});
publish
Publish the package to some package distributor. You must push the tags to github! This hooks is required for plugin that facilitate publishing.
auto.hooks.publish.tapPromise("NPM", async ({ bump }) => { await execPromise("npm", [ "version", bump, "-m", "Bump version to: %s [skip ci]", ]); await execPromise("npm", ["publish"]); await execPromise("git", [ "push", "--follow-tags", "--set-upstream", auto.remote, "$branch", ]); });auto.hooks.publish.tapPromise("NPM", async ({ bump }) => { await execPromise("npm", [ "version", bump, "-m", "Bump version to: %s [skip ci]", ]); await execPromise("npm", ["publish"]); await execPromise("git", [ "push", "--follow-tags", "--set-upstream", auto.remote, "$branch", ]); });
afterPublish
Ran after the package has been published.
canary
Used to publish a canary release.
In this hook you get the semver bump and the unique canary postfix ID.
You can either return a string value of just the version or an object containing the following which will be rendered within and HTML details element.
newVersion- The version published in thecanaryrelease or a header for the details element.details- The body of the details element
auto.hooks.canary.tapPromise( this.name, async ({ bump, canaryIdentifier, dryRun, quiet }) => { const lastRelease = await auto.git!.getLatestRelease(); const current = await auto.getCurrentVersion(lastRelease); const nextVersion = inc(current, bump as ReleaseType); const isScopedPackage = name.match(/@\S+\/\S+/); const canaryVersion = `${nextVersion}-canary${canaryIdentifier}`; await execPromise("npm", [ "version", canaryVersion, "--no-git-tag-version", ]); await execPromise("npm", ["publish", "--tag", "canary"]); auto.logger.verbose.info("Successfully published canary version"); return canaryVersion; } );auto.hooks.canary.tapPromise( this.name, async ({ bump, canaryIdentifier, dryRun, quiet }) => { const lastRelease = await auto.git!.getLatestRelease(); const current = await auto.getCurrentVersion(lastRelease); const nextVersion = inc(current, bump as ReleaseType); const isScopedPackage = name.match(/@\S+\/\S+/); const canaryVersion = `${nextVersion}-canary${canaryIdentifier}`; await execPromise("npm", [ "version", canaryVersion, "--no-git-tag-version", ]); await execPromise("npm", ["publish", "--tag", "canary"]); auto.logger.verbose.info("Successfully published canary version"); return canaryVersion; } );
canary version should not produce any of the following:
- a new tag
- any commits
- a new release
- any changes to changelogs
It is "test" release and has no impact on any of your real releases.
next
Used to publish a next release.
In this hook you get the semver bump and a list of all pre-releases made.
This hook must add the version it published to preReleaseVersions and return it.
preReleaseVersions- A list of prerelease version publish during the current runbump- The version bump to apply
import { determineNextVersion, execPromise, getCurrentBranch, } from "@auto-it/core"; auto.hooks.next.tapPromise( this.name, async (preReleaseVersions, { bump, dryRun }) => { const branch = getCurrentBranch() || ""; const lastRelease = await auto.git.getLatestRelease(); const current = (await auto.git.getLastTagNotInBaseBranch(branch)) || (await auto.getCurrentVersion(lastRelease)); // Use this helper function to determine the next prerelease version const prerelease = determineNextVersion(lastRelease, current, bump, "next"); // Make sure to add the version to the list preReleaseVersions.push(prerelease); if (dryRun) { return preReleaseVersions; } // Create a new tag for it await execPromise("git", [ "tag", prerelease, "-m", `"Tag pre-release: ${prerelease}"`, ]); // Push the tag await execPromise("git", ["push", auto.remote, "--tags"]); return preReleaseVersions; } );import { determineNextVersion, execPromise, getCurrentBranch, } from "@auto-it/core"; auto.hooks.next.tapPromise( this.name, async (preReleaseVersions, { bump, dryRun }) => { const branch = getCurrentBranch() || ""; const lastRelease = await auto.git.getLatestRelease(); const current = (await auto.git.getLastTagNotInBaseBranch(branch)) || (await auto.getCurrentVersion(lastRelease)); // Use this helper function to determine the next prerelease version const prerelease = determineNextVersion(lastRelease, current, bump, "next"); // Make sure to add the version to the list preReleaseVersions.push(prerelease); if (dryRun) { return preReleaseVersions; } // Create a new tag for it await execPromise("git", [ "tag", prerelease, "-m", `"Tag pre-release: ${prerelease}"`, ]); // Push the tag await execPromise("git", ["push", auto.remote, "--tags"]); return preReleaseVersions; } );
next version should not produce any of the following:
- any commits
- any changes to changelogs
makeRelease
Ran when trying to make a release during the release command has run.
This async hook gets the following arguments:
dryRun- Whether this is a dry runfrom- Commit to start calculating the version fromnewVersion- The version being releasedisPrerelease- Whether the release being made is a prereleasefullReleaseNotes- The generated release notes for all of the commitscommits- The commits included in the release
auto.hooks.makeRelease.tapPromise("MyPlugin", async (options) => { if (!options.dryRun) { this.logger.log.info(`Releasing ${options.newVersion} to GitHub.`); return this.git!.publish( options.fullReleaseNotes, options.newVersion, options.isPrerelease ); } });auto.hooks.makeRelease.tapPromise("MyPlugin", async (options) => { if (!options.dryRun) { this.logger.log.info(`Releasing ${options.newVersion} to GitHub.`); return this.git!.publish( options.fullReleaseNotes, options.newVersion, options.isPrerelease ); } });
Other examples:
- npm - Create GitHub releases for sub-packages
afterRelease
Ran after the release command has run, creating a new release on GitHub.
This async hook gets the following arguments:
lastRelease- the version that existed prior to the current releasenewVersion- version that was just releasedcommits- the commits in the releasereleaseNotes- generated release notes for the releaseresponse- the response returned from making the release
auto.hooks.afterRelease.tapPromise( "MyPlugin", async ({ lastRelease, newVersion, commits, releaseNotes, response }) => { // do something } );auto.hooks.afterRelease.tapPromise( "MyPlugin", async ({ lastRelease, newVersion, commits, releaseNotes, response }) => { // do something } );
Other examples:
- release - Post comment on issues and PRs about release version
- s3 - Upload release assets to s3
- slack - Post the release notes to slack
- twitter - Create a tweet about the new release
- upload-assets - Uses hook to upload files to newly created release
afterShipIt
Ran after the shipit command has run.
datanewVersion- The new version that was releasecommits- the commits in the releasecontext- The type of release that was created (latest,next,canary, orold)dryRun- Whether the run is a dry run
auto.hooks.afterShipIt.tap("MyPlugin", async ({ context }) => { // do something });auto.hooks.afterShipIt.tap("MyPlugin", async ({ context }) => { // do something });
Other examples:
- gradle - Uses hook to setup next snapshot version