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`. `NODE_VERSION_IS_RELEASE` must be `0`. 817 818<sup>Edit `src/node_version.h`, revert `NODE_VERSION_IS_RELEASE` back to `0`, and `git commit --amend`</sup> 819 820If there are conflicts in `doc` due to updated `REPLACEME` 821placeholders (that happens when a change previously landed on another release 822branch), keep both version numbers. Convert the YAML field to an array if it is 823not already one. 824 825[It's possible that the `cherry-pick` step will end up adding and/or 826changing unwanted lines](https://github.com/nodejs/Release/issues/771), 827please validate the changes in `doc/` folder files before confirming/continuing 828the cherry-pick step. 829 830Then finish cherry-picking and push the commit upstream: 831 832```console 833$ git add src/node_version.h doc 834$ git diff --staged src doc # read output to validate that changes shows up as expected 835$ git cherry-pick --continue 836$ make lint-md && make lint-cpp 837$ git push upstream main 838``` 839 840**Do not** cherry-pick the "Working on vx.y.z" commit to `main`. 841 842<details> 843<summary>Security release</summary> 844 845For security releases, you will also need to land the fixes on the `main` 846branch (if they apply there). Often, you can just cherry-pick the same commit 847that landed in the `current` security release which should already have the 848metadata. 849 850It is useful to first push the patches to `private/main` to check that the 851GitHub actions runs pass, before pushing to `upstream/main`: 852 853```console 854$ git checkout main 855$ git reset --hard upstream/main 856$ git cherry-pick ... # apply the patches which apply to main 857$ git push private main # push to private main first run GitHub actions 858$ git push upstream main 859``` 860 861</details> 862 863### 14. Push the release tag 864 865Push the tag to the repository before you promote the builds. If you 866haven't pushed your tag first, then build promotion won't work properly. 867Push the tag using the following command: 868 869```console 870$ git push upstream v1.2.3 871``` 872 873_Note_: Please do not push the tag unless you are ready to complete the 874remainder of the release steps. 875 876### 15. Promote and sign the release builds 877 878**The same individual who signed the release tag must be the one 879to promote the builds as the `SHASUMS256.txt` file needs to be signed with the 880same GPG key!** 881 882Use `tools/release.sh` to promote and sign the build. Before doing this, you'll 883need to ensure you've loaded the correct ssh key, or you'll see the following: 884 885```console 886# Checking for releases ... 887Enter passphrase for key '/Users/<user>/.ssh/id_rsa': 888dist@direct.nodejs.org's password: 889``` 890 891The key can be loaded either with `ssh-add`: 892 893```console 894# Substitute node_id_rsa with whatever you've named the key 895$ ssh-add ~/.ssh/node_id_rsa 896``` 897 898or at runtime with: 899 900```console 901# Substitute node_id_rsa with whatever you've named the key 902$ ./tools/release.sh -i ~/.ssh/node_id_rsa 903``` 904 905You can also specify a different ssh server address to connect to by defining 906a `NODEJS_RELEASE_HOST` environment variable: 907 908```console 909# Substitute proxy.xyz with whatever address you intend to use 910$ NODEJS_RELEASE_HOST=proxy.xyz ./tools/release.sh 911``` 912 913`tools/release.sh` will perform the following actions when run: 914 915<details> 916 917**a.** Select a GPG key from your private keys. It will use a command similar 918to: `gpg --list-secret-keys` to list your keys. If you don't have any keys, it 919will bail. If you have only one key, it will use that. If you have more than 920one key it will ask you to select one from the list. Be sure to use the same 921key that you signed your git tag with. 922 923**b.** Log in to the server via SSH and check for releases that can be promoted, 924along with the list of artifacts. It will use the `dist-promotable` command on 925the server to find these. You will be asked, for each promotable release, 926whether you want to proceed. If there is more than one release to promote (there 927shouldn't be), be sure to only promote the release you are responsible for. 928 929**c.** Log in to the server via SSH and run the promote script for the given 930release. The command on the server will be similar to: `dist-promote vx.y.z`. 931After this step, the release artifacts will be available for download and a 932`SHASUMS256.txt` file will be present. The release will still be unsigned, 933however. 934 935**d.** Use `scp` to download `SHASUMS256.txt` to a temporary directory on your 936computer. 937 938**e.** Sign the `SHASUMS256.txt` file using a command similar to: `gpg --default-key YOURKEY --digest-algo SHA256 --clearsign /path/to/SHASUMS256.txt`. 939You will be prompted by GPG for your password. The signed file will be named 940SHASUMS256.txt.asc. 941 942**f.** Output an ASCII armored version of your public GPG key using a command 943similar to: `gpg --default-key YOURKEY --digest-algo SHA256 --detach-sign /path/to/SHASUMS256.txt`. 944You will be prompted by GPG for your password. The signed file will be named 945SHASUMS256.txt.sig. 946 947**g.** Upload the `SHASUMS256.txt` files back to the server into the release 948directory. 949 950</details> 951 952**It is possible to only sign a release by running `./tools/release.sh -s 953vX.Y.Z`.** 954 955### 16. Check the release 956 957Your release should be available at `https://nodejs.org/dist/vx.y.z/` and 958<https://nodejs.org/dist/latest/>. Check that the appropriate files are in 959place. You may want to check that the binaries are working as appropriate and 960have the right internal version strings. Check that the API docs are available 961at <https://nodejs.org/api/>. Check that the release catalog files are correct 962at <https://nodejs.org/dist/index.tab> and <https://nodejs.org/dist/index.json>. 963 964### 17. Create a blog post 965 966There is an automatic build that is kicked off when you promote new builds, so 967within a few minutes nodejs.org will be listing your new version as the latest 968release. However, the blog post is not yet fully automatic. 969 970Create a new blog post by running the [nodejs.org release-post.js script][]: 971 972```console 973$ node ./scripts/release-post/index.mjs x.y.z 974``` 975 976This script will use the promoted builds and changelog to generate the post. Run 977`npm run serve` to preview the post locally before pushing to the 978[nodejs.org repository][]. 979 980* You can add a short blurb just under the main heading if you want to say 981 something important, otherwise the text should be publication ready. 982 983* The links to the download files won't be complete unless you waited for the 984 ARMv6 builds. Any downloads that are missing will have `*Coming soon*` next to 985 them. It's your responsibility to manually update these later when you have 986 the outstanding builds. 987 988* The `SHASUMS256.txt.asc` content is at the bottom of the post. When you update 989 the list of tarballs you'll need to copy/paste the new contents of this file 990 to reflect those changes. 991 992* Always use pull-requests on the [nodejs.org repository][]. Be respectful 993 of the website team, but you do not have to wait for PR sign-off. Please 994 use the following commit message format: 995 996 ```console 997 Blog: vX.Y.Z release post 998 999 Refs: <full URL to your release proposal PR> 1000 ``` 1001 1002* Changes to the base branch, `main`, on the [nodejs.org repository][] will 1003 trigger a new build of nodejs.org so your changes should appear a few minutes 1004 after pushing. 1005 1006### 18. Create the release on GitHub 1007 1008* Go to the [New release page](https://github.com/nodejs/node/releases/new). 1009* Select the tag version you pushed earlier. 1010* For release title, copy the title from the changelog. 1011* For the description, copy the rest of the changelog entry. 1012* If you are not releasing the latest "Current", uncheck 1013 "Set as the latest release". 1014* Click on the "Publish release" button. 1015 1016### 19. Announce 1017 1018The nodejs.org website will automatically rebuild and include the new version. 1019To announce the build on Twitter through the official @nodejs account, email 1020<pr@nodejs.org> with a message such as: 1021 1022> v5.8.0 of @nodejs is out: <https://nodejs.org/en/blog/release/v5.8.0/> 1023> … 1024> something here about notable changes 1025 1026To ensure communication goes out with the timing of the blog post, please allow 102724 hour prior notice. If known, please include the date and time the release 1028will be shared with the community in the email to coordinate these 1029announcements. 1030 1031Ping the IRC ops and the other [Partner Communities][] liaisons. 1032 1033<details> 1034<summary>Security release</summary> 1035 1036Let the security release steward know the releases are available. 1037 1038</details> 1039 1040### 20. Celebrate 1041 1042_In whatever form you do this..._ 1043 1044## LTS Releases 1045 1046### Marking a release line as LTS 1047 1048The process of marking a release line as LTS has been automated using 1049[node-core-utils](https://github.com/nodejs/node-core-utils). 1050 1051Start by checking out the staging branch for the release line that is going to 1052be marked as LTS, e.g: 1053 1054```console 1055$ git checkout v1.x-staging 1056``` 1057 1058Next, make sure you have **node-core-utils** installed: 1059 1060```console 1061$ npm i -g node-core-utils 1062``` 1063 1064Run the prepare LTS release command: 1065 1066```console 1067$ git node release --prepare --startLTS 1068``` 1069 1070<details> 1071<summary>Manual steps for reference.</summary> 1072 1073To mark a release line as LTS, the following changes must be made to 1074`src/node_version.h`: 1075 1076* The `NODE_MINOR_VERSION` macro must be incremented by one 1077* The `NODE_PATCH_VERSION` macro must be set to `0` 1078* The `NODE_VERSION_IS_LTS` macro must be set to `1` 1079* The `NODE_VERSION_LTS_CODENAME` macro must be set to the code name selected 1080 for the LTS release. 1081 1082For example: 1083 1084```diff 1085-#define NODE_MINOR_VERSION 12 1086-#define NODE_PATCH_VERSION 1 1087+#define NODE_MINOR_VERSION 13 1088+#define NODE_PATCH_VERSION 0 1089 1090-#define NODE_VERSION_IS_LTS 0 1091-#define NODE_VERSION_LTS_CODENAME "" 1092+#define NODE_VERSION_IS_LTS 1 1093+#define NODE_VERSION_LTS_CODENAME "Erbium" 1094 1095-#define NODE_VERSION_IS_RELEASE 0 1096+#define NODE_VERSION_IS_RELEASE 1 1097``` 1098 1099The changes must be made as part of a new semver-minor release. 1100 1101Updating changelogs to properly reflect the changes between **Current** and 1102**Long Term Support** is also necessary, along with adding a reference to the 1103current LTS codename in its release line changelog file. 1104 1105The `test/parallel/test-process-release.js` file might also need to be updated. 1106 1107In case you can not run the automated `node-core-utils` command and you are 1108currently running these steps manually it's a good idea to refer to previous 1109LTS proposal PRs and make sure all required changes are covered. 1110 1111</details> 1112 1113### Update release labels 1114 1115The `lts-watch-vN.x` issue label must be created, with the same color as other 1116existing labels for that release line, such as `vN.x`. 1117 1118If the release is transitioning from Active LTS to Maintenance, the 1119`backport-requested-vN.x` label must be deleted. 1120 1121### Add new codename to nodejs-latest-linker 1122 1123In order to make sure a download URL 1124(e.g: <https://nodejs.org/download/release/latest-codename/>) will be available 1125for the new LTS release line you need to submit a PR to 1126<https://github.com/nodejs/nodejs-latest-linker> and add a new entry for the 1127new LTS codename in its `ltsNames` map located in the `./latest-linker.js` 1128file. 1129 1130Make sure to reach out to the Build WG in order to validate that the new URL is 1131available as part of the LTS release promotion. 1132 1133### Update Release repo info 1134 1135Add the new LTS codename to the release schedule table located in the 1136`./README.md` file located at the <https://github.com/nodejs/Release> 1137repository along with the addition of the new codename to the `./schedule.json` 1138file in that same repo. 1139 1140## Major releases 1141 1142The process for cutting a new Node.js major release has a number of differences 1143from cutting a minor or patch release. 1144 1145### Schedule 1146 1147New Node.js Major releases happen twice per year: 1148 1149* Even-numbered releases are cut in April. 1150* Odd-numbered releases are cut in October. 1151 1152Major releases should be targeted for the third Tuesday of the release month. 1153 1154A major release must not slip beyond the release month. In other words, major 1155releases must not slip into May or November. 1156 1157The @nodejs/releasers make a call for releasers 3 months in advance. 1158Currently, this call is automated in the `#nodejs-release-private` 1159Slack channel. 1160 1161The release date for the next major release should be announced immediately 1162following the current release (e.g. the release date for 13.0.0 should be 1163announced immediately following the release of 12.0.0). 1164 1165### Release branch 1166 1167Approximately two months before a major release, new `vN.x` and 1168`vN.x-staging` branches (where `N` indicates the major release) should be 1169created as forks of the `main` branch. Up until the cut-off date announced by 1170the releaser, these must be kept in sync with `main`. 1171 1172The `vN.x` and `vN.x-staging` branches must be kept in sync with one another 1173up until the date of the release. 1174 1175The TSC should be informed of any `SEMVER-MAJOR` commits that land within one 1176month of the release. 1177 1178### Create release labels 1179 1180The following issue labels must be created: 1181 1182* `vN.x` 1183* `backport-blocked-vN.x` 1184* `backport-open-vN.x` 1185* `backport-requested-vN.x` 1186* `backported-to-vN.x` 1187* `dont-land-on-vN.x` 1188 1189The label description can be copied from existing labels of previous releases. 1190The label color must be the same for all new labels, but different from the 1191labels of previous releases. 1192 1193### Release proposal 1194 1195A draft release proposal should be created 6 weeks before the release. A 1196separate `vN.x-proposal` branch should be created that tracks the `vN.x` 1197branch. This branch will contain the draft release commit (with the draft 1198changelog). 1199 1200Notify the `@nodejs/npm` team in the release proposal PR to inform them of the 1201upcoming release. `npm` maintains a list of [supported versions](https://github.com/npm/cli/blob/latest/lib/utils/unsupported.js#L3) 1202that will need updating to include the new major release. 1203 1204### Update `NODE_MODULE_VERSION` 1205 1206This macro in `src/node_version.h` is used to signal an ABI version for native 1207addons. It currently has two common uses in the community: 1208 1209* Determining what API to work against for compiling native addons, e.g. 1210 [NAN](https://github.com/nodejs/nan) uses it to form a compatibility-layer for 1211 much of what it wraps. 1212* Determining the ABI for downloading pre-built binaries of native addons, e.g. 1213 [node-pre-gyp](https://github.com/mapbox/node-pre-gyp) uses this value as 1214 exposed via `process.versions.modules` to help determine the appropriate 1215 binary to download at install-time. 1216 1217The general rule is to bump this version when there are _breaking ABI_ changes 1218and also if there are non-trivial API changes. The rules are not yet strictly 1219defined, so if in doubt, please confer with someone that will have a more 1220informed perspective, such as a member of the NAN team. 1221 1222A registry of currently used `NODE_MODULE_VERSION` values is maintained at 1223<https://github.com/nodejs/node/blob/HEAD/doc/abi_version_registry.json>. 1224When bumping `NODE_MODULE_VERSION`, you should choose a new value not listed 1225in the registry. Also include a change to the registry in your commit to 1226reflect the newly used value. Ensure that the release commit removes the 1227`-pre` suffix for the major version being prepared. 1228 1229It is current TSC policy to bump major version when ABI changes. If you 1230see a need to bump `NODE_MODULE_VERSION` outside of a major release then 1231you should consult the TSC. Commits may need to be reverted or a major 1232version bump may need to happen. 1233 1234### Test releases and release candidates 1235 1236Test builds should be generated from the `vN.x-proposal` branch starting at 1237about 6 weeks before the release. 1238 1239Release Candidates should be generated from the `vN.x-proposal` branch starting 1240at about 4 weeks before the release, with a target of one release candidate 1241per week. 1242 1243Always run test releases and release candidates through the Canary in the 1244Goldmine tool for additional testing. 1245 1246### Changelogs 1247 1248Generating major release changelogs is a bit more involved than minor and patch 1249changelogs. 1250 1251#### Create the changelog file 1252 1253In the `doc/changelogs` directory, create a new `CHANGELOG_V{N}.md` file where 1254`{N}` is the major version of the release. Follow the structure of the existing 1255`CHANGELOG_V*.md` files. 1256 1257The navigation headers in all of the `CHANGELOG_V*.md` files must be 1258updated to account for the new `CHANGELOG_V{N}.md` file. 1259 1260Once the file is created, the root `CHANGELOG.md` file must be updated to 1261reference the newly-created major release `CHANGELOG_V{N}.md`. 1262 1263#### Generate the changelog 1264 1265To generate a proper major release changelog, use the `branch-diff` tool to 1266compare the `vN.x` branch against the `vN-1.x` branch (e.g. for Node.js 12.0, 1267we compare the `v12.x` branch against the up to date `v11.x` branch). Make sure 1268that the local copy of the downlevel branch is up to date. 1269 1270The commits in the generated changelog must then be organized: 1271 1272* Remove all release commits from the list 1273* Remove all reverted commits and their reverts 1274* Separate all SEMVER-MAJOR, SEMVER-MINOR, and SEMVER-PATCH commits into lists 1275 1276#### Generate the notable changes 1277 1278For a major release, all SEMVER-MAJOR commits that are not strictly internal, 1279test, or doc-related are to be listed as notable changes. Some SEMVER-MINOR 1280commits may be listed as notable changes on a case-by-case basis. Use your 1281judgment there. 1282 1283### Update the expected assets 1284 1285The promotion script does a basic check that the expected files are present. 1286Open a pull request in the Build repository to add the list of expected files 1287for the new release line as a new file, `v{N}.x` (where `{N}` is the major 1288version of the release), in the [expected assets][] folder. The change will 1289need to be deployed onto the web server by a member of the [build-infra team][] 1290before the release is promoted. 1291 1292### Snap 1293 1294The Node.js [Snap][] package has a "default" for installs where the user hasn't 1295specified a release line ("track" in Snap terminology). This should be updated 1296to point to the most recently activated LTS. A member of the Node.js Build 1297Infrastructure team is able to perform the switch of the default. An issue 1298should be opened on the [Node.js Snap management repository][] requesting this 1299take place once a new LTS line has been released. 1300 1301[Build issue tracker]: https://github.com/nodejs/build/issues/new 1302[CI lockdown procedure]: https://github.com/nodejs/build/blob/HEAD/doc/jenkins-guide.md#restricting-access-for-security-releases 1303[Node.js Snap management repository]: https://github.com/nodejs/snap 1304[Partner Communities]: https://github.com/nodejs/community-committee/blob/HEAD/governance/PARTNER_COMMUNITIES.md 1305[Snap]: https://snapcraft.io/node 1306[build-infra team]: https://github.com/orgs/nodejs/teams/build-infra 1307[expected assets]: https://github.com/nodejs/build/tree/HEAD/ansible/www-standalone/tools/promote/expected_assets 1308[nodejs.org release-post.js script]: https://github.com/nodejs/nodejs.org/blob/HEAD/scripts/release-post/index.mjs 1309[nodejs.org repository]: https://github.com/nodejs/nodejs.org 1310