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 releaseshipit
will 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
latest
release - 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
major
happens - 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 thecanary
release 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.
data
newVersion
- 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