-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Release Process
- The release cadence is optimized for consistency – new releases happen weekly, on the same day of the week (Wednesday)
- Out-of-band releases can & do happen to address critical security bugs or patch a broken release & we sometimes elect to skip weeks where there is competing priorities or vacation/OOO
- There is only one officially supported release branch:
npm@latest
) (ie. the latest/stable version of npm)- Our team does not support any LTS releases - you can read more about the versions of
npm
we support here.
- Our team does not support any LTS releases - you can read more about the versions of
Note: We're currently shipping weekly releases of
npm@latest
every Wednesday (& occasionally even more than once a week).
Each release has a release manager, who is responsible for landing that release's pull requests and dependency upgrades, ensuring that the tests pass for the release branch, writing the release notes, and running through the actual release process (see below). The current release managers are the npm CLI team:
- Darcy Clarke / @darcyclarke
- "nlf" / @nlf
- "gar" / @wraithgar
- Luke Karrys / @lukekarrys
- Nathan Fritz / @fritzy
If you're a new release manager, you need a GPG key to sign releases with. We've been using https://keybase.io/ to store/verify our public keys.
In order to sign the release tags, you will need to set this also: npm config set sign-git-tag true
Much of the release process is automated using a customized release-please
script in @npmcli/template-oss
.
The configuration for release-please
is located in a root repo config file release-please-config.json
.
When creating a new major release, first set the prerelease: true
flag in the release-please
config, and then continue to use conventional commits to indicate changes and cut a branch for the latest version of the previous major.
-
Cut a
release/v<CURRENT_MAJOR>
branchgit checkout latest git checkout -b release/v<CURRENT_MAJOR> git push -u origin release/v<CURRENT_MAJOR> git checkout latest
-
Update
releases.json
innpm/documentation
with the new branches -
Set
prerelease: true
for all packages inrelease-please-config.json
// ./release-please-config.json { ... "packages": { ".": { ... "prerelease": true } } ... }
-
Commit
prerelease: true
asfeat:
git checkout -b prerelease git commit -am "feat: set prerelease flag" gh pr create -f
-
Continue to use conventional commits and feature PRs
Everything is now identical to normal release development. The only difference is that
release-please
will version and tag all releases with a-pre.<PRE_ID>
suffix.The usual release process should be followed, except for the sections marked
NOT FOR PRERELEASE
.git checkout latest git checkout -b me/my-breaking-feature git commit -m 'feat: break stuff BREAKING CHANGE: this message gets added to the changelog' gh pr create -f
-
One month later…, remove
prerelease
flag and commitWarning: All breaking changes must be merged AND released before this step
git checkout latest # Remove `prerelease` flags from manifest git commit -am "feat: remove prerelease flags" # `release-please` uses the convention of an empty commit # to force all packages to be released git commit -m "feat: trigger release process" --allow-empty # this cannot be made into a PR because rebasing on GitHub # will remove the empty commit git push origin latest
This will trigger a new release without a
-pre.<PRE_ID>
suffix that can be merged and published normally. -
Combine all prerelease changelogs into the final GitHub Release notes
release-please
only generates changelogs based on the diff from the previous prerelease. So when coming out of prerelease mode, we combine all the prerelease changelogs and manually update the notes of the GitHub Release after it has been created.The GitHub Release notes are the source of truth for the Node.js pull request as well.
The following steps need to be followed when a new major version is tagged latest
for the first time. This will not always occur at the same time as a major version coming out of prerelease mode.
-
Update
releases.json
innpm/documentation
so thebranch
andspec
of the new and previous major releases point to the correct place. -
Set the
dist-tag
of both the new and previous major versionsnode . dist-tag add npm@<CURRENT-MAJOR.Y.Z> latest-<CURRENT-MAJOR> node . dist-tag add npm@<NEW-MAJOR.Y.Z> latest
-
TODO: There may be more of these?
Warning: There are probably more steps here!
-
Search for PRs to merge
Some helpful
gh
searches:gh pr list --draft=false --search "status:pending" gh pr list --draft=false --search "status:success" gh pr list --draft=false --search "review:required" gh pr list --draft=false --search "review:approved"
-
Make sure the PR is targeting
latest
and not something elsegh pr view --json baseRefName -q '.baseRefName'
-
Merge the pull request using squash or rebase
Note: Prefer using rebase if the PR has multiple conventional commits.
Squash
gh pr merge -s <pr-num>
Rebase
gh pr merge -r <pr-num>
Note: Workspace do not need to be updated, since the automated release process will sync all workspace versions as part of the release pull request.
Dependency updates should all go through pull requests using the deps:
conventional commit prefix. This section shows how to check for any outdated deps and make pull requests for them.
-
Check all top level deps
node . outdated
-
Check all levels of production deps
node . outdated -a --omit=dev
-
Install and commit each dep to a PR
git checkout -b deps/updates node . install <pkg>@<version> node . run dependencies # Use prefix `chore:` for dev deps git commit -am 'deps: <pkg>@<version>' git push origin deps/updates gh pr create -f
-
Merge the PR if things look ok
Note:
@npmcli/template-oss
is a dependency of all workspaces and must be installed with--save-exact
-
Update
@npmcli/template-oss
in all workspaces and rootnode . i @npmcli/template-oss@latest -ws -iwr --save-exact
-
Commit and open PR
git checkout -b deps/template-oss git commit -am 'chore(deps): @npmcli/template-oss@<version>' git push origin deps/template-oss gh pr create -f
See Updating Dependencies
for the process.
Note: A single release pull request is created for the CLI and all dependent workspaces by
release-please
.
The release pull request is created automatically by release-please
whenever a commit is pushed to the default branch. This PR should be left open until Release Day, when it should be checked to make sure all workflows are passing. You should checkout the branch locally and publish from there. Once everything is published the PR can be merged into latest
.
-
Checkout the release branch
Ensure git status is not dirty on this branch after resetting deps. If it is, then something is probably wrong with the automated release process.
gh pr checkout <PR-NUMBER> --force node . run resetdeps node scripts/git-dirty.js
-
Check CI status
gh pr checks --watch
-
Publish the CLI
Warning: This will publish all updated workspaces, and will publish the CLI with the dist-tag set to
next-<MAJOR>
.Note: The
--test
argument can optionally be omitted to run the publish process without running any tests locally.node scripts/publish.js --test
-
Optionally install and test
npm@<X.Y.Z>
locallynpm i -g npm@<X.Y.Z> npm --version npm whoami npm help install # etc
-
Set
latest
dist-tag
to newly published versionWarning: NOT FOR PRERELEASE: Do not run this step for prereleases or if
<MAJOR>
is not being set tolatest
.node . dist-tag add npm@<X.Y.Z> latest
-
Merge release PR
gh pr merge --rebase git checkout <BASE-BRANCH> git fetch git reset --hard origin/<BASE-BRANCH> node . run resetdeps
-
Check For Release Tags
Release Please will run on the just pushed release commit and create GitHub releases and tags for each package.
gh run watch `gh run list -w release -L 1 --json databaseId -q ".[0].databaseId"`
-
New @npmjs release: <X.Y.Z>! <GITHUB-RELEASE-LINK> Release details...
-
Trigger
docs.npmjs.com
updategh workflow run update-cli.yml --repo npm/documentation
-
Open
nodejs/node
PR to updatenpm
to latestWarning: NOT FOR PRERELEASE: Do not run this step for prereleases or if
<MAJOR>
is not being set tolatest
.Trigger the Create Node PR action:
gh workflow run create-node-pr.yml