Skip to content

Release Process

nlf edited this page Feb 18, 2021 · 93 revisions

Overview

  • When possible, it is optimal to have both a latest (stable) version of npm alongside the next version under the dist-tag of x.y-next, where x and y are the semver-major and -minor components of that release's version
  • When issues are found in a next-x release, a new patch release will may be published and retagged as next-x, to eventually be promoted to latest on the following release date
  • The release cadence is optimized for consistency – new releases happen every two-to-four weeks, on the same day of the week (Tuesday)
  • Out-of-band releases can & do happen to address critical security bugs or patch a broken release
  • There is only one officially supported release branch: npm@6 (latest) (ie. the latest/stable version of npm)

Note: we're currently shipping weekly releases of npm@7 every Tuesday (& sometimes even more than once a week).


Roles

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:

If you're a new release manager, start by looking at the release setup notes.


Quick Checklist

  • 1. Start a new release branch.
    1. Run: git checkout latest && git pull
    2. Run: npm run resetdeps
    3. Run: git checkout -b release/v<MAJOR>.<MINOR>.<PATCH>
    4. Run: git push origin release/v<MAJOR>.<MINOR>.<PATCH> in order to create the remote branch as we'll need it later
  • 2. Pull in PRs
    1. Install the pull cli: npm i -g @npmcli/pull
    2. Run: pull <pull # OR url>
    3. Fixes any inconsistencies (such as changing reviewer attribution) then git commit --amend (if needed)
    4. Run: pull update in order to push the release branch and update the target PR with the ammended commit
  • 3. Update Deps
    1. Check outdated: npm outdated & npm outdated -a --prod
    2. Run: node . install <pkg>@<version>
    3. Run: node ./scripts/bundle-and-gitignore-deps.js
    4. Run: git add -A && git commit -m '<pkg>@<version>'
  • 4. Make sure tests pass
  • 5. Generate Changelog
    • Run: node ./scripts/changelog.js <commitish> (ex. <commitish> should be a tag or SHA reference to the previous release)
      • Copy output into CHANGELOG.md
      • Manually reformat & match style of historical updates
      • Run: git add CHANGELOG.md && git commit -m 'docs: changelog for v<MAJOR>.<MINOR>.<PATCH>'
  • 6. Update Version
    • Run: npm version <exact version number>|major|minor|patch
  • 7. Push to GitHub
    • Run: git push origin release/v<MAJOR>.<MINOR>.<PATCH>
  • 8. Publish Package
    • Run: make publish
  • 9. Update Dist Tags
    1. Run: npm dist-tag add npm@<version> latest
    2. Run: npm dist-tag add npm@<version> lts
    3. Run: npm dist-tag add npm@<version> next
  • 10. Add release notes - ref: release x.x.x
  • 11. Merge the release branch into release-next & latest
  • 12. Post on Twitter w/ ref to GitHub tag/changleog- ref: new post
  • 13. Update Node.js

Planning

The team meets weekly to determine what to include in that week's release, and typically covers the following outline:

  1. How many of the CLI team's in-progress pull requests will be ready to ship this week?
  2. Are there too many GitHub issues or pull requests assigned to team members?
  3. Review available dependency upgrades (npm outdated -l against each supported release series.
  4. Review outstanding community pull requests against npm/cli & label accordingly.
    1. ex. GitHub PR search filter: is:pr is:open sort:updated-desc -label:"semver:major" -label:Backlog -label:"Needs Tests" -label:"Needs Discussion"
  5. Review outstanding pull requests against npm dependencies managed by the CLI team & label accordingly.
  6. Does the team need to release a new npm@6 (LTS) this week?
  7. What's going into this week's release?
  8. What does the team want to land in next week's release?
  9. Is there anything marketable in upcoming releases?
  10. Update release milestones & the road map weekly focus.

Preparing

Create a release/x.y.z branch on which to land all changes before finally releasing it to the respective target branch, so you can rebase / rewrite the branch's commits freely. Be aware that rebasing after you've started work on the release notes will mean you'll have to fix up and check all the commitishes that are on the rebased branch.

All pull requests must be reviewed by a member of the CLI team before being merged into the release branch. The review process is pretty flexible and straightforward, but it must be followed, and if the team decides that a change isn't ready to ship, it'll be punted to the next release. A week isn't too much longer to wait (although in some rare cases, tricky patches have taken up to a few months to be included).

  • Dependency upgrades should be landed as commits on the release branch release-next
  • Look for outdated dependencies with npm outdated -l
  • Each module updated should be done as a single commit with a commit subject of package@version (run scripts/dep-update <package> <version> to handle this for you)

Cutting the release

Each branch's release manager follows this procedure:

  1. The release manager ensures that all tests are passing for the release branch (usually release-next or release-next-<n>).
  2. The release manager updates the changelog with salient changes for that release, calling out any breaking changes. You can get a head start on the changelog by running scripts/gen-changelog, which will do its machine best to generate a changelog for you and stick it at the top of CHANGELOG.md. It's not a very smart script though, so you'll still need to edit the result.
  3. The release manager gets a CLI team member to review the release notes for content and style.
  4. The release manager runs npm version <version> on the branch. If it's a new patch or minor version, it should be X.Y.Z-next.0. If it's a patch to an existing prerelease, increment the number. The git release tags are always signed with GnuPG by a npm core team member. (More on setting up GPG with Git.)
  5. The release manager runs make publish on the branch. This:
    1. Ensures that the docs have been built correctly.
    2. Ensures that all changes and tags have been pushed to the appropriate branch on GitHub.
    3. Publishes npm to the registry, setting the release tag to vX.Y-next (not latest, for reasons described above).
    4. NOTE: make sure you have github and npm write permissions!
  6. The release manager runs npm dist-tag set npm@<new-version> next in order to update the next tag and repeat the command in order to update the other appropriate tags (or, next-<n> if doing a prerelease for a different major version line)
  7. The release manager cleans up the vX.Y-next that was generated as part of the publish process, using npm dist-tag rm npm vX.Y-next.
  8. Post the release notes to Github Releases. Make sure to remove extra newlines from the original, to preserve text flow in browsers.
  9. The release manager tweets about the new release!

Twitter template

New @npmjs release! DETAILS_ABOUT_THE_RELEASE

latest: X.X.X
next: X.X.X

Submitting to Node.js

Before starting, make sure that you're working from a clone of Node.js where:

  • a remote named downstream points at https://github.com/nodejs/node.git
  • a remote named npm points at git@github.com:npm/node.git
  1. Checkout a new branch for the release: git checkout -b npm-x.y.z
  2. Run through the steps in the Maintaining npm in Node.js doc.
  3. Once complete, go to the npm fork of node & create a pull request, ensuring that the base of the PR is node/master.
  4. In the body of the PR, link to the release notes for that version.

Merge the release

Merge release/x.y.z into latest

git checkout latest
git fetch && git pull
git merge --ff-only release/x.y.z
git push origin latest --follow-tags