Browse Source

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.
Jeremy Apthorp 6 years ago
parent
commit
b8a8bf82ac
1 changed files with 67 additions and 64 deletions
  1. 67 64
      docs/development/upgrading-node.md

+ 67 - 64
docs/development/upgrading-node.md

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