diff --git a/doc/contributing/releases.md b/doc/contributing/releases.md index 1f33d8f2771732..cb47959cabd5c4 100644 --- a/doc/contributing/releases.md +++ b/doc/contributing/releases.md @@ -39,24 +39,40 @@ official release builds for Node.js, hosted on . ## Who can make a release? -Release authorization is given by the Node.js TSC. Once authorized, an -individual must have the following: +Individuals who are Members of the +[backporters team](https://github.com/orgs/nodejs/teams/backporters) can +land things on the staging branches and prepare releases. This is a +prerequisite to being able to prepare releases which is the first step +to becoming a releaser. + +Release authorization is given by the Node.js TSC. This is required to +promote a release after it has been prepared. If you are working on +preparing a release for the first time you can do that and have someone else +who is already onboarded promote the release on your behalf. Once +authorized by the TSC, an individual will be require the following: ### 1. Jenkins release access -There are three relevant Jenkins jobs that should be used for a release flow: +There are four relevant Jenkins jobs that should be used for a release flow: **a.** **Test runs:** **[node-test-pull-request](https://ci.nodejs.org/job/node-test-pull-request/)** is used for a final full-test run to ensure that the current _HEAD_ is stable. -**b.** **Nightly builds:** (optional) +**b.** **CitGM:** +**[citgm-smoker](https://ci.nodejs.org/job/citgm-smoker/)** is used to run +the CitGM tool which tests a build of Node.js against a defined set of +community modules. This is used during a release process to ensure that +none of the commonly used modules which are tested by CitGM show functional +regressions with the new Node.js version which could impact users. + +**c.** **Nightly builds:** (optional) **[iojs+release](https://ci-release.nodejs.org/job/iojs+release/)** can be used to create a nightly release for the current _HEAD_ if public test releases are required. Builds triggered with this job are published straight to and are available for public download. -**c.** **Release builds:** +**d.** **Release builds:** **[iojs+release](https://ci-release.nodejs.org/job/iojs+release/)** does all of the work to build all required release assets. Promotion of the release files is a manual step once they are ready (see below). @@ -66,8 +82,8 @@ this access to individuals authorized by the TSC. ### 2. \ access -The _dist_ user on nodejs.org controls the assets available in -. is an alias for +The _dist_ user on the `nodejs.org` host controls the assets available in +. is an alias for . The Jenkins release build workers upload their artifacts to the web server as @@ -90,6 +106,12 @@ responsible for that release. In order to be able to verify downloaded binaries, the public should be able to check that the `SHASUMS256.txt` file has been signed by someone who has been authorized to create a release. +If you do not currently have a key then you should create one with a +suitable strength with `gpg --full-generate-key`. The default options +(currently "ECC sign and encrypt" and "Curve 25519") are good choices and +consistent with the +[ssh key recommendations in the GOVERNANCE.md file](https://github.com/nodejs/Release/blob/main/GOVERNANCE.md#ssh-key-guidance). + The public keys should be fetchable from a known third-party keyserver. The OpenPGP keyserver at is recommended. Use the [submission](https://keys.openpgp.org/upload) form to submit @@ -108,11 +130,28 @@ gpg --keyserver hkps://keys.openpgp.org --recv-keys The key you use may be a child/subkey of an existing key. +If you wish to also upload your key to the commonly used Ubuntu keyservers +you can do so with + +```bash +gpg --keyserver keyserver.ubuntu.com --send-keys +``` + +and check it by switching the server name in the `--recv-keys` operation +list above to the Ubuntu keyserver. + Additionally, full GPG key fingerprints for individuals authorized to release should be listed in the Node.js GitHub README.md file. -> It is recommended to sign all commits under the Node.js repository. -> Run: `git config commit.gpgsign true` inside the `node` folder. +> All commits to branches in `nodejs/node` other than `main` and `actions/*` MUST be signed +> otherwise pushing to those branches will be rejected by GitHub. +> Run: `git config commit.gpgsign true` inside the `node` folder or use the +> `-S` flag on your git operations (The examples in this document will +> include `-S` expliticlty) + +While GitHub allows signing individual commits using an ssh key, +that is not covered here as this will not allow you to sign releases, so you +will need to set up a GPG signing key in GitHub. ## How to create a release @@ -123,7 +162,7 @@ Notes: * Version strings are listed below as _"vx.y.z"_ or _"x.y.z"_. Substitute for the release version. * Examples will use the fictional release version `1.2.3`. -* When preparing a security release, follow the security steps in the details +* When preparing a _security release_, follow the security steps in the details sections. ### 0. Pre-release steps @@ -136,13 +175,6 @@ and the release blog post is available on the project website. Build can be contacted best by opening up an issue on the [Build issue tracker][]. -When preparing a security release, contact Build at least two weekdays in -advance of the expected release. To ensure that the security patch(es) can be -properly tested, run a `node-test-pull-request` job against the `main` branch -of the `nodejs-private/node-private` repository a day or so before the -[CI lockdown procedure][] begins. This is to confirm that Jenkins can properly -access the private repository. - ### 1. Update the staging branch Checkout the staging branch locally. @@ -174,11 +206,11 @@ When landing the PR add the `Backport-PR-URL:` line to each commit. Close the backport PR with `Landed in ...`. Update the label on the original PR from `backport-requested-vN.x` to `backported-to-vN.x`. -You can add the `Backport-PR-URL` metadata by using `--backport` with -`git node land` +You can add the `Backport-PR-URL` metadata automatically when landing by +using `--backport` with `git node land`: ```bash -git node land --backport $PR-NUMBER +git node land -S --backport $PR-NUMBER ``` To determine the relevant commits, use @@ -189,16 +221,32 @@ metadata, as well as the GitHub labels such as `semver-minor` and omitted from a commit, the commit will show up because it's unsure if it's a duplicate or not. +A `branch-diff` run can use a lot of credits and users are +[limited by default to 5000 per hour](https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api?apiVersion=2026-03-10). +It is not unusual for a run of branch-diff to +use around 1000 of these. For this reason it is recommended that when you +run branch-diff you redirect the output to a file and then process it. You +can check your current usage with `gh rate_limit` if you have the GitHub CLI +installed and configured, or using the curl command from +[this link](https://docs.github.com/en/rest/rate-limit/rate-limit?apiVersion=2026-03-10) +with authentication e.g. + +```bash +curl -H "Authorization: token $YOURGITHUBTOKEN" -X GET https://api.github.com/rate_limit +``` + For a list of commits that could be landed in a minor release on v1.x: ```bash N=1 sh -c 'branch-diff v$N.x-staging upstream/main --exclude-label=semver-major,dont-land-on-v$N.x,backport-requested-v$N.x,backport-blocked-v$N.x,backport-open-v$N.x,backported-to-v$N.x --filter-release --format=simple' ``` -If the target branch is an LTS line, you should also exclude the `baking-for-lts`: +If the target branch is an LTS line, you should also exclude the +`baking-for-lts` and use a Current version released at least two weeks before the expected release date. +In this example we use 25.5.0 as the base version to prepare a release for Node.js 24: ```bash -N=1 sh -c 'branch-diff v$N.x-staging upstream/main --exclude-label=semver-major,dont-land-on-v$N.x,backport-requested-v$N.x,backport-blocked-v$N.x,backport-open-v$N.x,backported-to-v$N.x,baking-for-lts --filter-release --format=simple' +N=24 sh -c 'branch-diff v$N.x-staging v26.5.0 --exclude-label=semver-major,dont-land-on-v$N.x,backport-requested-v$N.x,backport-blocked-v$N.x,backport-open-v$N.x,backported-to-v$N.x,baking-for-lts --filter-release --format=simple' ``` Previously released commits and version bumps do not need to be @@ -216,6 +264,11 @@ Carefully review the list of commits: When you are ready to cherry-pick commits, you can automate with the following command. +Since this is slightly different from the previous branch-diff output - it +contains only the commit SHAs and in revert order - you may wish to save +this before piping it directly to `git cherry-pick` in case it does not go +cleanly. + ```bash N=1 sh -c 'branch-diff v$N.x-staging upstream/main --exclude-label=semver-major,dont-land-on-v$N.x,backport-requested-v$N.x,backport-blocked-v$N.x,backport-open-v$N.x,backported-to-v$N.x --filter-release --format=sha --reverse' | xargs git cherry-pick -S ``` @@ -351,6 +404,8 @@ This will ensure they are included in the "Notable Changes" section of the CHANG ### 3. Update `src/node_version.h` +_(This step will be done automatically if you are using `create-release-proposal` or `git node release --prepare`)_ + Set the version for the proposed release using the following macros, which are already defined in `src/node_version.h`: @@ -369,6 +424,8 @@ be produced with a version string that does not have a trailing pre-release tag: ### 4. Update the changelog +_(This step will be done automatically if you are using `create-release-proposal` or `git node release --prepare`)_ + #### Step 1: Collect the formatted list of changes Collect a formatted list of commits since the last release. Use @@ -485,13 +542,15 @@ are formatted correctly. If this release includes new APIs then it is necessary to document that they were first added in this version. The relevant commits should already include `REPLACEME` tags (see [Writing Documentation](./api-documentation.md#writing-documentation)). -Check for these tags with ```bash grep REPLACEME doc/api/*.md ``` -and substitute this node version with +The above command will check for the presence of the tags and show you which +files need to be updated. You can then perform the replacements with one of +the following commands using either `sed` or `perl`. In these examples +`$VERSION` must be prefixed with a `v`: ```bash sed -i "s/REPLACEME/$VERSION/g" doc/api/*.md @@ -509,8 +568,6 @@ or perl -pi -e "s/REPLACEME/$VERSION/g" doc/api/*.md ``` -`$VERSION` should be prefixed with a `v`. - If this release includes any new deprecations it is necessary to ensure that those are assigned a proper static deprecation code. These are listed in the docs (see `doc/api/deprecations.md`) and in the source as `DEP00XX`. The code @@ -520,6 +577,8 @@ run. ### 5. Create release commit +_(This step will be done automatically if you are using `create-release-proposal` or `git node release --prepare`)_ + The `CHANGELOG.md`, `doc/changelogs/CHANGELOG_Vx.md`, `src/node_version.h`, and `REPLACEME` changes should be the final commit that will be tagged for the release. When committing these to git, use the following message format: @@ -561,6 +620,8 @@ Otherwise, you will leak the commits before the security release. ### 6. Propose release on GitHub +_(This step will be done automatically if you are using `create-release-proposal` or `git node release --prepare`)_ + Push the release branch to `nodejs/node`, not to your own fork. This allows release branches to more easily be passed between members of the release team if necessary. @@ -612,13 +673,18 @@ purpose. Run it once with the base `vx.x` branch as a reference and with the proposal branch to check if new regressions could be introduced in the ecosystem. -Use `ncu-ci` to compare `vx.x` run (10) and proposal branch (11) +Use `ncu-ci` with the two build numbers from the `citgm-smoker` job to +compare the base `vx.x` run (10) and the new proposal branch (11). ```bash npm i -g @node-core/utils ncu-ci citgm 10 11 ``` +A number of the modules tested by CitGM are not completely +reliable so differences shown by the comparison are not immediately cause +for concern. +
Security release @@ -744,7 +810,7 @@ Once you have produced builds that you're happy with you can either run `git node release --promote`: ```bash -git node release --promote https://github.com/nodejs/node/pull/XXXX -S +git node release -S --promote https://github.com/nodejs/node/pull/XXXX ``` to automate the remaining steps until step 16 or you can perform it manually @@ -760,11 +826,10 @@ fetch the proposal from using the `--fetch-from` flag. When promoting several releases, you can pass multiple URLs: ```bash -git node release --promote \ +git node release -S --promote \ --fetch-from git@github.com:nodejs-private/node-private.git \ https://github.com/nodejs-private/node-private/pull/XXXX \ - https://github.com/nodejs-private/node-private/pull/XXXX \ - -S + https://github.com/nodejs-private/node-private/pull/XXXX ```
@@ -1494,7 +1559,6 @@ Typical resolution: sign the release again. ``` [Build issue tracker]: https://github.com/nodejs/build/issues/new -[CI lockdown procedure]: https://github.com/nodejs/build/blob/HEAD/doc/jenkins-guide.md#restricting-access-for-security-releases [Node.js Snap management repository]: https://github.com/nodejs/snap [Snap]: https://snapcraft.io/node [`create-release-post.yml`]: https://github.com/nodejs/nodejs.org/actions/workflows/create-release-post.yml