1# Node.js release process 2 3This document describes the technical aspects of the Node.js release process. 4The intended audience is those who have been authorized by the Node.js 5Technical Steering Committee (TSC) to create, promote, and sign 6official release builds for Node.js, hosted on <https://nodejs.org/>. 7 8## Table of contents 9 10* [Who can make a release?](#who-can-make-a-release) 11 * [1. Jenkins release access](#1-jenkins-release-access) 12 * [2. \<nodejs.org> access](#2-nodejsorg-access) 13 * [3. A publicly listed GPG key](#3-a-publicly-listed-gpg-key) 14* [How to create a release](#how-to-create-a-release) 15 * [0. Pre-release steps](#0-pre-release-steps) 16 * [1. Update the staging branch](#1-update-the-staging-branch) 17 * [2. Create a new branch for the release](#2-create-a-new-branch-for-the-release) 18 * [3. Update `src/node_version.h`](#3-update-srcnode_versionh) 19 * [4. Update the changelog](#4-update-the-changelog) 20 * [5. Create release commit](#5-create-release-commit) 21 * [6. Propose release on GitHub](#6-propose-release-on-github) 22 * [7. Ensure that the release branch is stable](#7-ensure-that-the-release-branch-is-stable) 23 * [7.1 Updating the release _(optional)_](#7-1-updating-the-release-optional) 24 * [8. Produce a nightly build _(optional)_](#8-produce-a-nightly-build-optional) 25 * [9. Produce release builds](#9-produce-release-builds) 26 * [10. Test the build](#10-test-the-build) 27 * [11. Tag and sign the release commit](#11-tag-and-sign-the-release-commit) 28 * [12. Set up for the next release](#12-set-up-for-the-next-release) 29 * [13. Cherry-pick the release commit to `main`](#13-cherry-pick-the-release-commit-to-main) 30 * [14. Push the release tag](#14-push-the-release-tag) 31 * [15. Promote and sign the release builds](#15-promote-and-sign-the-release-builds) 32 * [16. Check the release](#16-check-the-release) 33 * [17. Create a blog post](#17-create-a-blog-post) 34 * [18. Create the release on GitHub](#18-create-the-release-on-github) 35 * [19. Cleanup](#19-cleanup) 36 * [20. Announce](#20-announce) 37 * [21. Celebrate](#21-celebrate) 38* [LTS releases](#lts-releases) 39* [Major releases](#major-releases) 40 41## Who can make a release? 42 43Release authorization is given by the Node.js TSC. Once authorized, an 44individual must have the following: 45 46### 1. Jenkins release access 47 48There are three relevant Jenkins jobs that should be used for a release flow: 49 50**a.** **Test runs:** 51**[node-test-pull-request](https://ci.nodejs.org/job/node-test-pull-request/)** 52is used for a final full-test run to ensure that the current _HEAD_ is stable. 53 54**b.** **Nightly builds:** (optional) 55**[iojs+release](https://ci-release.nodejs.org/job/iojs+release/)** can be used 56to create a nightly release for the current _HEAD_ if public test releases are 57required. Builds triggered with this job are published straight to 58<https://nodejs.org/download/nightly/> and are available for public download. 59 60**c.** **Release builds:** 61**[iojs+release](https://ci-release.nodejs.org/job/iojs+release/)** does all of 62the work to build all required release assets. Promotion of the release files is 63a manual step once they are ready (see below). 64 65The [Node.js build team](https://github.com/nodejs/build) is able to provide 66this access to individuals authorized by the TSC. 67 68### 2. \<nodejs.org> access 69 70The _dist_ user on nodejs.org controls the assets available in 71<https://nodejs.org/download/>. <https://nodejs.org/dist/> is an alias for 72<https://nodejs.org/download/release/>. 73 74The Jenkins release build workers upload their artifacts to the web server as 75the _staging_ user. The _dist_ user has access to move these assets to public 76access while, for security, the _staging_ user does not. 77 78Nightly builds are promoted automatically on the server by a cron task for the 79_dist_ user. 80 81Release builds require manual promotion by an individual with SSH access to the 82server as the _dist_ user. The 83[Node.js build team](https://github.com/nodejs/build) is able to provide this 84access to individuals authorized by the TSC. 85 86### 3. A publicly-listed GPG key 87 88A `SHASUMS256.txt` file is produced for every promoted build, nightly, and 89releases. Additionally for releases, this file is signed by the individual 90responsible for that release. In order to be able to verify downloaded binaries, 91the public should be able to check that the `SHASUMS256.txt` file has been 92signed by someone who has been authorized to create a release. 93 94The GPG keys should be fetchable from a known third-party keyserver. The SKS 95Keyservers at <https://sks-keyservers.net> are recommended. Use the 96[submission](https://pgp.mit.edu/) form to submit a new GPG key. You'll need to 97do an ASCII-armored export of your key first: 98 99```console 100$ gpg --armor --export email@server.com > ~/nodekey.asc 101``` 102 103Keys should be fetchable via: 104 105```console 106$ gpg --keyserver pool.sks-keyservers.net --recv-keys <FINGERPRINT> 107``` 108 109The key you use may be a child/subkey of an existing key. 110 111Additionally, full GPG key fingerprints for individuals authorized to release 112should be listed in the Node.js GitHub README.md file. 113 114## How to create a release 115 116Notes: 117 118* Dates listed below as _"YYYY-MM-DD"_ should be the date of the release **as 119 UTC**. Use `date -u +'%Y-%m-%d'` to find out what this is. 120* Version strings are listed below as _"vx.y.z"_ or _"x.y.z"_. Substitute for 121 the release version. 122* Examples will use the fictional release version `1.2.3`. 123* When preparing a security release, follow the security steps in the details 124 sections. 125 126### 0. Pre-release steps 127 128Before preparing a Node.js release, the Build Working Group must be notified at 129least one business day in advance of the expected release. Coordinating with 130Build is essential to make sure that the CI works, release files are published, 131and the release blog post is available on the project website. 132 133Build can be contacted best by opening up an issue on the [Build issue 134tracker][]. 135 136When preparing a security release, contact Build at least two weekdays in 137advance of the expected release. To ensure that the security patch(es) can be 138properly tested, run a `node-test-pull-request` job against the `main` branch 139of the `nodejs-private/node-private` repository a day or so before the 140[CI lockdown procedure][] begins. This is to confirm that Jenkins can properly 141access the private repository. 142 143### 1. Update the staging branch 144 145Checkout the staging branch locally. 146 147```console 148$ git remote update 149$ git checkout v1.x-staging 150$ git reset --hard upstream/v1.x-staging 151``` 152 153If the staging branch is not up to date relative to `main`, bring the 154appropriate PRs and commits into it. 155 156Go through PRs with the label `vN.x`. e.g. [PRs with the `v8.x` label](https://github.com/nodejs/node/pulls?q=is%3Apr+is%3Aopen+sort%3Aupdated-desc+label%3Av8.x). 157 158For each PR: 159 160* Run or check that there is a passing CI. 161* Check approvals (you can approve yourself). 162* Check that the commit metadata was not changed from the `main` commit. 163* If there are merge conflicts, ask the PR author to rebase. 164 Simple conflicts can be resolved when landing. 165 166When landing the PR add the `Backport-PR-URL:` line to each commit. Close the 167backport PR with `Landed in ...`. Update the label on the original PR from 168`backport-requested-vN.x` to `backported-to-vN.x`. 169 170You can add the `Backport-PR-URL` metadata by using `--backport` with 171`git node land` 172 173```console 174$ git node land --backport $PR-NUMBER 175``` 176 177To determine the relevant commits, use 178[`branch-diff`](https://github.com/nodejs/branch-diff). The tool is available on 179npm and should be installed globally or run with `npx`. It depends on our commit 180metadata, as well as the GitHub labels such as `semver-minor` and 181`semver-major`. One drawback is that when the `PR-URL` metadata is accidentally 182omitted from a commit, the commit will show up because it's unsure if it's a 183duplicate or not. 184 185For a list of commits that could be landed in a patch release on v1.x: 186 187```console 188$ branch-diff v1.x-staging main --exclude-label=semver-major,semver-minor,dont-land-on-v1.x,backport-requested-v1.x,backport-blocked-v1.x,backport-open-v1.x,backported-to-v1.x --filter-release --format=simple 189``` 190 191Previously released commits and version bumps do not need to be 192cherry-picked. 193 194Carefully review the list of commits: 195 196* Checking for errors (incorrect `PR-URL`) 197* Checking semver status - Commits labeled as `semver-minor` or `semver-major` 198 should only be cherry-picked when appropriate for the type of release being 199 made. 200* If you think it's risky and the change should wait for a while, add the 201 `baking-for-lts` tag. 202 203When you are ready to cherry-pick commits, you can automate with the following 204command. (For semver-minor releases, make sure to remove the `semver-minor` tag 205from `exclude-label`.) 206 207```console 208$ branch-diff v1.x-staging main --exclude-label=semver-major,semver-minor,dont-land-on-v1.x,backport-requested-v1.x,backport-blocked-v1.x,backport-open-v1.x,backported-to-v1.x --filter-release --format=sha --reverse | xargs git cherry-pick 209``` 210 211When cherry-picking commits, if there are simple conflicts you can resolve 212them. Otherwise, add the `backport-requested-vN.x` label to the original PR 213and post a comment stating that it does not land cleanly and will require a 214backport PR. You can refer the owner of the PR to the "[Backporting to Release 215Lines](https://github.com/nodejs/node/blob/HEAD/doc/contributing/backporting-to-release-lines.md)" guide. 216 217If commits were cherry-picked in this step, check that the test still pass. 218 219```console 220$ make test 221``` 222 223Then, push to the staging branch to keep it up-to-date. 224 225```console 226$ git push upstream v1.x-staging 227``` 228 229<details> 230<summary>Security release</summary> 231 232Security releases with private patches need to be prepared in the `nodejs-private` 233GitHub organization. 234 235Add the `nodejs-private` remote: 236 237```console 238$ git remote add private git@github.com:nodejs-private/node-private.git 239``` 240 241For security releases, we generally try to only include the security patches. 242As there may already be commits on the `vN.x-staging` branch, it is preferable 243to checkout the `vN.x` branch and build up the release directly in a proposal 244branch. 245 246```console 247$ git checkout vN.x 248$ git reset --hard upstream/vN.x 249``` 250 251The list of patches to include should be listed in the "Next Security Release" 252issue in `nodejs-private`. Ask the security release steward if you're unsure. 253 254The `git node land` tool does not work with the `nodejs-private` 255organization. To land a PR in Node.js private, use `git cherry-pick` to apply 256each commit from the PR. You will also need to manually apply the PR 257metadata (`PR-URL`, `Reviewed-by`, etc.) by amending the commit messages. If 258known, additionally include `CVE-ID: CVE-XXXX-XXXXX` in the commit metadata. 259 260**Note**: Do not run CI on the PRs in `nodejs-private` until CI is locked down. 261You can integrate the PRs into the proposal without running full CI. 262 263</details> 264 265### 2. Create a new branch for the release 266 267⚠️ At this point, you can either run `git node release --prepare`: 268 269```console 270$ git node release --prepare x.y.z 271``` 272 273to automate the remaining steps until step 6 or you can perform it manually 274following the below steps. 275 276*** 277 278Create a new branch named `vx.y.z-proposal`, off the corresponding staging 279branch. 280 281```console 282$ git checkout -b v1.2.3-proposal upstream/v1.x-staging 283``` 284 285<details> 286<summary>Security release</summary> 287 288When performing Security Releases, the `vN.x.x-proposal` branch should be 289branched off of `vN.x`. 290 291```console 292$ git checkout -b v1.2.3-proposal upstream/v1.x 293git cherry-pick ... # cherry-pick nodejs-private PR commits directly into the proposal 294``` 295 296</details> 297 298### 3. Update `src/node_version.h` 299 300Set the version for the proposed release using the following macros, which are 301already defined in `src/node_version.h`: 302 303```c 304#define NODE_MAJOR_VERSION x 305#define NODE_MINOR_VERSION y 306#define NODE_PATCH_VERSION z 307``` 308 309Set the `NODE_VERSION_IS_RELEASE` macro value to `1`. This causes the build to 310be produced with a version string that does not have a trailing pre-release tag: 311 312```c 313#define NODE_VERSION_IS_RELEASE 1 314``` 315 316### 4. Update the changelog 317 318#### Step 1: Collect the formatted list of changes 319 320Collect a formatted list of commits since the last release. Use 321[`changelog-maker`](https://github.com/nodejs/changelog-maker) to do this: 322 323```console 324$ changelog-maker --group --markdown 325``` 326 327`changelog-maker` counts commits since the last tag and if the last tag 328in the repository was not on the current branch you may have to supply a 329`--start-ref` argument: 330 331```console 332$ changelog-maker --group --markdown --filter-release --start-ref v1.2.2 333``` 334 335`--filter-release` will remove the release commit from the previous release. 336 337#### Step 2: Update the appropriate doc/changelogs/CHANGELOG\_\*.md file 338 339There is a separate `CHANGELOG_Vx.md` file for each major Node.js release line. 340These are located in the `doc/changelogs/` directory. Once the formatted list of 341changes is collected, it must be added to the top of the relevant changelog file 342in the release branch (e.g. a release for Node.js v4 would be added to the 343`/doc/changelogs/CHANGELOG_V4.md`). 344 345**Please do _not_ add the changelog entries to the root `CHANGELOG.md` file.** 346 347The new entry should take the following form: 348 349```markdown 350<a id="x.y.x"></a> 351## YYYY-MM-DD, Version x.y.z (Release Type), @releaser 352 353### Notable changes 354 355* List notable changes here 356* ... 357 358### Commits 359 360* Include the full list of commits since the last release here. Do not include "Working on X.Y.Z+1" commits. 361``` 362 363The release type should be either Current, LTS, or Maintenance, depending on the 364type of release being produced. 365 366By default, the `### Notable changes` section should be populated with the 367commits in the release that have either the `notable-change` or `semver-minor` 368label. Some `semver-minor` features may be determined by the releaser, or 369indicated by another contributor, to not be appropriate to be listed as a 370notable. The ultimate decision rests with the releaser. 371 372You can use `branch-diff` to get a list of commits with the `notable-change` 373label: 374 375```console 376$ branch-diff upstream/v1.x v1.2.3-proposal --require-label=notable-change --plaintext 377``` 378 379Be sure that the `<a>` tag, as well as the two headings, are not indented at 380all. 381 382<details> 383<summary>Security release</summary> 384 385For security releases, it is necessary to include more detailed information 386including which vulnerabilities have been fixed, and any revert flags or 387workarounds to revert to the old behavior. 388 389You can use the following template as a guide: 390 391```markdown 392<a id="x.y.x"></a> 393## YYYY-MM-DD, Version x.y.z (Release Type), @releaser 394 395This is a security release. 396 397### Notable changes 398 399* <CVE Title> (High|Medium|Low)(CVE-XXXX-XXXXX) 400* ... 401 402### Commits 403 404* Include the full list of commits since the last release here. Do not include "Working on X.Y.Z+1" commits. 405``` 406 407Alternatively, refer to one of the [previous security release changelog entries](https://github.com/nodejs/node/blob/main/doc/changelogs/CHANGELOG_V17.md#2022-01-10-version-1731-current-bethgriggs) 408to get an idea of the structure and level of detail. 409 410For each fix, use your judgement as to whether a subheading is necessary to 411describe the fix in more detail. Much of this information should be able to be 412lifted from the "post-release" announcement (should be available in 413`nodejs-private`). If the CVE is being fixed in multiple release lines, try to 414coordinate the changelog content between the other release so the descriptions 415are consistent. 416 417</details> 418 419At the top of the root `CHANGELOG.md` file, there is a table indexing all 420releases in each major release line. A link to the new release needs to be added 421to it. Follow the existing examples and be sure to add the release to the _top_ 422of the list. The most recent release for each release line is shown in **bold** 423in the index. When updating the index, please make sure to update the display 424accordingly by removing the bold styling from the previous release. 425 426Run `make format-md` to ensure the `CHANGELOG_Vx.md` and `CHANGELOG.md` files 427are formatted correctly. 428 429#### Step 3: Update any REPLACEME and DEP00XX tags in the docs 430 431If this release includes new APIs then it is necessary to document that they 432were first added in this version. The relevant commits should already include 433`REPLACEME` tags as per the example in the 434[docs README](../../tools/doc/README.md). Check for these tags with 435 436```console 437grep REPLACEME doc/api/*.md 438``` 439 440and substitute this node version with 441 442```console 443sed -i "s/REPLACEME/$VERSION/g" doc/api/*.md 444``` 445 446For macOS requires the extension to be specified. 447 448```bash 449sed -i "" "s/REPLACEME/$VERSION/g" doc/api/*.md 450``` 451 452or 453 454```console 455perl -pi -e "s/REPLACEME/$VERSION/g" doc/api/*.md 456``` 457 458`$VERSION` should be prefixed with a `v`. 459 460If this release includes any new deprecations it is necessary to ensure that 461those are assigned a proper static deprecation code. These are listed in the 462docs (see `doc/api/deprecations.md`) and in the source as `DEP00XX`. The code 463must be assigned a number (e.g. `DEP0012`). This assignment should 464occur when the PR is landed, but a check will be made when the release build is 465run. 466 467### 5. Create release commit 468 469The `CHANGELOG.md`, `doc/changelogs/CHANGELOG_Vx.md`, `src/node_version.h`, and 470`REPLACEME` changes should be the final commit that will be tagged for the 471release. When committing these to git, use the following message format: 472 473```text 474YYYY-MM-DD, Version x.y.z (Release Type) 475 476Notable changes: 477 478* Copy the notable changes list here, reformatted for plain-text 479 480PR-URL: TBD 481``` 482 483<details> 484<summary>Security release</summary> 485 486For security releases, begin the commit message with the phrase 487`This is a security release.` to allow the 488[distribution indexer](https://github.com/nodejs/nodejs-dist-indexer) to 489identify it as such: 490 491```text 492YYYY-MM-DD, Version x.y.z (Release Type) 493 494This is a security release. 495 496Notable changes: 497 498* Copy the notable changes list here, reformatted for plain-text 499 500PR-URL: TBD 501``` 502 503**Note**: Ensure to push the proposal branch to the nodejs-private repository. 504Otherwise, you will leak the commits before the security release. 505 506</details> 507 508### 6. Propose release on GitHub 509 510Push the release branch to `nodejs/node`, not to your own fork. This allows 511release branches to more easily be passed between members of the release team if 512necessary. 513 514Create a pull request targeting the correct release line. For example, a 515`v5.3.0-proposal` PR should target `v5.x`, not `main`. Paste the CHANGELOG 516modifications into the body of the PR so that collaborators can see what is 517changing. These PRs should be left open for at least 24 hours, and can be 518updated as new commits land. If the CHANGELOG pasted into the pull request 519is long enough that it slows down the GitHub UI, consider pasting the commits 520into `<details>` tags or in follow up comments. 521 522If using the `<details>` tag, use the following format: 523 524```markdown 525<details> 526<summary>Commits</summary> 527 528* Full list of commits... 529</details> 530``` 531 532If you need any additional information about any of the commits, this PR is a 533good place to @-mention the relevant contributors. 534 535After opening the PR, update the release commit to include `PR-URL` metadata and 536force-push the proposal. 537 538<details> 539<summary>Security release</summary> 540 541If there are private security patches, remember to push and open the proposal 542in the `nodejs-private` GitHub repository. 543 544</details> 545 546### 7. Ensure that the release branch is stable 547 548Run a **[`node-test-pull-request`](https://ci.nodejs.org/job/node-test-pull-request/)** 549test run to ensure that the build is stable and the HEAD commit is ready for 550release. 551 552Also run a **[`node-test-commit-v8-linux`](https://ci.nodejs.org/job/node-test-commit-v8-linux/)** 553test run if the release contains changes to `deps/v8`. 554 555Perform some smoke-testing. There is the 556**[`citgm-smoker`](https://ci.nodejs.org/job/citgm-smoker/)** CI job for this 557purpose. Run it once with the base `vx.x` branch as a reference and with the 558proposal branch to check if new regressions could be introduced in the 559ecosystem. 560 561Use `ncu-ci` to compare `vx.x` run (10) and proposal branch (11) 562 563```console 564$ npm i -g node-core-utils 565$ ncu-ci citgm 10 11 566``` 567 568<details> 569<summary>Security release</summary> 570 571If there are private security patches, do not run any CI jobs on the proposal 572until CI has been locked down. The security steward should be coordinating this 573with the Build Working Group. 574 575</details> 576 577#### 7.1 Updating the release _(optional)_ 578 579Sometimes a release might be deferred to the subsequent day due to several 580conditions: 581 582* Unstable CI 583* Late CI completion 584 585And when it happens, the CHANGELOG\_Vx and the commit metadata needs to be 586updated according to the new target date. 587 588However, if it's just the changelog/commit message that has changed since the 589last CI execution, there's no need to rerun CI, V8, or CITGM workflows. 590The PR still needs a clean GitHub action run, and the original CI, V8, and 591CITGM run should be in a visible comment. 592 593There are some cases when a commit needs to be dropped or adjusted, 594consider using the following approach: 595 5961. Update staging 597 598```console 599$ git checkout v1.x-staging 600$ git rebase -i $HASH_PREVIOUS_BAD_COMMIT 601... drop or edit the bad commit(s) 602$ git push -f upstream v1.x-staging 603``` 604 6052. Rebase the proposal against the updated staging branch 606 607```console 608$ git checkout v1.2.3-proposal 609$ git checkout -b v1.2.3-proposal-tmp 610$ git checkout v1.2.3-proposal 611 612$ git reset --hard upstream/v1.x-staging 613$ git cherry-pick v1.2.3-proposal-tmp 614``` 615 616Note the `tmp` branch was created just to save the release commit. 617 6183. Re-run `changelog-maker` and update the CHANGELOG\_Vx to include the new 619 Git SHAs. Remember to update the commit message if applicable. 620 621### 8. Produce a nightly build _(optional)_ 622 623If there is a reason to produce a test release for the purpose of having others 624try out installers or specifics of builds, produce a nightly build using 625**[iojs+release](https://ci-release.nodejs.org/job/iojs+release/)** and wait for 626it to drop in <https://nodejs.org/download/nightly/>. Follow the directions and 627enter a proper length commit SHA, enter a date string, and select "nightly" for 628"disttype". 629 630This is particularly recommended if there has been recent work relating to the 631macOS or Windows installers as they are not tested in any way by CI. 632 633<details> 634<summary>Security release</summary> 635 636Do not produce a release candidate build. 637 638</details> 639 640### 9. Produce release builds 641 642Use **[iojs+release](https://ci-release.nodejs.org/job/iojs+release/)** to 643produce release artifacts. Enter the commit that you want to build from and 644select "release" for "disttype". 645 646Artifacts from each worker are uploaded to Jenkins and are available if further 647testing is required. Use this opportunity particularly to test macOS and Windows 648installers if there are any concerns. Click through to the individual workers 649for a run to find the artifacts. 650 651All release workers should achieve "SUCCESS" (and be green, not red). A release 652with failures should not be promoted as there are likely problems to be 653investigated. 654 655You can rebuild the release as many times as you need prior to promoting them if 656you encounter problems. 657 658If you have an error on Windows and need to start again, be aware that you'll 659get immediate failure unless you wait up to 2 minutes for the linker to stop 660from previous jobs. i.e. if a build fails after having started compiling, that 661worker will still have a linker process that's running for another couple of 662minutes which will prevent Jenkins from clearing the workspace to start a new 663one. This isn't a big deal, it's just a hassle because it'll result in another 664failed build if you start again! 665 666### 10. Test the build 667 668Jenkins collects the artifacts from the builds, allowing you to download and 669install the new build. Make sure that the build appears correct. Check the 670version numbers, and perform some basic checks to confirm that all is well with 671the build before moving forward. Use the following list as a baseline: 672 673* `process.version` is as expected 674* `process.release` is as expected 675* `process.versions` is as expected (for example, `openssl` or `llhttp` version 676 must be in the expected updated version) 677* npm version (check it matches what we expect) 678* Run the test suite against the built binaries (optional) 679 * Remember to use the proposal branch 680 * Run `make build-addons` before running the tests 681 * Remove `config.gypi` file 682 683```console 684./tools/test.py --shell ~/Downloads/node-v18.5.0-linux-x64/bin/node 685``` 686 687### 11. Tag and sign the release commit 688 689Once you have produced builds that you're happy with, create a new tag. By 690waiting until this stage to create tags, you can discard a proposed release if 691something goes wrong or additional commits are required. Once you have created a 692tag and pushed it to GitHub, you _**must not**_ delete and re-tag. If you make 693a mistake after tagging then you'll have to version-bump and start again and 694count that tag/version as lost. 695 696Tag summaries have a predictable format. Look at a recent tag to see: 697 698```console 699git tag -v v6.0.0 700``` 701 702The message should look something like 703`2016-04-26 Node.js v6.0.0 (Current) Release`. 704 705Install `git-secure-tag` npm module: 706 707```console 708$ npm install -g git-secure-tag 709``` 710 711Create a tag using the following command: 712 713```console 714$ git secure-tag <vx.y.z> <commit-sha> -sm "YYYY-MM-DD Node.js vx.y.z (<release-type>) Release" 715``` 716 717<sup>The commit-sha is the release commit. You can get it easily by running `git rev-parse HEAD`</sup> 718 719`release-type` is either "Current" or "LTS". For LTS releases, you should also 720include the release code name. 721 722```text 7232019-10-22 Node.js v10.17.0 'Dubnium' (LTS) Release 724``` 725 726The tag **must** be signed using the GPG key that's listed for you on the 727project README. 728 729**Note**: Don't push the tag to remote at this point. 730 731### 12. Set up for the next release 732 733On release proposal branch, edit `src/node_version.h` again and: 734 735* Increment `NODE_PATCH_VERSION` by one 736* Change `NODE_VERSION_IS_RELEASE` back to `0` 737 738Commit this change with the following commit message format: 739 740```text 741Working on vx.y.z # where 'z' is the incremented patch number 742 743PR-URL: <full URL to your release proposal PR> 744``` 745 746This sets up the branch so that nightly builds are produced with the next 747version number _and_ a pre-release tag. 748 749Merge your release proposal branch into the stable branch that you are releasing 750from and rebase the corresponding staging branch on top of that. 751 752```console 753$ git checkout v1.x 754$ git merge --ff-only v1.2.3-proposal 755$ git push upstream v1.x 756$ git checkout v1.x-staging 757$ git rebase v1.x 758$ git push upstream v1.x-staging 759``` 760 761<details> 762<summary>Security release</summary> 763 764For security releases, you can start merging the release in the `nodejs-private` 765GitHub organization in advance by following the same steps: 766 767```console 768$ git checkout v1.x 769$ git merge --ff-only v1.2.3-proposal 770$ git push private v1.x 771$ git checkout v1.x-staging 772$ git rebase v1.x 773$ git push private v1.x-staging 774``` 775 776Once all releasers are ready, you can push each of the branches to the public 777repository. 778 779</details> 780 781### 13. Cherry-pick the release commit to `main` 782 783```console 784$ git checkout main 785$ git pull upstream main 786$ git cherry-pick --strategy-option=diff-algorithm=patience v1.x^ 787``` 788 789Git should stop to let you fix conflicts. 790 791Revert all changes that were made to `src/node_version.h`: 792 793```console 794$ git checkout --ours HEAD -- src/node_version.h 795``` 796 797<details> 798<summary>Major version release</summary> 799 800On the main branch, instead of reverting changes made to `src/node_version.h` 801edit it instead and: 802 803* Increment `NODE_MAJOR_VERSION` by one 804* Reset `NODE_PATCH_VERSION` to `0` 805* Change `NODE_VERSION_IS_RELEASE` back to `0` 806 807Amend the current commit to apply the changes: 808 809```console 810$ git commit --amend 811``` 812 813</details> 814 815Even if there are no conflicts, ensure that you revert all the changes that were 816made to `src/node_version.h`. 817 818If there are conflicts in `doc` due to updated `REPLACEME` 819placeholders (that happens when a change previously landed on another release 820branch), keep both version numbers. Convert the YAML field to an array if it is 821not already one. 822 823[It's possible that the `cherry-pick` step will end up adding and/or 824changing unwanted lines](https://github.com/nodejs/Release/issues/771), 825please validate the changes in `doc/` folder files before confirming/continuing 826the cherry-pick step. 827 828Then finish cherry-picking and push the commit upstream: 829 830```console 831$ git add src/node_version.h doc 832$ git diff --staged src doc # read output to validate that changes shows up as expected 833$ git cherry-pick --continue 834$ make lint-md && make lint-cpp 835$ git push upstream main 836``` 837 838**Do not** cherry-pick the "Working on vx.y.z" commit to `main`. 839 840<details> 841<summary>Security release</summary> 842 843For security releases, you will also need to land the fixes on the `main` 844branch (if they apply there). Often, you can just cherry-pick the same commit 845that landed in the `current` security release which should already have the 846metadata. 847 848It is useful to first push the patches to `private/main` to check that the 849GitHub actions runs pass, before pushing to `upstream/main`: 850 851```console 852$ git checkout main 853$ git reset --hard upstream/main 854$ git cherry-pick ... # apply the patches which apply to main 855$ git push private main # push to private main first run GitHub actions 856$ git push upstream main 857``` 858 859</details> 860 861### 14. Push the release tag 862 863Push the tag to the repository before you promote the builds. If you 864haven't pushed your tag first, then build promotion won't work properly. 865Push the tag using the following command: 866 867```console 868$ git push upstream v1.2.3 869``` 870 871_Note_: Please do not push the tag unless you are ready to complete the 872remainder of the release steps. 873 874### 15. Promote and sign the release builds 875 876**The same individual who signed the release tag must be the one 877to promote the builds as the `SHASUMS256.txt` file needs to be signed with the 878same GPG key!** 879 880Use `tools/release.sh` to promote and sign the build. Before doing this, you'll 881need to ensure you've loaded the correct ssh key, or you'll see the following: 882 883```console 884# Checking for releases ... 885Enter passphrase for key '/Users/<user>/.ssh/id_rsa': 886dist@direct.nodejs.org's password: 887``` 888 889The key can be loaded either with `ssh-add`: 890 891```console 892# Substitute node_id_rsa with whatever you've named the key 893$ ssh-add ~/.ssh/node_id_rsa 894``` 895 896or at runtime with: 897 898```console 899# Substitute node_id_rsa with whatever you've named the key 900$ ./tools/release.sh -i ~/.ssh/node_id_rsa 901``` 902 903You can also specify a different ssh server address to connect to by defining 904a `NODEJS_RELEASE_HOST` environment variable: 905 906```console 907# Substitute proxy.xyz with whatever address you intend to use 908$ NODEJS_RELEASE_HOST=proxy.xyz ./tools/release.sh 909``` 910 911`tools/release.sh` will perform the following actions when run: 912 913<details> 914 915**a.** Select a GPG key from your private keys. It will use a command similar 916to: `gpg --list-secret-keys` to list your keys. If you don't have any keys, it 917will bail. If you have only one key, it will use that. If you have more than 918one key it will ask you to select one from the list. Be sure to use the same 919key that you signed your git tag with. 920 921**b.** Log in to the server via SSH and check for releases that can be promoted, 922along with the list of artifacts. It will use the `dist-promotable` command on 923the server to find these. You will be asked, for each promotable release, 924whether you want to proceed. If there is more than one release to promote (there 925shouldn't be), be sure to only promote the release you are responsible for. 926 927**c.** Log in to the server via SSH and run the promote script for the given 928release. The command on the server will be similar to: `dist-promote vx.y.z`. 929After this step, the release artifacts will be available for download and a 930`SHASUMS256.txt` file will be present. The release will still be unsigned, 931however. 932 933**d.** Use `scp` to download `SHASUMS256.txt` to a temporary directory on your 934computer. 935 936**e.** Sign the `SHASUMS256.txt` file using a command similar to: `gpg --default-key YOURKEY --digest-algo SHA256 --clearsign /path/to/SHASUMS256.txt`. 937You will be prompted by GPG for your password. The signed file will be named 938SHASUMS256.txt.asc. 939 940**f.** Output an ASCII armored version of your public GPG key using a command 941similar to: `gpg --default-key YOURKEY --digest-algo SHA256 --detach-sign /path/to/SHASUMS256.txt`. 942You will be prompted by GPG for your password. The signed file will be named 943SHASUMS256.txt.sig. 944 945**g.** Upload the `SHASUMS256.txt` files back to the server into the release 946directory. 947 948</details> 949 950**It is possible to only sign a release by running `./tools/release.sh -s 951vX.Y.Z`.** 952 953### 16. Check the release 954 955Your release should be available at `https://nodejs.org/dist/vx.y.z/` and 956<https://nodejs.org/dist/latest/>. Check that the appropriate files are in 957place. You may want to check that the binaries are working as appropriate and 958have the right internal version strings. Check that the API docs are available 959at <https://nodejs.org/api/>. Check that the release catalog files are correct 960at <https://nodejs.org/dist/index.tab> and <https://nodejs.org/dist/index.json>. 961 962### 17. Create a blog post 963 964There is an automatic build that is kicked off when you promote new builds, so 965within a few minutes nodejs.org will be listing your new version as the latest 966release. However, the blog post is not yet fully automatic. 967 968Create a new blog post by running the [nodejs.org release-post.js script][]: 969 970```console 971$ node ./scripts/release-post/index.mjs x.y.z 972``` 973 974This script will use the promoted builds and changelog to generate the post. Run 975`npm run serve` to preview the post locally before pushing to the 976[nodejs.org repository][]. 977 978* You can add a short blurb just under the main heading if you want to say 979 something important, otherwise the text should be publication ready. 980 981* The links to the download files won't be complete unless you waited for the 982 ARMv6 builds. Any downloads that are missing will have `*Coming soon*` next to 983 them. It's your responsibility to manually update these later when you have 984 the outstanding builds. 985 986* The `SHASUMS256.txt.asc` content is at the bottom of the post. When you update 987 the list of tarballs you'll need to copy/paste the new contents of this file 988 to reflect those changes. 989 990* Always use pull-requests on the [nodejs.org repository][]. Be respectful 991 of the website team, but you do not have to wait for PR sign-off. Please 992 use the following commit message format: 993 994 ```console 995 Blog: vX.Y.Z release post 996 997 Refs: <full URL to your release proposal PR> 998 ``` 999 1000* Changes to the base branch, `main`, on the [nodejs.org repository][] will 1001 trigger a new build of nodejs.org so your changes should appear a few minutes 1002 after pushing. 1003 1004### 18. Create the release on GitHub 1005 1006* Go to the [New release page](https://github.com/nodejs/node/releases/new). 1007* Select the tag version you pushed earlier. 1008* For release title, copy the title from the changelog. 1009* For the description, copy the rest of the changelog entry. 1010* If you are not releasing the latest "Current", uncheck 1011 "Set as the latest release". 1012* Click on the "Publish release" button. 1013 1014### 19. Announce 1015 1016The nodejs.org website will automatically rebuild and include the new version. 1017To announce the build on Twitter through the official @nodejs account, email 1018<pr@nodejs.org> with a message such as: 1019 1020> v5.8.0 of @nodejs is out: <https://nodejs.org/en/blog/release/v5.8.0/> 1021> … 1022> something here about notable changes 1023 1024To ensure communication goes out with the timing of the blog post, please allow 102524 hour prior notice. If known, please include the date and time the release 1026will be shared with the community in the email to coordinate these 1027announcements. 1028 1029Ping the IRC ops and the other [Partner Communities][] liaisons. 1030 1031<details> 1032<summary>Security release</summary> 1033 1034Let the security release steward know the releases are available. 1035 1036</details> 1037 1038### 20. Celebrate 1039 1040_In whatever form you do this..._ 1041 1042## LTS Releases 1043 1044### Marking a release line as LTS 1045 1046The process of marking a release line as LTS has been automated using 1047[node-core-utils](https://github.com/nodejs/node-core-utils). 1048 1049Start by checking out the staging branch for the release line that is going to 1050be marked as LTS, e.g: 1051 1052```console 1053$ git checkout v1.x-staging 1054``` 1055 1056Next, make sure you have **node-core-utils** installed: 1057 1058```console 1059$ npm i -g node-core-utils 1060``` 1061 1062Run the prepare LTS release command: 1063 1064```console 1065$ git node release --prepare --startLTS 1066``` 1067 1068<details> 1069<summary>Manual steps for reference.</summary> 1070 1071To mark a release line as LTS, the following changes must be made to 1072`src/node_version.h`: 1073 1074* The `NODE_MINOR_VERSION` macro must be incremented by one 1075* The `NODE_PATCH_VERSION` macro must be set to `0` 1076* The `NODE_VERSION_IS_LTS` macro must be set to `1` 1077* The `NODE_VERSION_LTS_CODENAME` macro must be set to the code name selected 1078 for the LTS release. 1079 1080For example: 1081 1082```diff 1083-#define NODE_MINOR_VERSION 12 1084-#define NODE_PATCH_VERSION 1 1085+#define NODE_MINOR_VERSION 13 1086+#define NODE_PATCH_VERSION 0 1087 1088-#define NODE_VERSION_IS_LTS 0 1089-#define NODE_VERSION_LTS_CODENAME "" 1090+#define NODE_VERSION_IS_LTS 1 1091+#define NODE_VERSION_LTS_CODENAME "Erbium" 1092 1093-#define NODE_VERSION_IS_RELEASE 0 1094+#define NODE_VERSION_IS_RELEASE 1 1095``` 1096 1097The changes must be made as part of a new semver-minor release. 1098 1099Updating changelogs to properly reflect the changes between **Current** and 1100**Long Term Support** is also necessary, along with adding a reference to the 1101current LTS codename in its release line changelog file. 1102 1103The `test/parallel/test-process-release.js` file might also need to be updated. 1104 1105In case you can not run the automated `node-core-utils` command and you are 1106currently running these steps manually it's a good idea to refer to previous 1107LTS proposal PRs and make sure all required changes are covered. 1108 1109</details> 1110 1111### Update release labels 1112 1113The `lts-watch-vN.x` issue label must be created, with the same color as other 1114existing labels for that release line, such as `vN.x`. 1115 1116If the release is transitioning from Active LTS to Maintenance, the 1117`backport-requested-vN.x` label must be deleted. 1118 1119### Add new codename to nodejs-latest-linker 1120 1121In order to make sure a download URL 1122(e.g: <https://nodejs.org/download/release/latest-codename/>) will be available 1123for the new LTS release line you need to submit a PR to 1124<https://github.com/nodejs/nodejs-latest-linker> and add a new entry for the 1125new LTS codename in its `ltsNames` map located in the `./latest-linker.js` 1126file. 1127 1128Make sure to reach out to the Build WG in order to validate that the new URL is 1129available as part of the LTS release promotion. 1130 1131### Update Release repo info 1132 1133Add the new LTS codename to the release schedule table located in the 1134`./README.md` file located at the <https://github.com/nodejs/Release> 1135repository along with the addition of the new codename to the `./schedule.json` 1136file in that same repo. 1137 1138## Major releases 1139 1140The process for cutting a new Node.js major release has a number of differences 1141from cutting a minor or patch release. 1142 1143### Schedule 1144 1145New Node.js Major releases happen twice per year: 1146 1147* Even-numbered releases are cut in April. 1148* Odd-numbered releases are cut in October. 1149 1150Major releases should be targeted for the third Tuesday of the release month. 1151 1152A major release must not slip beyond the release month. In other words, major 1153releases must not slip into May or November. 1154 1155The @nodejs/releasers make a call for releasers 3 months in advance. 1156Currently, this call is automated in the `#nodejs-release-private` 1157Slack channel. 1158 1159The release date for the next major release should be announced immediately 1160following the current release (e.g. the release date for 13.0.0 should be 1161announced immediately following the release of 12.0.0). 1162 1163### Release branch 1164 1165Approximately two months before a major release, new `vN.x` and 1166`vN.x-staging` branches (where `N` indicates the major release) should be 1167created as forks of the `main` branch. Up until the cut-off date announced by 1168the releaser, these must be kept in sync with `main`. 1169 1170The `vN.x` and `vN.x-staging` branches must be kept in sync with one another 1171up until the date of the release. 1172 1173The TSC should be informed of any `SEMVER-MAJOR` commits that land within one 1174month of the release. 1175 1176### Create release labels 1177 1178The following issue labels must be created: 1179 1180* `vN.x` 1181* `backport-blocked-vN.x` 1182* `backport-open-vN.x` 1183* `backport-requested-vN.x` 1184* `backported-to-vN.x` 1185* `dont-land-on-vN.x` 1186 1187The label description can be copied from existing labels of previous releases. 1188The label color must be the same for all new labels, but different from the 1189labels of previous releases. 1190 1191### Release proposal 1192 1193A draft release proposal should be created 6 weeks before the release. A 1194separate `vN.x-proposal` branch should be created that tracks the `vN.x` 1195branch. This branch will contain the draft release commit (with the draft 1196changelog). 1197 1198Notify the `@nodejs/npm` team in the release proposal PR to inform them of the 1199upcoming release. `npm` maintains a list of [supported versions](https://github.com/npm/cli/blob/latest/lib/utils/unsupported.js#L3) 1200that will need updating to include the new major release. 1201 1202### Update `NODE_MODULE_VERSION` 1203 1204This macro in `src/node_version.h` is used to signal an ABI version for native 1205addons. It currently has two common uses in the community: 1206 1207* Determining what API to work against for compiling native addons, e.g. 1208 [NAN](https://github.com/nodejs/nan) uses it to form a compatibility-layer for 1209 much of what it wraps. 1210* Determining the ABI for downloading pre-built binaries of native addons, e.g. 1211 [node-pre-gyp](https://github.com/mapbox/node-pre-gyp) uses this value as 1212 exposed via `process.versions.modules` to help determine the appropriate 1213 binary to download at install-time. 1214 1215The general rule is to bump this version when there are _breaking ABI_ changes 1216and also if there are non-trivial API changes. The rules are not yet strictly 1217defined, so if in doubt, please confer with someone that will have a more 1218informed perspective, such as a member of the NAN team. 1219 1220A registry of currently used `NODE_MODULE_VERSION` values is maintained at 1221<https://github.com/nodejs/node/blob/HEAD/doc/abi_version_registry.json>. 1222When bumping `NODE_MODULE_VERSION`, you should choose a new value not listed 1223in the registry. Also include a change to the registry in your commit to 1224reflect the newly used value. Ensure that the release commit removes the 1225`-pre` suffix for the major version being prepared. 1226 1227It is current TSC policy to bump major version when ABI changes. If you 1228see a need to bump `NODE_MODULE_VERSION` outside of a major release then 1229you should consult the TSC. Commits may need to be reverted or a major 1230version bump may need to happen. 1231 1232### Test releases and release candidates 1233 1234Test builds should be generated from the `vN.x-proposal` branch starting at 1235about 6 weeks before the release. 1236 1237Release Candidates should be generated from the `vN.x-proposal` branch starting 1238at about 4 weeks before the release, with a target of one release candidate 1239per week. 1240 1241Always run test releases and release candidates through the Canary in the 1242Goldmine tool for additional testing. 1243 1244### Changelogs 1245 1246Generating major release changelogs is a bit more involved than minor and patch 1247changelogs. 1248 1249#### Create the changelog file 1250 1251In the `doc/changelogs` directory, create a new `CHANGELOG_V{N}.md` file where 1252`{N}` is the major version of the release. Follow the structure of the existing 1253`CHANGELOG_V*.md` files. 1254 1255The navigation headers in all of the `CHANGELOG_V*.md` files must be 1256updated to account for the new `CHANGELOG_V{N}.md` file. 1257 1258Once the file is created, the root `CHANGELOG.md` file must be updated to 1259reference the newly-created major release `CHANGELOG_V{N}.md`. 1260 1261#### Generate the changelog 1262 1263To generate a proper major release changelog, use the `branch-diff` tool to 1264compare the `vN.x` branch against the `vN-1.x` branch (e.g. for Node.js 12.0, 1265we compare the `v12.x` branch against the up to date `v11.x` branch). Make sure 1266that the local copy of the downlevel branch is up to date. 1267 1268The commits in the generated changelog must then be organized: 1269 1270* Remove all release commits from the list 1271* Remove all reverted commits and their reverts 1272* Separate all SEMVER-MAJOR, SEMVER-MINOR, and SEMVER-PATCH commits into lists 1273 1274#### Generate the notable changes 1275 1276For a major release, all SEMVER-MAJOR commits that are not strictly internal, 1277test, or doc-related are to be listed as notable changes. Some SEMVER-MINOR 1278commits may be listed as notable changes on a case-by-case basis. Use your 1279judgment there. 1280 1281### Update the expected assets 1282 1283The promotion script does a basic check that the expected files are present. 1284Open a pull request in the Build repository to add the list of expected files 1285for the new release line as a new file, `v{N}.x` (where `{N}` is the major 1286version of the release), in the [expected assets][] folder. The change will 1287need to be deployed onto the web server by a member of the [build-infra team][] 1288before the release is promoted. 1289 1290### Snap 1291 1292The Node.js [Snap][] package has a "default" for installs where the user hasn't 1293specified a release line ("track" in Snap terminology). This should be updated 1294to point to the most recently activated LTS. A member of the Node.js Build 1295Infrastructure team is able to perform the switch of the default. An issue 1296should be opened on the [Node.js Snap management repository][] requesting this 1297take place once a new LTS line has been released. 1298 1299[Build issue tracker]: https://github.com/nodejs/build/issues/new 1300[CI lockdown procedure]: https://github.com/nodejs/build/blob/HEAD/doc/jenkins-guide.md#restricting-access-for-security-releases 1301[Node.js Snap management repository]: https://github.com/nodejs/snap 1302[Partner Communities]: https://github.com/nodejs/community-committee/blob/HEAD/governance/PARTNER_COMMUNITIES.md 1303[Snap]: https://snapcraft.io/node 1304[build-infra team]: https://github.com/orgs/nodejs/teams/build-infra 1305[expected assets]: https://github.com/nodejs/build/tree/HEAD/ansible/www-standalone/tools/promote/expected_assets 1306[nodejs.org release-post.js script]: https://github.com/nodejs/nodejs.org/blob/HEAD/scripts/release-post/index.mjs 1307[nodejs.org repository]: https://github.com/nodejs/nodejs.org 1308