Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/major-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Major Release

on:
schedule:
- cron: 0 0 15 2,8 * # runs at midnight UTC every 15 February and 15 August
- cron: 0 0 15 2 * # runs at midnight UTC every 15 February

permissions:
contents: read
Expand Down
139 changes: 77 additions & 62 deletions doc/contributing/releases.md
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,11 @@ already defined in `src/node_version.h`:
#define NODE_MAJOR_VERSION x
#define NODE_MINOR_VERSION y
#define NODE_PATCH_VERSION z

// And for alpha releases:
#define NODE_ALPHA_MAJOR_VERSION a
#define NODE_ALPHA_MINOR_VERSION b
#define NODE_ALPHA_PATCH_VERSION c
```

Set the `NODE_VERSION_IS_RELEASE` macro value to `1`. This causes the build to
Expand All @@ -431,6 +436,14 @@ be produced with a version string that does not have a trailing pre-release tag:
#define NODE_VERSION_IS_RELEASE 1
```

<details>
<summary>Major version release</summary>

Remove the `NODE_ALPHA_MAJOR_VERSION`, `NODE_ALPHA_MINOR_VERSION`, and
`NODE_ALPHA_PATCH_VERSION` macros.

</details>

### 4. Update the changelog

_(This step will be done automatically if you are using `create-release-proposal` or `git node release --prepare`)_
Expand Down Expand Up @@ -900,8 +913,8 @@ project README.

On release proposal branch, edit `src/node_version.h` again and:

* Increment `NODE_PATCH_VERSION` by one
* Change `NODE_VERSION_IS_RELEASE` back to `0`
* Increment `NODE_PATCH_VERSION` (or `NODE_ALPHA_PATCH_VERSION` for alpha releases) by one.
* Change `NODE_VERSION_IS_RELEASE` back to `0`.

Commit this change with the following commit message format:

Expand Down Expand Up @@ -968,9 +981,12 @@ git restore --source=upstream/main src/node_version.h
On the main branch, instead of reverting changes made to `src/node_version.h`
edit it instead and:

* Increment `NODE_MAJOR_VERSION` by one
* Reset `NODE_PATCH_VERSION` to `0`
* Change `NODE_VERSION_IS_RELEASE` back to `0`
* Increment `NODE_MAJOR_VERSION` by one.
* Reset `NODE_PATCH_VERSION` and `NODE_MINOR_VERSION` to `0`.
* Set `NODE_ALPHA_MAJOR_VERSION`, `NODE_ALPHA_MINOR_VERSION`, and
`NODE_ALPHA_PATCH_VERSION` back to `0` (`main` should already have this, the
release commit will have them removed).
* Change `NODE_VERSION_IS_RELEASE` back to `0`.

Amend the current commit to apply the changes:

Expand Down Expand Up @@ -1281,9 +1297,9 @@ git node release --prepare --startLTS
To mark a release line as LTS, the following changes must be made to
`src/node_version.h`:

* The `NODE_MINOR_VERSION` macro must be incremented by one
* The `NODE_PATCH_VERSION` macro must be set to `0`
* The `NODE_VERSION_IS_LTS` macro must be set to `1`
* The `NODE_MINOR_VERSION` macro must be incremented by one.
* The `NODE_PATCH_VERSION` macro must be set to `0`.
* The `NODE_VERSION_IS_LTS` macro must be set to `1`.
* The `NODE_VERSION_LTS_CODENAME` macro must be set to the code name selected
for the LTS release.

Expand Down Expand Up @@ -1352,15 +1368,15 @@ from cutting a minor or patch release.

### Schedule

New Node.js Major releases happen twice per year:
New Node.js Major releases happen once per year:

* Even-numbered releases are cut in April.
* Odd-numbered releases are cut in October.
* Branch-off is in October.
* Semver-major release is in April.

Major releases should be targeted for the third Tuesday of the release month.

A major release must not slip beyond the release month. In other words, major
releases must not slip into May or November.
releases must not slip into May.

The @nodejs/releasers make a call for releasers 3 months in advance.
Currently, this call is automated in the `#nodejs-release-private`
Expand All @@ -1370,26 +1386,25 @@ The release date for the next major release should be announced immediately
following the current release (e.g. the release date for 13.0.0 should be
announced immediately following the release of 12.0.0).

### Release branch
### Branch-off (October)

Approximately two months before a major release, new `vN.x` and
`vN.x-staging` branches (where `N` indicates the major release) should be
created as forks of the `main` branch. Up until the cut-off date announced by
the releaser, these must be kept in sync with `main`.
#### Release branch

The `vN.x` and `vN.x-staging` branches must be kept in sync with one another
up until the date of the release.
Approximately six months before a major release, new `vN.x` and
`vN.x-staging` branches (where `N` indicates the major release) should be
created as forks of the `main` branch. Alpha releases should be released picking
up commits from `main`. Target the first alpha release to be released the same
day as the previous release line is graduated to LTS status.

If a `SEMVER-MAJOR` pull request lands on the default branch within one month
prior to the major release date, it must not be included on the new major
staging branch, unless there is consensus from the Node.js releasers team to
do so. This measure aims to ensure better stability for the release candidate
(RC) phase, which begins approximately two weeks prior to the official release.
By restricting `SEMVER-MAJOR` commits in this period, we provide more time for
thorough testing and reduce the potential for major breakages, especially in
LTS lines.
thorough testing and reduce the potential for major breakages.

### Create release labels
#### Create release labels

The following issue labels must be created:

Expand All @@ -1404,31 +1419,17 @@ The label description can be copied from existing labels of previous releases.
The label color must be the same for all new labels, but different from the
labels of previous releases.

### Release proposal
#### Initial Alpha release proposal

A draft release proposal should be created 6 weeks before the release. A
A draft release proposal should be created before the release. A
separate `vN.x-proposal` branch should be created that tracks the `vN.x`
branch. This branch will contain the draft release commit (with the draft
changelog).

Notify the `@nodejs/npm` team in the release proposal PR to inform them of the
upcoming release.

To keep the branch in sync until the release date, it can be as simple as
doing the following:

> Make sure to check that there are no PRs with the label `dont-land-on-vX.x`.

```bash
git checkout vN.x
git reset --hard upstream/main
git checkout vN.x-staging
git reset --hard upstream/main
git push upstream vN.x
git push upstream vN.x-staging
```

### Update `NODE_MODULE_VERSION`
##### Update `NODE_MODULE_VERSION`

This macro in `src/node_version.h` is used to signal an ABI version for native
addons. It currently has two common uses in the community:
Expand Down Expand Up @@ -1458,24 +1459,12 @@ see a need to bump `NODE_MODULE_VERSION` outside of a major release then
you should consult the TSC. Commits may need to be reverted or a major
version bump may need to happen.

### Test releases and release candidates

Test builds should be generated from the `vN.x-proposal` branch starting at
about 6 weeks before the release.

Release Candidates should be generated from the `vN.x-proposal` branch starting
at about 4 weeks before the release, with a target of one release candidate
per week.

Always run test releases and release candidates through the Canary in the
Goldmine tool for additional testing.

### Changelogs
##### Changelogs

Generating major release changelogs is a bit more involved than minor and patch
changelogs.

#### Create the changelog file
###### Create the changelog file

In the `doc/changelogs` directory, create a new `CHANGELOG_V{N}.md` file where
`{N}` is the major version of the release. Follow the structure of the existing
Expand All @@ -1487,7 +1476,7 @@ updated to account for the new `CHANGELOG_V{N}.md` file.
Once the file is created, the root `CHANGELOG.md` file must be updated to
reference the newly-created major release `CHANGELOG_V{N}.md`.

#### Generate the changelog
###### Generate the changelog

To generate a proper major release changelog, use the `branch-diff` tool to
compare the `vN.x` branch against the `vN-1.x` branch (e.g. for Node.js 12.0,
Expand All @@ -1506,14 +1495,7 @@ $ branch-diff upstream/vN-1.x upstream/vN.x --require-label=semver-minor --group
$ branch-diff upstream/vN-1.x upstream/vN.x --exclude-label=semver-major,semver-minor --group --filter-release --markdown # get all patches
```

#### Generate the notable changes

For a major release, all SEMVER-MAJOR commits that are not strictly internal,
test, or doc-related are to be listed as notable changes. Some SEMVER-MINOR
commits may be listed as notable changes on a case-by-case basis. Use your
judgment there.

### Update the expected assets
##### Update the expected assets

The promotion script does a basic check that the expected files are present.
Open a pull request in the Build repository to add the list of expected files
Expand All @@ -1522,6 +1504,39 @@ version of the release), in the [expected assets][] folder. The change will
need to be deployed onto the web server by a member of the [build-infra team][]
before the release is promoted.

### Semver-major release (April)

#### Release proposal

A draft release proposal should be created 6 weeks before the release. A
separate `vN.x-proposal` branch should be created that tracks the `vN.x`
branch. This branch will contain the draft release commit (with the draft
changelog).

Notify the `@nodejs/npm` team in the release proposal PR to inform them of the
upcoming release.

Major release proposal should contain a single commit, the release one. All
semver-major changes must have landed in a alpha version before the major is
released. Semver-major changes that have missed the alpha period will be included
in the next major release line.

##### Marking a release line as "out of Alpha"

To mark a release line as stable, the following changes must be made to
`src/node_version.h`:

* Remove `NODE_ALPHA_MAJOR_VERSION`, `NODE_ALPHA_MINOR_VERSION`, and
`NODE_ALPHA_PATCH_VERSION`.

#### Generate the notable changes

For a major release, all SEMVER-MAJOR commits that are not strictly internal,
test, or doc-related are to be listed as notable changes. Some SEMVER-MINOR
commits may be listed as notable changes on a case-by-case basis. Use your
judgment there.
Include the notable changes from the Alpha versions where it applies.

### Snap

The Node.js [Snap][] package has a "default" for installs where the user hasn't
Expand Down
11 changes: 11 additions & 0 deletions lib/internal/ffi/fast-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const {
getRawPointer,
kFastArguments,
kFastBufferInvoke,
uintptrMax,
} = internalBinding('ffi');

const {
Expand Down Expand Up @@ -110,6 +111,14 @@ function needsPointerConversion(type) {
needsNullPointerConversion(type) || needsStringPointerConversion(type);
}

function validateFastPointerArg(type, value, index) {
if (needsPointerConversion(type) && typeof value === 'bigint' &&
(value < 0n || value > uintptrMax)) {
throwFFIArgError(
`Argument ${index} must be a non-negative pointer bigint`);
}
}

function hasStringPointerArg(type, value) {
return typeof value === 'string' && needsStringPointerConversion(type);
}
Expand Down Expand Up @@ -159,6 +168,7 @@ function getStringConversionPointer(state, value, index) {
}

function convertPointerArg(type, value, stringState, index) {
validateFastPointerArg(type, value, index);
if (needsNullPointerConversion(type) &&
(value === null || value === undefined)) {
return 0n;
Expand Down Expand Up @@ -261,6 +271,7 @@ function wrapWithRawPointerConversions(rawFn, argumentTypes, owner) {
throwFFIArgCountError(1, arguments.length);
}
validateFastIntegerArg(t0, a0, 0);
validateFastPointerArg(t0, a0, 0);
let arg = a0;
if (needsNullPointerConversion(t0) &&
(arg === null || arg === undefined)) {
Expand Down
10 changes: 10 additions & 0 deletions src/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,16 @@ NODE_EXTERN void SetProcessExitHandler(
std::function<void(Environment*, int)>&& handler);
NODE_EXTERN void DefaultProcessExitHandler(Environment* env, int exit_code);

// Sets a process-global handler invoked when Node.js programmatically aborts.
// Nullable strings representing the location and reason for the abort may or
// may not be passed as a parameter to the handler. The handler should not
// return, but node will ensure that the process exits after the handler is
// called regardless of whether or not it returns. Passing nullptr restores the
// default handler. This is process-global and may be invoked before any Isolate
// or Environment exists.
using AbortHandler = void (*)(const char* location, const char* message);
NODE_EXTERN void SetAbortHandler(AbortHandler handler);

// This may return nullptr if context is not associated with a Node instance.
NODE_EXTERN Environment* GetCurrentEnvironment(v8::Local<v8::Context> context);
NODE_EXTERN IsolateData* GetEnvironmentIsolateData(Environment* env);
Expand Down
30 changes: 27 additions & 3 deletions src/node_errors.cc
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,30 @@ void AppendExceptionLine(Environment* env,
.FromMaybe(false));
}

namespace {
// Default handler: Dumps native + JS backtraces to stderr and exits. This
// indirectly calls backtrace so it can not be marked as [[noreturn]] (see the
// comment on node::Assert() below). `message` and `location` are ignored
// because the assertion/fatal-error message, if any, is already printed to
// stderr by the caller (Assert()/OnFatalError()) before this handler runs.
void DefaultAbortHandler(const char* /*location*/, const char* /*message*/) {
DumpNativeBacktrace(stderr);
DumpJavaScriptBacktrace(stderr);
fflush(stderr);
ABORT_NO_BACKTRACE();
}
// Constant-initialized, so this is valid from load time, safe even for a
// CHECK() during early startup, before any SetAbortHandler call.
AbortHandler g_abort_handler = DefaultAbortHandler;
} // namespace

void SetAbortHandler(AbortHandler handler) {
g_abort_handler = handler ? handler : DefaultAbortHandler;
}
AbortHandler GetAbortHandler() {
return g_abort_handler;
}

void Assert(const AssertionInfo& info) {
std::string name = GetHumanReadableProcessName();

Expand All @@ -406,7 +430,7 @@ void Assert(const AssertionInfo& info) {
info.message);

fflush(stderr);
ABORT();
ABORT_WITH_DETAILS(info.file_line, info.message);
}

enum class EnhanceFatalException { kEnhance, kDontEnhance };
Expand Down Expand Up @@ -584,7 +608,7 @@ static void ReportFatalException(Environment* env,
}

fflush(stderr);
ABORT();
ABORT_WITH_DETAILS(location, message);
}

void OOMErrorHandler(const char* location, const v8::OOMDetails& details) {
Expand Down Expand Up @@ -620,7 +644,7 @@ void OOMErrorHandler(const char* location, const v8::OOMDetails& details) {
}

fflush(stderr);
ABORT();
ABORT_WITH_DETAILS(location, message);
}

v8::ModifyCodeGenerationFromStringsResult ModifyCodeGenerationFromStrings(
Expand Down
6 changes: 3 additions & 3 deletions src/node_ffi.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1341,9 +1341,9 @@ static void Initialize(Local<Object> target,
Boolean::New(isolate, CHAR_MIN < 0))
.Check();

// The shared-buffer fast path uses `uintptrMax` to reject pointer BigInts
// that would otherwise be silently truncated by `ReadFFIArgFromBuffer`'s
// `memcpy(..., type->size, ...)` on 32-bit platforms. The slow path
// The JavaScript fast paths use `uintptrMax` to reject pointer BigInts that
// would otherwise be silently truncated by V8 or, on 32-bit platforms, by
// `ReadFFIArgFromBuffer`'s `memcpy(..., type->size, ...)`. The slow path
// rejects the same values through `ToFFIArgument`.
target
->Set(context,
Expand Down
Loading
Loading