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
4 changes: 1 addition & 3 deletions .github/workflows/commit-queue.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,7 @@ jobs:
fast_track_prs=$(list_prs \
--label 'fast-track' \
--search "-label:blocked")
queued_prs=$(list_prs \
--search "-label:blocked")
candidates=$(printf '%s %s %s\n' "$aged_prs" "$fast_track_prs" "$queued_prs" |
candidates=$(printf '%s %s\n' "$fast_track_prs" "$aged_prs" |
jq -r -s 'reduce .[] as $pr ([]; if index($pr) then . else . + [$pr] end) | join(" ")')
echo "candidates=$candidates" >> "$GITHUB_OUTPUT"
env:
Expand Down
10 changes: 10 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ works.
* [Issues](#issues)
* [Pull Requests](#pull-requests)
* [Automation and bots](#automation-and-bots)
* [AI Use Policy and Guidelines](#ai-use-policy-and-guidelines)
* [Developer's Certificate of Origin 1.1](#developers-certificate-of-origin-11)

## [Code of Conduct](./doc/contributing/code-of-conduct.md)
Expand Down Expand Up @@ -66,6 +67,15 @@ by an automation that was not authorized by Node.js collaborators are
subject to immediate moderation enforcement on the automation and owner
without notice.

## [AI Use Policy and Guidelines](./doc/contributing/ai-guidelines.md)

Node.js requires contributors to understand and take full responsibility for
every change they propose. Pull requests containing AI-generated code the
contributor has not personally understood, tested, and verified will likely be closed
without review.

See [details on our AI use policy and guidelines](./doc/contributing/ai-guidelines.md).

## Developer's Certificate of Origin 1.1

```text
Expand Down
98 changes: 98 additions & 0 deletions doc/contributing/ai-guidelines.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# AI use policy and guidelines

* [Core principle](#core-principle)
* [When AI is used in contributions](#when-ai-is-used-in-contributions)
* [When AI is used in communications](#when-ai-is-used-in-communications)

This document aligns with the [OpenJS Foundation AI Coding Assistants Policy][].

## Core principle

Tools should never replace human judgment, regardless of whether they are
powered by AI.

Node.js requires contributors to understand and take full responsibility for
every change they propose. The answer to "Why is X an improvement?" can
never be "I'm not sure. The AI did it."

If AI tools assisted in generating a contribution, acknowledge that honestly.
Regardless of how much code is generated by AI, disclosure does not serve
as a disclaimer of responsibility.

Be aware that the mention of for-profit trademarks or commercial brands in
commit messages, which are part of the code base, can be abused for
profit-driven marketing. If the disclosure involves for-profit trademarks or
commercial brands, it's recommended to either anonymize the branding (e.g. say
`a frontier reasoning model`, `a closed-source coding agent` instead of
`<brand>`), or only mention the for-profit brand/trademark in the PR
description, but not in the commit message, unless the message would not have
made sense without mentioning the specific brand/trademark. These
recommendations only apply to for-profit tools/models, not any non-profit ones.

Pull requests that contain AI-generated code the contributor has not
personally understood, tested, and verified waste collaborator time and
will be subject to closure without additional review. Contributors who
repeatedly submit such changes, show no understanding of the project or
its processes, or are dishonest about the use of automated assistance
may be blocked from further contributions.

Pull requests must not be opened by automated tooling, unless specifically
approved in advance by the project. To request approval, either open an issue in
[nodejs/admin](https://github.com/nodejs/admin/issues), or if the automation can
be done in the form of a GitHub workflow, submit a pull request to add the
workflow and use the usual pull request review process to seek consensus.

## When AI is used in contributions

Contributors may use AI tools to assist with contributions, but such tools
never replace human judgment.

When using AI as a coding assistant:

* **Understand the codebase first.** Do not skip familiarizing yourself with
the relevant subsystem. Always verify analysis generated by tools against
the actual source code with human judgement.

* **Own every line you submit.** You are responsible for all code in your
pull request, regardless of how it was created. The submitted changes
must satisfy the project's [Developer's Certificate of Origin][] and licensing
requirements. Be prepared to explain any change in detail during review.

* **Keep the commits logical.** The [commit message guidelines][]
and [commit squashing guidelines](./pull-requests.md#commit-squashing)
must be followed regardless of what tool is used in the pull request.

* **Test thoroughly.** Existing tests should not be removed or modified
without human verification. It is crucial to verify, with human judgement,
the correctness of new tests against the intended behavior of the feature
being tested, independently of how the implementation happens to behave.

* **Do not disappear.** If you open a PR, follow it through. Respond to
feedback and iterate until the work lands or is explicitly closed. If you
can no longer pursue it, close the PR. Stalled PRs block progress.

* **Do not use AI to claim "good first issue" tasks.** These issues exist to
help new contributors learn the codebase and processes hands-on.

* **Keep the comments useful.** Verify with human judgement that the
comments are necessary and accurate. Remove comments that simply
restate what the code does. Add comments only where the logic is non-obvious.

## When AI is used in communications

Node.js values concise, precise communication that respects collaborator and
contributor time.

* **Do not paste messages generated entirely by AI** in pull requests, issues,
or the project's communication channels. Such communication may be removed in
accordance to [the Node.js moderation policy][].
* **Verify claims about the code with human judgement before using them in
communications**. Results from AI tools should only be treated as hypothesis.
Link to actual code, documentation and specifications as source of truth.
* Grammar and spell-check tools are acceptable when they improve clarity and
conciseness.

[Developer's Certificate of Origin]: ../../CONTRIBUTING.md#developers-certificate-of-origin-11
[OpenJS Foundation AI Coding Assistants Policy]: https://ai-coding-assistants-policy.openjsf.org/
[commit message guidelines]: ./pull-requests.md#commit-message-guidelines
[the Node.js moderation policy]: https://github.com/nodejs/admin/blob/main/Moderation-Policy.md
77 changes: 41 additions & 36 deletions doc/contributing/commit-queue.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,32 +20,34 @@ From a high-level, the Commit Queue works as follows:

1. Collaborators will add `commit-queue` label to pull requests they want the
queue to land. The label can be added before the pull request has completed
its wait time, or before requested CI has finished. Required approvals must
already be in place. The commit queue does not request CI on its own.
its wait time. Required approvals must already be in place, and any required
CI must have completed successfully. The commit queue does not request CI on
its own.
2. On each scheduled run, the queue builds a candidate list from open pull
requests with the `commit-queue` label and without the `blocked` label. The
workflow uses a five-minute cron, but GitHub Actions scheduled workflows are
not guaranteed to run exactly every five minutes. For each candidate, the
queue will:
requests with the `commit-queue` label and without the `blocked` label. A
candidate must also either have been created at least two days earlier or
have the `fast-track` label. Other labeled pull requests retain the label
until they become old enough or are fast-tracked. The workflow uses a
five-minute cron, but GitHub Actions scheduled workflows are not guaranteed
to run exactly every five minutes. For each candidate, the queue will:
1. In the landing job, install and configure `@node-core/utils`, then run a
metadata-only readiness check without checking out the repository
2. If the metadata check exits with a deferrable readiness code, meaning
the PR is only blocked on wait time, keep the `commit-queue` label and
skip this PR until a later queue run
3. Check if the PR also has a `request-ci` label (if it has, skip this PR
since it's pending a CI run)
4. Check whether GitHub checks are still running (if they are, skip this PR)
5. Remove the `commit-queue` label and run `git node land`
6. If it fails:
1. Add the `commit-queue-failed` label to the PR
3. Run `git node land` for ready PRs and PRs with hard or mixed readiness
failures, keeping the `commit-queue` label in place during the attempt
4. If it fails:
1. Replace the `commit-queue` label with the `commit-queue-failed` label
2. Leave a comment on the PR with the output from `git node land`
3. Abort the `git node land` session. If the abort succeeds, continue to
the next PR; otherwise, stop the queue in an unknown state
7. If it succeeds:
5. If it succeeds:
1. Push or merge the changes into nodejs/node
2. Leave a comment on the PR with `Landed in ...`
3. Close the PR
4. Go to next PR in the queue
4. Remove the `commit-queue` label
5. Go to next PR in the queue

To make the Commit Queue squash all the commits of a pull request into the
first one, add the `commit-queue-squash` label.
Expand Down Expand Up @@ -94,11 +96,11 @@ reasons:
without rebasing them first.

The workflow starts with a small candidate job that uses GitHub CLI to fetch
pull requests with the `commit-queue` label. It first fetches the same
age-based and fast-track buckets the queue used before accepting early queue
requests, then fetches the broader queue and de-duplicates the result. This
keeps not-yet-ready PRs from crowding out PRs that the previous query would
have selected if GitHub paginates or caps a query result.
open pull requests with the `commit-queue` label and without the `blocked`
label. It fetches two buckets: pull requests created at least two days earlier
and pull requests with the `fast-track` label. The job de-duplicates the
buckets before passing the candidates to the landing job. Pull requests in
neither bucket remain labeled but are not processed during that run.

If there are candidate PRs, the landing job installs and configures
`@node-core/utils` once with a personal token and a Jenkins token from
Expand All @@ -123,9 +125,10 @@ states. Unknown filter failures fail the workflow before starting the landing
script and leave PR labels unchanged so the queue can retry on a later
scheduled run. PRs passed through with exit code `40`-`49` continue through
`commit-queue.sh`. The workflow checks out the repository only when at least
one PR remains after filtering. The script still applies its existing
`request-ci` and pending-check deferrals before removing the queue label and
reporting a hard failure.
one PR remains after filtering. The script does not separately skip PRs with a
`request-ci` label or pending GitHub checks. Instead, `git node land` performs
the landing checks and the script reports any failure through the normal queue
failure path.

> The personal token needs permission for public repositories and to read
> profiles. It is used by `@node-core/utils` and by the landing job for
Expand All @@ -139,18 +142,20 @@ reporting a hard failure.
3. Every positional argument starting at this one will be a pull request ID of
a pull request with commit-queue set.

The script will iterate over the pull requests. GitHub CLI is used to check if
the PR is waiting for CI to start (`request-ci` label) or still has pending
GitHub checks. The PR is skipped if CI is pending. No other CI validation is
done here since `git node land` will fail if the last CI failed.

The script removes the `commit-queue` label, then runs `git node land`,
forwarding stdout and stderr to a file. PRs that are only blocked on wait time
should have already been filtered by the metadata check. If a hard readiness
failure appears between the metadata filter and `git node land`, the landing
job adds a `commit-queue-failed` label to the PR, leaves a comment with the
output of `git node land`, and then aborts the landing session. If the abort
fails, the queue stops instead of continuing in an unknown state.
The script iterates over the pull requests. For each PR, it uses GitHub CLI to
fetch the labels and select the multiple-commit policy, then runs
`git node land`, forwarding stdout and stderr to a file. It does not perform a
separate CI preflight; `git node land` performs the current readiness and CI
validation.

The script keeps the `commit-queue` label in place while `git node land` is
running. PRs that are only blocked on wait time should have already been
filtered by the metadata check. A hard or mixed readiness failure is passed
through so `git node land` can produce the failure output. If the landing
attempt fails for that or any other reason, the job replaces the
`commit-queue` label with `commit-queue-failed`, leaves a comment with the
output, and then aborts the landing session. If the abort fails, the queue
stops instead of continuing in an unknown state.

Fast-tracked PRs use the metadata check before checkout and the landing script.
If the fast-track request has not yet received enough collaborator thumbs-up,
Expand All @@ -164,8 +169,8 @@ If no errors happen during `git node land`, the script either pushes the direct
rebase landing to `main` or uses GitHub's squash merge API for single-commit and
fixup landings. It then leaves a `Landed in ...` comment in the PR. GitHub
closes PRs merged through the merge API automatically; for direct pushes, the
script closes the PR. Iteration continues until all PRs have done the steps
above.
script closes the PR. The script then removes the `commit-queue` label.
Iteration continues until all PRs have done the steps above.

## Reverting broken commits

Expand Down
18 changes: 2 additions & 16 deletions node.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -178,16 +178,8 @@
'src/node_worker.cc',
'src/node_zlib.cc',
'src/path.cc',
'src/permission/child_process_permission.cc',
'src/permission/openssl_store_permission.cc',
'src/permission/ffi_permission.cc',
'src/permission/fs_permission.cc',
'src/permission/inspector_permission.cc',
'src/permission/permission.cc',
'src/permission/wasi_permission.cc',
'src/permission/worker_permission.cc',
'src/permission/net_permission.cc',
'src/permission/addon_permission.cc',
'src/pipe_wrap.cc',
'src/process_wrap.cc',
'src/signal_wrap.cc',
Expand Down Expand Up @@ -315,16 +307,10 @@
'src/node_watchdog.h',
'src/node_worker.h',
'src/path.h',
'src/permission/child_process_permission.h',
'src/permission/openssl_store_permission.h',
'src/permission/ffi_permission.h',
'src/permission/boolean_permission.h',
'src/permission/fs_permission.h',
'src/permission/inspector_permission.h',
'src/permission/permission.h',
'src/permission/wasi_permission.h',
'src/permission/worker_permission.h',
'src/permission/net_permission.h',
'src/permission/addon_permission.h',
'src/permission/permission_base.h',
'src/pipe_wrap.h',
'src/req_wrap.h',
'src/req_wrap-inl.h',
Expand Down
14 changes: 14 additions & 0 deletions src/env-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -841,6 +841,13 @@ void Environment::set_process_exit_handler(
#undef VY
#undef VP

#define V(Name, label, _, __) \
inline v8::Local<v8::String> IsolateData::Name##_permission_string() const { \
return Name##_permission_string##_.Get(isolate_); \
}
PERMISSIONS(V)
#undef V

#define VM(PropertyName) V(PropertyName##_binding_template, v8::ObjectTemplate)
#define V(PropertyName, TypeName) \
inline v8::Local<TypeName> IsolateData::PropertyName() const { \
Expand Down Expand Up @@ -870,6 +877,13 @@ void Environment::set_process_exit_handler(
#undef VY
#undef VP

#define V(Name, label, _, __) \
inline v8::Local<v8::String> Environment::Name##_permission_string() const { \
return isolate_data()->Name##_permission_string(); \
}
PERMISSIONS(V)
#undef V

#define V(PropertyName, TypeName) \
inline v8::Local<TypeName> Environment::PropertyName() const { \
return isolate_data()->PropertyName(); \
Expand Down
Loading
Loading