| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 898276b commit 8b5dd35
1 file changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -4,6 +4,9 @@ | |||
| 4 | 4 | ||
| 5 | 5 | * [Issues and Pull Requests](#issues-and-pull-requests) | |
| 6 | 6 | * [Accepting Modifications](#accepting-modifications) | |
| 7 | + - [Internal vs. Public API](#internal-vs-public-api) | ||
| 8 | + - [Breaking Changes](#breaking-changes) | ||
| 9 | + - [Deprecations](#deprecations) | ||
| 7 | 10 | - [Involving the CTC](#involving-the-ctc) | |
| 8 | 11 | * [Landing Pull Requests](#landing-pull-requests) | |
| 9 | 12 | - [Technical HOWTO](#technical-howto) | |
@@ -84,6 +87,205 @@ All pull requests that modify executable code should be subjected to | |||
| 84 | 87 | continuous integration tests on the | |
| 85 | 88 | [project CI server](https://ci.nodejs.org/). | |
| 86 | 89 | ||
| 90 | + ### Internal vs. Public API | ||
| 91 | + | ||
| 92 | + Due to the nature of the JavaScript language, it can often be difficult to | ||
| 93 | + establish a clear distinction between which parts of the Node.js implementation | ||
| 94 | + represent the "public" API Node.js users should assume to be stable and which | ||
| 95 | + are considered part of the "internal" implementation detail of Node.js itself. | ||
| 96 | + A general rule of thumb has been to base the determination off what | ||
| 97 | + functionality is actually *documented* in the official Node.js API | ||
| 98 | + documentation. However, it has been repeatedly demonstrated that either the | ||
| 99 | + documentation does not completely cover implemented behavior or that Node.js | ||
| 100 | + users have come to rely heavily on undocumented aspects of the Node.js | ||
| 101 | + implementation. | ||
| 102 | + | ||
| 103 | + While there are numerous exceptions, the following general rules should be | ||
| 104 | + followed to determine which aspects of the Node.js API are considered | ||
| 105 | + "internal": | ||
| 106 | + | ||
| 107 | + - Any and all functionality exposed via `process.binding(...)` is considered to | ||
| 108 | + be internal and *not* part of the Node.js Public API. | ||
| 109 | + - Any and all functionality implemented in `lib/internal/**/*.js` that is not | ||
| 110 | + re-exported by code in `lib/*.js`, or is not documented as part of the | ||
| 111 | + Node.js Public API, is considered to be internal. | ||
| 112 | + - Any object property or method whose key is a non-exported `Symbol` is | ||
| 113 | + considered to be an internal property. | ||
| 114 | + - Any object property or method whose key begins with the underscore `_` prefix, | ||
| 115 | + and is not documented as part of the Node.js Public API, is considered to be | ||
| 116 | + an internal property. | ||
| 117 | + - Any object, property, method, argument, behavior, or event not documented in | ||
| 118 | + the Node.js documentation is considered to be internal. | ||
| 119 | + - Any native C/C++ APIs/ABIs exported by the Node.js `*.h` header files that | ||
| 120 | + are hidden behind the `NODE_WANT_INTERNALS` flag are considered to be | ||
| 121 | + internal. | ||
| 122 | + | ||
| 123 | + Exception to each of these points can be made if use or behavior of a given | ||
| 124 | + internal API can be demonstrated to be sufficiently relied upon by the Node.js | ||
| 125 | + ecosystem such that any changes would cause too much breakage. The threshhold | ||
| 126 | + for what qualifies as "too much breakage" is to be decided on a case-by-case | ||
| 127 | + basis by the CTC. | ||
| 128 | + | ||
| 129 | + If it is determined that a currently undocumented object, property, method, | ||
| 130 | + argument, or event *should* be documented, then a pull request adding the | ||
| 131 | + documentation is required in order for it to be considered part of the "public" | ||
| 132 | + API. | ||
| 133 | + | ||
| 134 | + Making a determination about whether something *should* be documented can be | ||
| 135 | + difficult and will need to be handled on a case-by-case basis. For instance, if | ||
| 136 | + one documented API cannot be used successfully without the use of a second | ||
| 137 | + *currently undocumented* API, then the second API *should* be documented. If | ||
| 138 | + using an API in a manner currently undocumented achieves a particular useful | ||
| 139 | + result, a decision will need to be made whether or not that falls within the | ||
| 140 | + supported scope of that API; and if it does, it should be documented. | ||
| 141 | + | ||
| 142 | + Breaking changes to internal elements are permitted in semver-patch or | ||
| 143 | + semver-minor commits but Collaborators should take significant care when | ||
| 144 | + making and reviewing such changes. Before landing such commits, an effort | ||
| 145 | + must be made to determine the potential impact of the change in the ecosystem | ||
| 146 | + by analyzing current use and by validating such changes through ecosystem | ||
| 147 | + testing using the [Canary in the Goldmine](https://github.com/nodejs/citgm) | ||
| 148 | + tool. If a change cannot be made without ecosystem breakage, then CTC review is | ||
| 149 | + required before landing the change as anything less than semver-major. | ||
| 150 | + | ||
| 151 | + If a determination is made that a particular internal API (for instance, an | ||
| 152 | + underscore `_` prefixed property) is sufficiently relied upon by the ecosystem | ||
| 153 | + such that any changes may break user code, then serious consideration should be | ||
| 154 | + given to providing an alternative Public API for that functionality before any | ||
| 155 | + breaking changes are made. | ||
| 156 | + | ||
| 157 | + ### Breaking Changes | ||
| 158 | + | ||
| 159 | + Backwards-incompatible changes may land on the master branch at any time after | ||
| 160 | + sufficient review by collaborators and approval of at least two CTC members. | ||
| 161 | + | ||
| 162 | + Examples of breaking changes include, but are not necessarily limited to, | ||
| 163 | + removal or redefinition of existing API arguments, changing return values | ||
| 164 | + (except when return values do not currently exist), removing or modifying existing properties on an options argument, adding or removing errors, | ||
| 165 | + changing error messages in any way, altering expected timing of an event (e.g. | ||
| 166 | + moving from sync to async responses or vice versa), and changing the | ||
| 167 | + non-internal side effects of using a particular API. | ||
| 168 | + | ||
| 169 | + With a few notable exceptions outlined below, when backwards incompatible | ||
| 170 | + changes to a *Public* API are necessary, the existing API *must* be deprecated | ||
| 171 | + *first* and the new API either introduced in parallel or added after the next | ||
| 172 | + major Node.js version following the deprecation as a replacement for the | ||
| 173 | + deprecated API. In other words, as a general rule, existing *Public* APIs | ||
| 174 | + *must not* change (in a backwards incompatible way) without a deprecation. | ||
| 175 | + | ||
| 176 | + Exception to this rule is given in the following cases: | ||
| 177 | + | ||
| 178 | + * Adding or removing errors thrown or reported by a Public API; | ||
| 179 | + * Changing error messages; | ||
| 180 | + * Altering the timing and non-internal side effects of the Public API. | ||
| 181 | + | ||
| 182 | + Such changes *must* be handled as semver-major changes but MAY be landed | ||
| 183 | + without a [Deprecation cycle](#deprecation-cycle). | ||
| 184 | + | ||
| 185 | + From time-to-time, in particularly exceptional cases, the CTC may be asked to | ||
| 186 | + consider and approve additional exceptions to this rule. | ||
| 187 | + | ||
| 188 | + Purely additive changes (e.g. adding new events to EventEmitter | ||
| 189 | + implementations, adding new arguments to a method in a way that allows | ||
| 190 | + existing code to continue working without modification, or adding new | ||
| 191 | + properties to an options argument) are handled as semver-minor changes. | ||
| 192 | + | ||
| 193 | + Note that errors thrown, along with behaviors and APIs implemented by | ||
| 194 | + dependencies of Node.js (e.g. those originating from V8) are generally not | ||
| 195 | + under the control of Node.js and therefore *are not directly subject to this | ||
| 196 | + policy*. However, care should still be taken when landing updates to | ||
| 197 | + dependencies when it is known or expected that breaking changes to error | ||
| 198 | + handling may have been made. Additional CI testing may be required. | ||
| 199 | + | ||
| 200 | + #### When breaking changes actually break things | ||
| 201 | + | ||
| 202 | + Breaking changes are difficult primarily because they change the fundamental | ||
| 203 | + assumptions a user of Node.js has when writing their code and can cause | ||
| 204 | + existing code to stop functioning as expected -- costing developers and users | ||
| 205 | + time and energy to fix. | ||
| 206 | + | ||
| 207 | + Because breaking (semver-major) changes are permitted to land in master at any | ||
| 208 | + time, it should be *understood and expected* that at least some subset of the | ||
| 209 | + user ecosystem *may* be adversely affected *in the short term* when attempting | ||
| 210 | + to build and use Node.js directly from master. This potential instability is | ||
| 211 | + precisely why Node.js offers distinct Current and LTS release streams that | ||
| 212 | + offer explicit stability guarantees. | ||
| 213 | + | ||
| 214 | + Specifically: | ||
| 215 | + | ||
| 216 | + * Breaking changes should *never* land in Current or LTS except when: | ||
| 217 | + * Resolving critical security issues. | ||
| 218 | + * Fixing a critical bug (e.g. fixing a memory leak) requires a breaking | ||
| 219 | + change. | ||
| 220 | + * There is CTC consensus that the change is required. | ||
| 221 | + * If a breaking commit does accidentally land in a Current or LTS branch, an | ||
| 222 | + attempt to fix the issue will be made before the next release; If no fix is | ||
| 223 | + provided then the commit will be reverted. | ||
| 224 | + | ||
| 225 | + When any change is landed in master, and it is determined that the such | ||
| 226 | + changes *do* break existing code, a decision may be made to revert those | ||
| 227 | + changes either temporarily or permanently. However, the decision to revert or | ||
| 228 | + not can often be based on many complex factors that are not easily codified. It | ||
| 229 | + is also possible that the breaking commit can be labeled retroactively as a | ||
| 230 | + semver-major change that will not be backported to Current or LTS branches. | ||
| 231 | + | ||
| 232 | + ### Deprecations | ||
| 233 | + | ||
| 234 | + Deprecation refers to the identification of Public APIs that should no longer | ||
| 235 | + be used and that may be removed or modified in non-backwards compatible ways in | ||
| 236 | + a future major release of Node.js. Deprecation *may* be used with internal APIs | ||
| 237 | + if there is expected impact on the user community. | ||
| 238 | + | ||
| 239 | + Node.js uses three fundamental Deprecation levels: | ||
| 240 | + | ||
| 241 | + * *Documentation-Only Deprecation* refers to elements of the Public API that are | ||
| 242 | + being staged for deprecation in a future Node.js major release. An explicit | ||
| 243 | + notice indicating the deprecated status is added to the API documentation | ||
| 244 | + *but no functional changes are implemented in the code*. There will be no | ||
| 245 | + runtime deprecation warning emitted for such deprecations. | ||
| 246 | + | ||
| 247 | + * *Runtime Deprecation* refers to the use of process warnings emitted at | ||
| 248 | + runtime the first time that a deprecated API is used. A command-line | ||
| 249 | + switch can be used to escalate such warnings into runtime errors that will | ||
| 250 | + cause the Node.js process to exit. As with Documentation-Only Deprecation, | ||
| 251 | + the documentation for the API must be updated to clearly indicate the | ||
| 252 | + deprecated status. | ||
| 253 | + | ||
| 254 | + * *End-of-life* refers to APIs that have gone through Runtime Deprecation and | ||
| 255 | + are ready to be removed from Node.js entirely. | ||
| 256 | + | ||
| 257 | + Documentation-Only Deprecations *may* be handled as semver-minor or | ||
| 258 | + semver-major changes. Such deprecations have no impact on the successful | ||
| 259 | + operation of running code and therefore should not be viewed as breaking | ||
| 260 | + changes. | ||
| 261 | + | ||
| 262 | + Runtime Deprecations and End-of-life APIs (internal or public) *must* be | ||
| 263 | + handled as semver-major changes unless there is CTC consensus to land the | ||
| 264 | + deprecation as a semver-minor. | ||
| 265 | + | ||
| 266 | + All Documentation-Only and Runtime deprecations will be assigned a unique | ||
| 267 | + identifier that can be used to persistently refer to the deprecation in | ||
| 268 | + documentation, emitted process warnings, or errors thrown. Documentation for | ||
| 269 | + these identifiers will be included in the Node.js API documentation and will | ||
| 270 | + be immutable once assigned. Even if End-of-Life code is removed from Node.js, | ||
| 271 | + the documentation for the assigned deprecation identifier must remain in the | ||
| 272 | + Node.js API documentation. | ||
| 273 | + | ||
| 274 | + <a id="deprecation-cycle"></a> | ||
| 275 | + A "Deprecation cycle" is one full Node.js major release during which an API | ||
| 276 | + has been in one of the three Deprecation levels. (Note that Documentation-Only | ||
| 277 | + Deprecations may land in a Node.js minor release but must not be upgraded to | ||
| 278 | + a Runtime Deprecation until the next major release.) | ||
| 279 | + | ||
| 280 | + No API can be moved to End-of-life without first having gone through a | ||
| 281 | + Runtime Deprecation cycle. | ||
| 282 | + | ||
| 283 | + A best effort will be made to communicate pending deprecations and associated | ||
| 284 | + mitigations with the ecosystem as soon as possible (preferably *before* the pull | ||
| 285 | + request adding the deprecation lands in master). All deprecations included in | ||
| 286 | + a Node.js release should be listed prominently in the "Notable Changes" section | ||
| 287 | + of the release notes. | ||
| 288 | + | ||
| 87 | 289 | ### Involving the CTC | |
| 88 | 290 | ||
| 89 | 291 | Collaborators may opt to elevate pull requests or issues to the CTC for | |
@@ -291,15 +493,15 @@ You can find more information [in the full LTS plan](https://github.com/nodejs/l | |||
| 291 | 493 | ||
| 292 | 494 | #### How does LTS work? | |
| 293 | 495 | ||
| 294 | - Once a stable branch enters LTS, changes in that branch are limited to bug | ||
| 496 | + Once a Current branch enters LTS, changes in that branch are limited to bug | ||
| 295 | 497 | fixes, security updates, possible npm updates, documentation updates, and | |
| 296 | 498 | certain performance improvements that can be demonstrated to not break existing | |
| 297 | 499 | applications. Semver-minor changes are only permitted if required for bug fixes | |
| 298 | 500 | and then only on a case-by-case basis with LTS WG and possibly Core Technical | |
| 299 | 501 | Committee (CTC) review. Semver-major changes are permitted only if required for | |
| 300 | 502 | security related fixes. | |
| 301 | 503 | ||
| 302 | - Once a stable branch moves into Maintenance mode, only **critical** bugs, | ||
| 504 | + Once a Current branch moves into Maintenance mode, only **critical** bugs, | ||
| 303 | 505 | **critical** security fixes, and documentation updates will be permitted. | |
| 304 | 506 | ||
| 305 | 507 | #### Landing semver-minor commits in LTS | |
| Back | FazBrowse Home | New Git URL |
0 commit comments