Skip to content

Release Process (v6)

Darcy Clarke edited this page Apr 28, 2022 · 2 revisions

v6 Release Process

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)

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. Pull in PRs
    1. Install the pull cli: npm i -g @npmcli/pull
    2. Run: pull <pull # OR url>
  • 2. Update Deps
    1. Check outdated: npm outdated -l
    2. Run: ./scripts/dep-update <pkg> <version>
  • 3. Make sure tests pass
  • 4. Generate Changelog
    • Run: ./scripts/gen-changelog
  • 5. Update Version
    • Run: npm version
  • 6. Publish Package
    • Run: make publish
  • 7. Update Dist Tags
    • Run: ./scripts/update-dist-tags --otp=<otp>
  • 8. Add release notes - ref: release x.x.x
  • 9. Merge the release branch into release-next & latest
  • 10. Write a blog post - ref: new post
  • 11. Post on Twitter - ref: new post
  • 12. 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. Post a link on the npmjs tumblog.
  10. 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

Then:

  1. From the npm repo, git checkout <tag> the tag for whichever release is next, i.e. '6.6.0-next.1'.

  2. Run make release.

  3. Where x.y.z is the version to which npm is being upgraded:

    cd /path/to/node
    git fetch --all && git checkout -b npm-x.y.z downstream/master
    rm -rf deps/npm
    cd deps
    tar xfz /path/to/npm/release/npm-x.y.z.tgz
    cd ..
    git add -A deps/npm && git commit -m "deps: upgrade npm to x.y.z"
    mv .gitignore gitignore
    git status # make sure nothing from npm shows up
    mv gitignore .gitignore
    # build a new copy of node, the `icu` bits are needed by the license builder
    # the path bits make sure you're using stock system components
    PATH=/sbin:/usr/sbin:/bin:/usr/bin ./configure --with-intl=small-icu --download=icu
    PATH=/sbin:/usr/sbin:/bin:/usr/bin make
    tools/license-builder.sh && git add LICENSE && git commit -m "doc: update npm LICENSE using license-builder.sh"
    # Remote trailing whitespace and rebase
    git fetch --all && git rebase --whitespace=fix downstream/master
    # Push new commit to npm fork
    git push npm HEAD
  4. Run the tests with this new version of node with:

    PATH=/sbin:/usr/sbin:/bin:/usr/bin make test-npm
    

    The path bit is especially important here as it ensures that there's no way for you to accidentally use the wrong version of node or npm to test with.

  5. Go to the npm fork of node and create a pull request, ensuring that the base of the PR is node/master.

  6. In the body of the PR, link to the release notes for that version.


Merge the release

Merge release-x.y.z into release-next

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

Merge release-next into latest

git checkout latest
git fetch && git pull
git merge --ff-only release-next
git push origin latest --follow-tags