Browse Source

build: allow overriding electron version (#39974)

Cheng Zhao 1 year ago
parent
commit
e613595982
5 changed files with 82 additions and 26 deletions
  1. 20 8
      BUILD.gn
  2. 5 0
      buildflags/buildflags.gni
  3. 34 0
      script/get-git-version.py
  4. 23 15
      script/lib/get-version.js
  5. 0 3
      script/print-version.py

+ 20 - 8
BUILD.gn

@@ -104,14 +104,26 @@ branding = read_file("shell/app/BRANDING.json", "json")
 electron_project_name = branding.project_name
 electron_product_name = branding.product_name
 electron_mac_bundle_id = branding.mac_bundle_id
-electron_version = exec_script("script/print-version.py",
-                               [],
-                               "trim string",
-                               [
-                                 ".git/packed-refs",
-                                 ".git/HEAD",
-                                 "script/lib/get-version.js",
-                               ])
+
+if (override_electron_version != "") {
+  electron_version = override_electron_version
+} else {
+  # When building from source code tarball there is no git tag available and
+  # builders must explicitly pass override_electron_version in gn args.
+  # This read_file call will assert if there is no git information, without it
+  # gn will generate a malformed build configuration and ninja will get into
+  # infinite loop.
+  read_file(".git/packed-refs", "string")
+
+  # Set electron version from git tag.
+  electron_version = exec_script("script/get-git-version.py",
+                                 [],
+                                 "trim string",
+                                 [
+                                   ".git/packed-refs",
+                                   ".git/HEAD",
+                                 ])
+}
 
 if (is_mas_build) {
   assert(is_mac,

+ 5 - 0
buildflags/buildflags.gni

@@ -18,4 +18,9 @@ declare_args() {
 
   # Enable Spellchecker support
   enable_builtin_spellchecker = true
+
+  # The version of Electron.
+  # Packagers and vendor builders should set this in gn args to avoid running
+  # the script that reads git tag.
+  override_electron_version = ""
 }

+ 34 - 0
script/get-git-version.py

@@ -0,0 +1,34 @@
+#!/usr/bin/env python3
+
+import subprocess
+import os
+
+# Find the nearest tag to the current HEAD.
+# This is equivalent to our old logic of "use a value in package.json" for the
+# following reasons:
+#
+# 1. Whenever we updated the package.json we ALSO pushed a tag with the same
+#    version.
+# 2. Whenever we _reverted_ a bump all we actually did was push a commit that
+#    deleted the tag and changed the version number back.
+#
+# The only difference in the "git describe" technique is that technically a
+# commit can "change" its version number if a tag is created / removed
+# retroactively.  i.e. the first time a commit is pushed it will be 1.2.3
+# and after the tag is made rebuilding the same commit will result in it being
+# 1.2.4.
+
+try:
+  output = subprocess.check_output(
+      ['git', 'describe', '--tags', '--abbrev=0'],
+      cwd=os.path.abspath(os.path.join(os.path.dirname(__file__), '..')),
+      stderr=subprocess.PIPE,
+      universal_newlines=True)
+  version = output.strip().replace('v', '')
+  print(version)
+except Exception:
+  # When there is error we print a null version string instead of throwing an
+  # exception, this is because for linux/bsd packages and some vendor builds
+  # electron is built from a source code tarball and there is no git information
+  # there.
+  print('0.0.0-no-git-tag-found')

+ 23 - 15
script/lib/get-version.js

@@ -1,22 +1,30 @@
 const { spawnSync } = require('node:child_process');
+const fs = require('node:fs');
 const path = require('node:path');
 
+const { ELECTRON_DIR, getOutDir } = require('./utils');
+
+// Print the value of electron_version set in gn config.
 module.exports.getElectronVersion = () => {
-  // Find the nearest tag to the current HEAD
-  // This is equivilant to our old logic of "use a value in package.json" for the following reasons
-  //
-  // 1. Whenever we updated the package.json we ALSO pushed a tag with the same version
-  // 2. Whenever we _reverted_ a bump all we actually did was push a commit that deleted the tag and changed the version number back
-  //
-  // The only difference in the "git describe" technique is that technically a commit can "change" it's version
-  // number if a tag is created / removed retroactively.  i.e. the first time a commit is pushed it will be 1.2.3
-  // and after the tag is made rebuilding the same commit will result in it being 1.2.4
-  const output = spawnSync('git', ['describe', '--tags', '--abbrev=0'], {
-    cwd: path.resolve(__dirname, '..', '..')
-  });
+  // Read the override_electron_version from args.gn file.
+  try {
+    const outDir = path.resolve(ELECTRON_DIR, '..', 'out', getOutDir());
+    const content = fs.readFileSync(path.join(outDir, 'args.gn'));
+    const regex = /override_electron_version\s*=\s*["']([^"']+)["']/;
+    const match = content.toString().match(regex);
+    if (match) {
+      return match[1];
+    }
+  } catch (error) {
+    // Error may happen when trying to get version before running gn, which is a
+    // valid case and error will be ignored.
+  }
+  // Most win32 machines have python.exe but no python3.exe.
+  const python = process.platform === 'win32' ? 'python.exe' : 'python3';
+  // Get the version from git tag if it is not defined in gn args.
+  const output = spawnSync(python, [path.join(ELECTRON_DIR, 'script', 'get-git-version.py')]);
   if (output.status !== 0) {
-    console.error(output.stderr);
-    throw new Error('Failed to get current electron version');
+    throw new Error(`Failed to get git tag, script quit with ${output.status}: ${output.stdout}`);
   }
-  return output.stdout.toString().trim().replace(/^v/g, '');
+  return output.stdout.toString().trim();
 };

+ 0 - 3
script/print-version.py

@@ -1,3 +0,0 @@
-from lib.util import get_electron_version
-
-print(get_electron_version())