docs: update "upgrading node" guide (#14649)

I think there's more to do here, and I'll continue to add to & update this documentation as I go through the process of upgrading node in the context of the GN build.
This commit is contained in:
Jeremy Apthorp 2018-09-19 11:08:39 -07:00 committed by GitHub
parent 0e91db2188
commit b8a8bf82ac
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -2,14 +2,15 @@
## Discussion ## Discussion
One upgrade issue is building all of Electron with a single copy Chromium and Node.js both depend on V8, and Electron contains
of V8 to ensure compatibility. This is important because only a single copy of V8, so it's important to ensure that the
upstream Node and [libchromiumcontent](upgrading-chromium.md) version of V8 chosen is compatible with the build's version of
both use their own versions of V8. Node.js and Chromium.
Upgrading Node is much easier than upgrading libchromiumcontent, Upgrading Node is much easier than upgrading Chromium, so fewer
so fewer conflicts arise if one upgrades libchromiumcontent first, conflicts arise if one upgrades Chromium first, then chooses the
then chooses the upstream Node release whose V8 is closest to it. upstream Node release whose version of V8 is closest to the one
Chromium contains.
Electron has its own [Node fork](https://github.com/electron/node) Electron has its own [Node fork](https://github.com/electron/node)
with modifications for the V8 build details mentioned above with modifications for the V8 build details mentioned above
@ -32,16 +33,15 @@ So in short, the primary steps are:
1. Update Electron's Node fork to the desired version 1. Update Electron's Node fork to the desired version
2. Backport Node's V8 patches to our copy of V8 2. Backport Node's V8 patches to our copy of V8
3. Update Electron to use new version of Node 3. Update the GN build files, porting changes from node's GYP files
* Update submodules 4. Update Electron's DEPS to use new version of Node
* Update Node.js build configuration
## Updating Electron's Node [fork](https://github.com/electron/node) ## Updating Electron's Node [fork](https://github.com/electron/node)
1. Ensure that `master` on `electron/node` has updated release tags from `nodejs/node` 1. Ensure that `master` on `electron/node` has updated release tags from `nodejs/node`
2. Create a branch in https://github.com/electron/node: `electron-node-vX.X.X` where the base that you're branching from is the tag for the desired update 2. Create a branch in https://github.com/electron/node: `electron-node-vX.X.X` where the base that you're branching from is the tag for the desired update
- `vX.X.X` Must use a version of node compatible with our current version of chromium - `vX.X.X` Must use a version of Node compatible with our current version of Chromium
3. Re-apply our commits from the previous version of node we were using (`vY.Y.Y`) to `v.X.X.X` 3. Re-apply our commits from the previous version of Node we were using (`vY.Y.Y`) to `v.X.X.X`
- Check release tag and select the range of commits we need to re-apply - Check release tag and select the range of commits we need to re-apply
- Cherry-pick commit range: - Cherry-pick commit range:
1. Checkout both `vY.Y.Y` & `v.X.X.X` 1. Checkout both `vY.Y.Y` & `v.X.X.X`
@ -54,65 +54,68 @@ So in short, the primary steps are:
## Updating [V8](https://github.com/electron/node/src/V8) Patches ## Updating [V8](https://github.com/electron/node/src/V8) Patches
We need to generate a patch file from each patch applied to V8. We need to generate a patch file from each patch that Node
applies to V8.
1. Get a copy of Electron's libcc fork ```sh
- `$ git clone https://github.com/electron/libchromiumcontent` $ cd third_party/electron_node
2. Run `script/update` to get the latest libcc $ CURRENT_NODE_VERSION=vX.Y.Z
- This will be time-consuming # Find the last commit with the message "deps: update V8 to <some version>"
3. Remove our copies of the old Node v8 patches # This commit corresponds to Node resetting V8 to its pristine upstream
- (In libchromiumcontent repo) Read `patches/common/v8/README.md` to see which patchfiles # state at the stated version.
were created during the last update $ LAST_V8_UPDATE="$(git log --grep='^deps: update V8' --format='%H' -1 deps/v8)"
- Remove those files from `patches/common/v8/`: # This creates a patch file containing all changes in deps/v8 from
- `git rm` the patchfiles # $LAST_V8_UPDATE up to the current Node version, formatted in a way that
- edit `patches/common/v8/README.md` # it will apply cleanly to the V8 repository (i.e. with `deps/v8`
- commit these removals # stripped off the path and excluding the v8/gypfiles directory, which
4. Inspect Node [repo](https://github.com/electron/node) to see what patches upstream Node # isn't present in V8.
used with their v8 after bumping its version $ git format-patch \
- `git log --oneline "deps/v8"` --relative=deps/v8 \
5. Create a checklist of the patches. This is useful for tracking your work and for $LAST_V8_UPDATE..$CURRENT_NODE_VERSION \
having a quick reference of commit hashes to use in the `git diff-tree` step below. deps/v8 \
6. Read `patches/common/v8/README.md` to see which patchfiles came from the previous version of V8 and therefore need to be removed. ':(exclude)deps/v8/gypfiles' \
- Delete each patchfile referenced in `patches/common/v8/README.md` --stdout \
7. Apply all patches with the [`get-patch` script](https://github.com/electron/libchromiumcontent/blob/master/script/README.md#get-patch): > ../../electron/common/patches/v8/node_v8_patches.patch
- `./script/get-patch --repo src/v8 --output-dir patches/v8 --commit abc123 def456 ...` ```
8. Update `patches/common/v8/README.md` with references to all new patches that have been added so that the next person will know which need to be removed.
9. Update Electron's submodule references: This list of patches will probably include one that claims to
```sh make the V8 API backwards-compatible with a previous version of
$ cd electron/vendor/node V8. Unfortunately, those patches almost always change the V8 API
electron/vendor/node$ git fetch in a way that is incompatible with Chromium.
electron/vendor/node$ git checkout electron-node-vA.B.C
electron/vendor/node$ cd ../libchromiumcontent It's usually easier to update Node to work without the
electron/vendor/libchromiumcontent$ git fetch compatibility patch than to update Chromium to work with the
electron/vendor/libchromiumcontent$ git checkout upgrade-to-chromium-X compatibility patch, so it's recommended to revert the
electron/vendor/libchromiumcontent$ cd ../.. compatibility patch and fix any errors that arise when compiling
electron$ git add vendor Node.
electron$ git commit -m "update submodule references for node and libcc"
electron$ git push origin upgrade-to-chromium-<VERSION> ## Update Electron's `DEPS` file
electron$ script/bootstrap.py -d
electron$ script/build.py -c -D Update the `DEPS` file in the root of
``` [electron/electron](https://github.com/electron/electron) to
point to the git hash of the updated Node.
## Notes ## Notes
- libcc and V8 are treated as a single unit
- Node maintains its own fork of V8 - Node maintains its own fork of V8
- They backport a small amount of things as needed - They backport a small amount of things as needed
- Documentation in node about how [they work with V8](https://nodejs.org/api/v8.html) - Documentation in Node about how [they work with V8](https://nodejs.org/api/v8.html)
- We update code such that we only use one copy of V8 across all of electron - We update code such that we only use one copy of V8 across all of Electron
- E.g electron, libcc, and node - E.g Electron, Chromium, and Node.js
- We dont track upstream closely due to logistics: - We dont track upstream closely due to logistics:
- Upstream uses multiple repos and so merging into a single repo - Upstream uses multiple repos and so merging into a single repo
would result in lost history. So we only update when were planning would result in lost history. So we only update when were planning
a node version bump in electron. a Node version bump in Electron.
- libcc is large and time-consuming to update, so we typically - Chromium is large and time-consuming to update, so we typically
choose the node version based on which of its releases has a version choose the Node version based on which of its releases has a version
of V8 thats closest to the version in libcc that were using. of V8 thats closest to the version in Chromium that were using.
- We sometimes have to wait for the next periodic Node release - We sometimes have to wait for the next periodic Node release
because it will sync more closely with the version of V8 in the new libcc because it will sync more closely with the version of V8 in the new Chromium
- Electron keeps all its patches in libcc because its simpler than - Electron keeps all its patches in the repo because its simpler than
maintaining different repos for patches for each upstream project. maintaining different repos for patches for each upstream project.
- Crashpad, node, libcc, etc. patches are all kept in the same place - Crashpad, Node.js, Chromium, Skia etc. patches are all kept in the same place
- Building node: - Building Node:
- Theres a chance we need to change our build configuration - We maintain our own GN build files for Node.js to make it easier to ensure
to match the build flags that node wants in `node/common.gypi` that eevrything is built with the same compiler flags.
This means that every time we upgrade Node.js we have to do a modest amount of
work to synchronize the GN files with the upstream GYP files.