From 0fa35a5d67e0cb51fe93dfc3b4b16ec5db7175df Mon Sep 17 00:00:00 2001 From: Titus Fortner Date: Fri, 3 Jul 2026 11:52:46 -0500 Subject: [PATCH 1/7] [build] Resolve Chrome milestone from Chrome-for-Testing channel version --- scripts/pinned_browsers.py | 39 ++++++++++++++++--------------- scripts/update_cdp.py | 47 ++++++++++++++++++-------------------- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/scripts/pinned_browsers.py b/scripts/pinned_browsers.py index 5f87546cffb45..6bfc105ea44c6 100755 --- a/scripts/pinned_browsers.py +++ b/scripts/pinned_browsers.py @@ -20,28 +20,29 @@ def calculate_hash(url): print(f"Calculate hash for {url}", file=sys.stderr) h = hashlib.sha256() r = http.request("GET", url, preload_content=False) + if r.status != 200: + raise ValueError(f"Download unavailable (HTTP {r.status}): {url}") for b in iter(lambda: r.read(4096), b""): h.update(b) return h.hexdigest() -def get_chrome_info_for_channel(channel): - r = http.request( - "GET", - f"https://chromiumdash.appspot.com/fetch_releases?channel={channel}&num=1&platform=Mac,Linux", - ) - all_versions = json.loads(r.data) - # use the same milestone for all chrome releases, so pick the lowest - milestones = [version["milestone"] for version in all_versions if version["milestone"]] - if not milestones: - raise ValueError(f"No Chrome versions with milestones found for channel '{channel}'") - milestone = min(milestones) - r = http.request( - "GET", - "https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json", - ) - versions = json.loads(r.data)["versions"] +def latest_for_channel(channel): + """Newest Chrome-for-Testing version entry (version + downloads) for a channel. + Uses Chrome-for-Testing's channel designation, which tracks the latest milestone and is + unaffected by N-1 security respins. + """ + url = "https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions.json" + r = http.request("GET", url) + if r.status != 200: + raise ValueError(f"Fetch failed (HTTP {r.status}): {url}") + milestone = json.loads(r.data)["channels"][channel]["version"].split(".")[0] + url = "https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json" + r = http.request("GET", url) + if r.status != 200: + raise ValueError(f"Fetch failed (HTTP {r.status}): {url}") + versions = json.loads(r.data)["versions"] return sorted( filter(lambda v: v["version"].split(".")[0] == str(milestone), versions), key=lambda v: parse(v["version"]), @@ -51,6 +52,8 @@ def get_chrome_info_for_channel(channel): def chromedriver(selected_version, workspace_prefix=""): content = "" + if "chromedriver" not in selected_version["downloads"]: + raise ValueError(f"No chromedriver published for Chrome {selected_version['version']}") drivers = selected_version["downloads"]["chromedriver"] url = next((d["url"] for d in drivers if d["platform"] == "linux64"), None) @@ -551,12 +554,12 @@ def pin_browsers(): content = content + edge_and_edgedriver() # Stable Chrome - stable_chrome_info = get_chrome_info_for_channel(channel="Stable") + stable_chrome_info = latest_for_channel("Stable") content = content + chrome(stable_chrome_info, workspace_prefix="") content = content + chromedriver(stable_chrome_info, workspace_prefix="") # Beta Chrome - beta_chrome_info = get_chrome_info_for_channel(channel="Beta") + beta_chrome_info = latest_for_channel("Beta") content = content + chrome(beta_chrome_info, workspace_prefix="beta_") content = content + chromedriver(beta_chrome_info, workspace_prefix="beta_") diff --git a/scripts/update_cdp.py b/scripts/update_cdp.py index 9886651234fba..3b9b72bef5ebd 100755 --- a/scripts/update_cdp.py +++ b/scripts/update_cdp.py @@ -14,33 +14,22 @@ root_dir = Path(os.path.realpath(__file__)).parent.parent -def get_chrome_milestone(): - """Get the Chrome milestone from the channel. +def latest_for_channel(channel): + """Newest Chrome-for-Testing version entry for a channel. - This is the same method from pinned_browser. Use --chrome_channel=Beta if - using early stable release. + Uses Chrome-for-Testing's channel designation, which tracks the latest milestone and is + unaffected by N-1 security respins. """ - parser = argparse.ArgumentParser() - parser.add_argument("--chrome_channel", default="Stable", help="Set the Chrome channel") - args = parser.parse_args() - channel = args.chrome_channel - - r = http.request( - "GET", - f"https://chromiumdash.appspot.com/fetch_releases?channel={channel}&num=1&platform=Mac,Linux", - ) - all_versions = json.loads(r.data) - # use the same milestone for all Chrome releases, so pick the lowest - milestones = [version["milestone"] for version in all_versions if version["milestone"]] - if not milestones: - raise ValueError(f"No Chrome versions with milestones found for channel '{channel}'") - milestone = min(milestones) - r = http.request( - "GET", - "https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json", - ) + url = "https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions.json" + r = http.request("GET", url) + if r.status != 200: + raise ValueError(f"Fetch failed (HTTP {r.status}): {url}") + milestone = json.loads(r.data)["channels"][channel]["version"].split(".")[0] + url = "https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json" + r = http.request("GET", url) + if r.status != 200: + raise ValueError(f"Fetch failed (HTTP {r.status}): {url}") versions = json.loads(r.data)["versions"] - return sorted( filter(lambda v: v["version"].split(".")[0] == str(milestone), versions), key=lambda v: parse(v["version"]), @@ -49,6 +38,8 @@ def get_chrome_milestone(): def fetch_and_save(url, file_path): response = http.request("GET", url) + if response.status != 200: + raise ValueError(f"Fetch failed (HTTP {response.status}): {url}") with open(file_path, "wb") as file: file.write(response.data) @@ -79,6 +70,8 @@ def flatten_browser_pdl(file_path, chrome_version): for domain_file in includes: url = base_url + domain_file response = http.request("GET", url) + if response.status != 200: + raise ValueError(f"Fetch failed (HTTP {response.status}): {url}") concatenated += response.data.decode("utf-8") + "\n" # Overwrite the file with version block + concatenated domains with open(file_path, "w") as file: @@ -213,7 +206,11 @@ def update_js(chrome_milestone): if __name__ == "__main__": - chrome_milestone = get_chrome_milestone() + parser = argparse.ArgumentParser() + parser.add_argument("--chrome_channel", default="Stable", help="Set the Chrome channel (use Beta for early stable)") + args = parser.parse_args() + + chrome_milestone = latest_for_channel(args.chrome_channel) add_pdls(chrome_milestone) update_java(chrome_milestone) update_dotnet(chrome_milestone) From fab7a83107d24d36f51ccaefde71aad0818aed58 Mon Sep 17 00:00:00 2001 From: Titus Fortner Date: Fri, 3 Jul 2026 12:05:01 -0500 Subject: [PATCH 2/7] [build] Release download connection and restrict --chrome_channel to valid channels --- scripts/pinned_browsers.py | 11 +++++++---- scripts/update_cdp.py | 7 ++++++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/scripts/pinned_browsers.py b/scripts/pinned_browsers.py index 6bfc105ea44c6..d1d01e90b4d7f 100755 --- a/scripts/pinned_browsers.py +++ b/scripts/pinned_browsers.py @@ -20,10 +20,13 @@ def calculate_hash(url): print(f"Calculate hash for {url}", file=sys.stderr) h = hashlib.sha256() r = http.request("GET", url, preload_content=False) - if r.status != 200: - raise ValueError(f"Download unavailable (HTTP {r.status}): {url}") - for b in iter(lambda: r.read(4096), b""): - h.update(b) + try: + if r.status != 200: + raise ValueError(f"Download unavailable (HTTP {r.status}): {url}") + for b in iter(lambda: r.read(4096), b""): + h.update(b) + finally: + r.release_conn() return h.hexdigest() diff --git a/scripts/update_cdp.py b/scripts/update_cdp.py index 3b9b72bef5ebd..57431bdb7ef21 100755 --- a/scripts/update_cdp.py +++ b/scripts/update_cdp.py @@ -207,7 +207,12 @@ def update_js(chrome_milestone): if __name__ == "__main__": parser = argparse.ArgumentParser() - parser.add_argument("--chrome_channel", default="Stable", help="Set the Chrome channel (use Beta for early stable)") + parser.add_argument( + "--chrome_channel", + default="Stable", + choices=["Stable", "Beta", "Dev", "Canary"], + help="Set the Chrome channel (use Beta for early stable)", + ) args = parser.parse_args() chrome_milestone = latest_for_channel(args.chrome_channel) From ebd4d000d9d7887ef6f2c0a6e36860d341a82fc4 Mon Sep 17 00:00:00 2001 From: Titus Fortner Date: Fri, 3 Jul 2026 12:26:02 -0500 Subject: [PATCH 3/7] [build] Revert --chrome_channel choices constraint --- scripts/update_cdp.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/scripts/update_cdp.py b/scripts/update_cdp.py index 57431bdb7ef21..3b9b72bef5ebd 100755 --- a/scripts/update_cdp.py +++ b/scripts/update_cdp.py @@ -207,12 +207,7 @@ def update_js(chrome_milestone): if __name__ == "__main__": parser = argparse.ArgumentParser() - parser.add_argument( - "--chrome_channel", - default="Stable", - choices=["Stable", "Beta", "Dev", "Canary"], - help="Set the Chrome channel (use Beta for early stable)", - ) + parser.add_argument("--chrome_channel", default="Stable", help="Set the Chrome channel (use Beta for early stable)") args = parser.parse_args() chrome_milestone = latest_for_channel(args.chrome_channel) From 4984c250a1882d5d4346c4492ae5f5cc8df9921f Mon Sep 17 00:00:00 2001 From: Titus Fortner Date: Wed, 8 Jul 2026 09:31:59 -0500 Subject: [PATCH 4/7] [build] Remove release_conn, chromedriver guard, and metadata status checks --- scripts/pinned_browsers.py | 23 ++++++----------------- scripts/update_cdp.py | 10 ++-------- 2 files changed, 8 insertions(+), 25 deletions(-) diff --git a/scripts/pinned_browsers.py b/scripts/pinned_browsers.py index d1d01e90b4d7f..435fcc7774425 100755 --- a/scripts/pinned_browsers.py +++ b/scripts/pinned_browsers.py @@ -20,13 +20,10 @@ def calculate_hash(url): print(f"Calculate hash for {url}", file=sys.stderr) h = hashlib.sha256() r = http.request("GET", url, preload_content=False) - try: - if r.status != 200: - raise ValueError(f"Download unavailable (HTTP {r.status}): {url}") - for b in iter(lambda: r.read(4096), b""): - h.update(b) - finally: - r.release_conn() + if r.status != 200: + raise ValueError(f"Download unavailable (HTTP {r.status}): {url}") + for b in iter(lambda: r.read(4096), b""): + h.update(b) return h.hexdigest() @@ -36,15 +33,9 @@ def latest_for_channel(channel): Uses Chrome-for-Testing's channel designation, which tracks the latest milestone and is unaffected by N-1 security respins. """ - url = "https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions.json" - r = http.request("GET", url) - if r.status != 200: - raise ValueError(f"Fetch failed (HTTP {r.status}): {url}") + r = http.request("GET", "https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions.json") milestone = json.loads(r.data)["channels"][channel]["version"].split(".")[0] - url = "https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json" - r = http.request("GET", url) - if r.status != 200: - raise ValueError(f"Fetch failed (HTTP {r.status}): {url}") + r = http.request("GET", "https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json") versions = json.loads(r.data)["versions"] return sorted( filter(lambda v: v["version"].split(".")[0] == str(milestone), versions), @@ -55,8 +46,6 @@ def latest_for_channel(channel): def chromedriver(selected_version, workspace_prefix=""): content = "" - if "chromedriver" not in selected_version["downloads"]: - raise ValueError(f"No chromedriver published for Chrome {selected_version['version']}") drivers = selected_version["downloads"]["chromedriver"] url = next((d["url"] for d in drivers if d["platform"] == "linux64"), None) diff --git a/scripts/update_cdp.py b/scripts/update_cdp.py index 3b9b72bef5ebd..32430803b8893 100755 --- a/scripts/update_cdp.py +++ b/scripts/update_cdp.py @@ -20,15 +20,9 @@ def latest_for_channel(channel): Uses Chrome-for-Testing's channel designation, which tracks the latest milestone and is unaffected by N-1 security respins. """ - url = "https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions.json" - r = http.request("GET", url) - if r.status != 200: - raise ValueError(f"Fetch failed (HTTP {r.status}): {url}") + r = http.request("GET", "https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions.json") milestone = json.loads(r.data)["channels"][channel]["version"].split(".")[0] - url = "https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json" - r = http.request("GET", url) - if r.status != 200: - raise ValueError(f"Fetch failed (HTTP {r.status}): {url}") + r = http.request("GET", "https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json") versions = json.loads(r.data)["versions"] return sorted( filter(lambda v: v["version"].split(".")[0] == str(milestone), versions), From 66081a9433f8689a6f18571bd002a51885ab1777 Mon Sep 17 00:00:00 2001 From: Titus Fortner Date: Wed, 8 Jul 2026 09:48:58 -0500 Subject: [PATCH 5/7] [build] Rename version-entry variable and wrap long request lines for ruff --- scripts/pinned_browsers.py | 5 ++- scripts/update_cdp.py | 91 ++++++++++++++++++++------------------ 2 files changed, 51 insertions(+), 45 deletions(-) diff --git a/scripts/pinned_browsers.py b/scripts/pinned_browsers.py index 435fcc7774425..0b4bc942dbb73 100755 --- a/scripts/pinned_browsers.py +++ b/scripts/pinned_browsers.py @@ -35,7 +35,10 @@ def latest_for_channel(channel): """ r = http.request("GET", "https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions.json") milestone = json.loads(r.data)["channels"][channel]["version"].split(".")[0] - r = http.request("GET", "https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json") + r = http.request( + "GET", + "https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json", + ) versions = json.loads(r.data)["versions"] return sorted( filter(lambda v: v["version"].split(".")[0] == str(milestone), versions), diff --git a/scripts/update_cdp.py b/scripts/update_cdp.py index 32430803b8893..a5d8d7d9f9d40 100755 --- a/scripts/update_cdp.py +++ b/scripts/update_cdp.py @@ -22,7 +22,10 @@ def latest_for_channel(channel): """ r = http.request("GET", "https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions.json") milestone = json.loads(r.data)["channels"][channel]["version"].split(".")[0] - r = http.request("GET", "https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json") + r = http.request( + "GET", + "https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json", + ) versions = json.loads(r.data)["versions"] return sorted( filter(lambda v: v["version"].split(".")[0] == str(milestone), versions), @@ -38,16 +41,16 @@ def fetch_and_save(url, file_path): file.write(response.data) -def new_chrome(chrome_milestone): - return chrome_milestone["version"].split(".")[0] +def new_chrome(chrome_release): + return chrome_release["version"].split(".")[0] -def previous_chrome(chrome_milestone): - return str(int(new_chrome(chrome_milestone)) - 1) +def previous_chrome(chrome_release): + return str(int(new_chrome(chrome_release)) - 1) -def old_chrome(chrome_milestone): - return str(int(new_chrome(chrome_milestone)) - 3) +def old_chrome(chrome_release): + return str(int(new_chrome(chrome_release)) - 3) def flatten_browser_pdl(file_path, chrome_version): @@ -72,10 +75,10 @@ def flatten_browser_pdl(file_path, chrome_version): file.write(version_block + concatenated) -def add_pdls(chrome_milestone): - source_dir = root_dir / f"common/devtools/chromium/v{previous_chrome(chrome_milestone)}" - target_dir = root_dir / f"common/devtools/chromium/v{new_chrome(chrome_milestone)}" - old_dir = root_dir / f"common/devtools/chromium/v{old_chrome(chrome_milestone)}" +def add_pdls(chrome_release): + source_dir = root_dir / f"common/devtools/chromium/v{previous_chrome(chrome_release)}" + target_dir = root_dir / f"common/devtools/chromium/v{new_chrome(chrome_release)}" + old_dir = root_dir / f"common/devtools/chromium/v{old_chrome(chrome_release)}" if os.path.isdir(old_dir): shutil.rmtree(old_dir) @@ -86,19 +89,19 @@ def add_pdls(chrome_milestone): shutil.copytree(source_dir, target_dir, dirs_exist_ok=True) fetch_and_save( - f"https://raw.githubusercontent.com/chromium/chromium/{chrome_milestone['version']}/third_party/blink/public/devtools_protocol/browser_protocol.pdl", + f"https://raw.githubusercontent.com/chromium/chromium/{chrome_release['version']}/third_party/blink/public/devtools_protocol/browser_protocol.pdl", f"{target_dir}/browser_protocol.pdl", ) - flatten_browser_pdl(f"{target_dir}/browser_protocol.pdl", chrome_milestone["version"]) + flatten_browser_pdl(f"{target_dir}/browser_protocol.pdl", chrome_release["version"]) deps_content = http.request( "GET", - f"https://raw.githubusercontent.com/chromium/chromium/{chrome_milestone['version']}/DEPS", + f"https://raw.githubusercontent.com/chromium/chromium/{chrome_release['version']}/DEPS", ).data.decode("utf-8") v8_revision_line = next((line for line in deps_content.split("\n") if "v8_revision" in line), None) if v8_revision_line is None: - raise ValueError(f"No v8_revision found in DEPS for Chrome {chrome_milestone['version']}") + raise ValueError(f"No v8_revision found in DEPS for Chrome {chrome_release['version']}") v8_revision = v8_revision_line.split(": ")[1].strip("',") fetch_and_save( f"https://raw.githubusercontent.com/v8/v8/{v8_revision}/include/js_protocol.pdl", @@ -113,15 +116,15 @@ def add_pdls(chrome_milestone): file.truncate() -def create_new_chrome_files(src_base, chrome_milestone): +def create_new_chrome_files(src_base, chrome_release): """Create new Chrome devtools files for a language binding. Java and .NET need to copy previous version directory into new version directory. """ - source_dir = root_dir / f"{src_base}/v{previous_chrome(chrome_milestone)}" - target_dir = root_dir / f"{src_base}/v{new_chrome(chrome_milestone)}" - old_dir = root_dir / f"{src_base}/v{old_chrome(chrome_milestone)}" + source_dir = root_dir / f"{src_base}/v{previous_chrome(chrome_release)}" + target_dir = root_dir / f"{src_base}/v{new_chrome(chrome_release)}" + old_dir = root_dir / f"{src_base}/v{old_chrome(chrome_release)}" if old_dir.is_dir(): shutil.rmtree(old_dir) @@ -132,8 +135,8 @@ def create_new_chrome_files(src_base, chrome_milestone): shutil.copy(item, target_dir) for file in target_dir.iterdir(): - replace_in_file(file, previous_chrome(chrome_milestone), new_chrome(chrome_milestone)) - new_filename = file.name.replace(previous_chrome(chrome_milestone), new_chrome(chrome_milestone)) + replace_in_file(file, previous_chrome(chrome_release), new_chrome(chrome_release)) + new_filename = file.name.replace(previous_chrome(chrome_release), new_chrome(chrome_release)) file.rename(target_dir / new_filename) @@ -147,19 +150,19 @@ def replace_in_file(file_path, old_string, new_string, is_regex=False): file.truncate() -def update_java(chrome_milestone): - create_new_chrome_files("java/src/org/openqa/selenium/devtools", chrome_milestone) +def update_java(chrome_release): + create_new_chrome_files("java/src/org/openqa/selenium/devtools", chrome_release) files = [ root_dir / "java/src/org/openqa/selenium/devtools/versions.bzl", root_dir / "rake_tasks/java.rake", ] for file in files: - replace_in_file(file, old_chrome(chrome_milestone), new_chrome(chrome_milestone)) + replace_in_file(file, old_chrome(chrome_release), new_chrome(chrome_release)) -def update_dotnet(chrome_milestone): - create_new_chrome_files("dotnet/src/webdriver/DevTools", chrome_milestone) +def update_dotnet(chrome_release): + create_new_chrome_files("dotnet/src/webdriver/DevTools", chrome_release) files = [ root_dir / "dotnet/version.bzl", @@ -167,36 +170,36 @@ def update_dotnet(chrome_milestone): root_dir / "dotnet/src/webdriver/DevTools/DevToolsDomains.cs", ] for file in files: - replace_in_file(file, old_chrome(chrome_milestone), new_chrome(chrome_milestone)) + replace_in_file(file, old_chrome(chrome_release), new_chrome(chrome_release)) files = [root_dir / "dotnet/test/webdriver/Infrastructure/DriverConfigs/StableChannelChromeDriver.cs"] dir_path = root_dir / "dotnet/test/webdriver/DevTools" files.extend(str(file) for file in dir_path.glob("*") if file.is_file()) for file in files: - replace_in_file(file, previous_chrome(chrome_milestone), new_chrome(chrome_milestone)) + replace_in_file(file, previous_chrome(chrome_release), new_chrome(chrome_release)) -def update_ruby(chrome_milestone): +def update_ruby(chrome_release): file = root_dir / "rb/lib/selenium/devtools/BUILD.bazel" - replace_in_file(file, old_chrome(chrome_milestone), new_chrome(chrome_milestone)) + replace_in_file(file, old_chrome(chrome_release), new_chrome(chrome_release)) file = root_dir / "rb/lib/selenium/devtools/version.rb" replace_in_file( file, - rf"{previous_chrome(chrome_milestone)}\.[0-9]*", - f"{new_chrome(chrome_milestone)}.0", + rf"{previous_chrome(chrome_release)}\.[0-9]*", + f"{new_chrome(chrome_release)}.0", True, ) -def update_python(chrome_milestone): +def update_python(chrome_release): file = root_dir / "py/BUILD.bazel" - replace_in_file(file, old_chrome(chrome_milestone), new_chrome(chrome_milestone)) + replace_in_file(file, old_chrome(chrome_release), new_chrome(chrome_release)) -def update_js(chrome_milestone): +def update_js(chrome_release): file = root_dir / "javascript/selenium-webdriver/BUILD.bazel" - replace_in_file(file, old_chrome(chrome_milestone), new_chrome(chrome_milestone)) + replace_in_file(file, old_chrome(chrome_release), new_chrome(chrome_release)) if __name__ == "__main__": @@ -204,12 +207,12 @@ def update_js(chrome_milestone): parser.add_argument("--chrome_channel", default="Stable", help="Set the Chrome channel (use Beta for early stable)") args = parser.parse_args() - chrome_milestone = latest_for_channel(args.chrome_channel) - add_pdls(chrome_milestone) - update_java(chrome_milestone) - update_dotnet(chrome_milestone) - update_ruby(chrome_milestone) - update_python(chrome_milestone) - update_js(chrome_milestone) + chrome_release = latest_for_channel(args.chrome_channel) + add_pdls(chrome_release) + update_java(chrome_release) + update_dotnet(chrome_release) + update_ruby(chrome_release) + update_python(chrome_release) + update_js(chrome_release) - print(f"adding CDP {new_chrome(chrome_milestone)} and removing {old_chrome(chrome_milestone)}") + print(f"adding CDP {new_chrome(chrome_release)} and removing {old_chrome(chrome_release)}") From 50f4c76d31cf94a7bea553dc50b8bd1838ae9bee Mon Sep 17 00:00:00 2001 From: Titus Fortner Date: Wed, 8 Jul 2026 09:57:15 -0500 Subject: [PATCH 6/7] [build] Revert chrome_release rename, keep line wrapping --- scripts/update_cdp.py | 86 +++++++++++++++++++++---------------------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/scripts/update_cdp.py b/scripts/update_cdp.py index a5d8d7d9f9d40..eb71b18b5e447 100755 --- a/scripts/update_cdp.py +++ b/scripts/update_cdp.py @@ -41,16 +41,16 @@ def fetch_and_save(url, file_path): file.write(response.data) -def new_chrome(chrome_release): - return chrome_release["version"].split(".")[0] +def new_chrome(chrome_milestone): + return chrome_milestone["version"].split(".")[0] -def previous_chrome(chrome_release): - return str(int(new_chrome(chrome_release)) - 1) +def previous_chrome(chrome_milestone): + return str(int(new_chrome(chrome_milestone)) - 1) -def old_chrome(chrome_release): - return str(int(new_chrome(chrome_release)) - 3) +def old_chrome(chrome_milestone): + return str(int(new_chrome(chrome_milestone)) - 3) def flatten_browser_pdl(file_path, chrome_version): @@ -75,10 +75,10 @@ def flatten_browser_pdl(file_path, chrome_version): file.write(version_block + concatenated) -def add_pdls(chrome_release): - source_dir = root_dir / f"common/devtools/chromium/v{previous_chrome(chrome_release)}" - target_dir = root_dir / f"common/devtools/chromium/v{new_chrome(chrome_release)}" - old_dir = root_dir / f"common/devtools/chromium/v{old_chrome(chrome_release)}" +def add_pdls(chrome_milestone): + source_dir = root_dir / f"common/devtools/chromium/v{previous_chrome(chrome_milestone)}" + target_dir = root_dir / f"common/devtools/chromium/v{new_chrome(chrome_milestone)}" + old_dir = root_dir / f"common/devtools/chromium/v{old_chrome(chrome_milestone)}" if os.path.isdir(old_dir): shutil.rmtree(old_dir) @@ -89,19 +89,19 @@ def add_pdls(chrome_release): shutil.copytree(source_dir, target_dir, dirs_exist_ok=True) fetch_and_save( - f"https://raw.githubusercontent.com/chromium/chromium/{chrome_release['version']}/third_party/blink/public/devtools_protocol/browser_protocol.pdl", + f"https://raw.githubusercontent.com/chromium/chromium/{chrome_milestone['version']}/third_party/blink/public/devtools_protocol/browser_protocol.pdl", f"{target_dir}/browser_protocol.pdl", ) - flatten_browser_pdl(f"{target_dir}/browser_protocol.pdl", chrome_release["version"]) + flatten_browser_pdl(f"{target_dir}/browser_protocol.pdl", chrome_milestone["version"]) deps_content = http.request( "GET", - f"https://raw.githubusercontent.com/chromium/chromium/{chrome_release['version']}/DEPS", + f"https://raw.githubusercontent.com/chromium/chromium/{chrome_milestone['version']}/DEPS", ).data.decode("utf-8") v8_revision_line = next((line for line in deps_content.split("\n") if "v8_revision" in line), None) if v8_revision_line is None: - raise ValueError(f"No v8_revision found in DEPS for Chrome {chrome_release['version']}") + raise ValueError(f"No v8_revision found in DEPS for Chrome {chrome_milestone['version']}") v8_revision = v8_revision_line.split(": ")[1].strip("',") fetch_and_save( f"https://raw.githubusercontent.com/v8/v8/{v8_revision}/include/js_protocol.pdl", @@ -116,15 +116,15 @@ def add_pdls(chrome_release): file.truncate() -def create_new_chrome_files(src_base, chrome_release): +def create_new_chrome_files(src_base, chrome_milestone): """Create new Chrome devtools files for a language binding. Java and .NET need to copy previous version directory into new version directory. """ - source_dir = root_dir / f"{src_base}/v{previous_chrome(chrome_release)}" - target_dir = root_dir / f"{src_base}/v{new_chrome(chrome_release)}" - old_dir = root_dir / f"{src_base}/v{old_chrome(chrome_release)}" + source_dir = root_dir / f"{src_base}/v{previous_chrome(chrome_milestone)}" + target_dir = root_dir / f"{src_base}/v{new_chrome(chrome_milestone)}" + old_dir = root_dir / f"{src_base}/v{old_chrome(chrome_milestone)}" if old_dir.is_dir(): shutil.rmtree(old_dir) @@ -135,8 +135,8 @@ def create_new_chrome_files(src_base, chrome_release): shutil.copy(item, target_dir) for file in target_dir.iterdir(): - replace_in_file(file, previous_chrome(chrome_release), new_chrome(chrome_release)) - new_filename = file.name.replace(previous_chrome(chrome_release), new_chrome(chrome_release)) + replace_in_file(file, previous_chrome(chrome_milestone), new_chrome(chrome_milestone)) + new_filename = file.name.replace(previous_chrome(chrome_milestone), new_chrome(chrome_milestone)) file.rename(target_dir / new_filename) @@ -150,19 +150,19 @@ def replace_in_file(file_path, old_string, new_string, is_regex=False): file.truncate() -def update_java(chrome_release): - create_new_chrome_files("java/src/org/openqa/selenium/devtools", chrome_release) +def update_java(chrome_milestone): + create_new_chrome_files("java/src/org/openqa/selenium/devtools", chrome_milestone) files = [ root_dir / "java/src/org/openqa/selenium/devtools/versions.bzl", root_dir / "rake_tasks/java.rake", ] for file in files: - replace_in_file(file, old_chrome(chrome_release), new_chrome(chrome_release)) + replace_in_file(file, old_chrome(chrome_milestone), new_chrome(chrome_milestone)) -def update_dotnet(chrome_release): - create_new_chrome_files("dotnet/src/webdriver/DevTools", chrome_release) +def update_dotnet(chrome_milestone): + create_new_chrome_files("dotnet/src/webdriver/DevTools", chrome_milestone) files = [ root_dir / "dotnet/version.bzl", @@ -170,36 +170,36 @@ def update_dotnet(chrome_release): root_dir / "dotnet/src/webdriver/DevTools/DevToolsDomains.cs", ] for file in files: - replace_in_file(file, old_chrome(chrome_release), new_chrome(chrome_release)) + replace_in_file(file, old_chrome(chrome_milestone), new_chrome(chrome_milestone)) files = [root_dir / "dotnet/test/webdriver/Infrastructure/DriverConfigs/StableChannelChromeDriver.cs"] dir_path = root_dir / "dotnet/test/webdriver/DevTools" files.extend(str(file) for file in dir_path.glob("*") if file.is_file()) for file in files: - replace_in_file(file, previous_chrome(chrome_release), new_chrome(chrome_release)) + replace_in_file(file, previous_chrome(chrome_milestone), new_chrome(chrome_milestone)) -def update_ruby(chrome_release): +def update_ruby(chrome_milestone): file = root_dir / "rb/lib/selenium/devtools/BUILD.bazel" - replace_in_file(file, old_chrome(chrome_release), new_chrome(chrome_release)) + replace_in_file(file, old_chrome(chrome_milestone), new_chrome(chrome_milestone)) file = root_dir / "rb/lib/selenium/devtools/version.rb" replace_in_file( file, - rf"{previous_chrome(chrome_release)}\.[0-9]*", - f"{new_chrome(chrome_release)}.0", + rf"{previous_chrome(chrome_milestone)}\.[0-9]*", + f"{new_chrome(chrome_milestone)}.0", True, ) -def update_python(chrome_release): +def update_python(chrome_milestone): file = root_dir / "py/BUILD.bazel" - replace_in_file(file, old_chrome(chrome_release), new_chrome(chrome_release)) + replace_in_file(file, old_chrome(chrome_milestone), new_chrome(chrome_milestone)) -def update_js(chrome_release): +def update_js(chrome_milestone): file = root_dir / "javascript/selenium-webdriver/BUILD.bazel" - replace_in_file(file, old_chrome(chrome_release), new_chrome(chrome_release)) + replace_in_file(file, old_chrome(chrome_milestone), new_chrome(chrome_milestone)) if __name__ == "__main__": @@ -207,12 +207,12 @@ def update_js(chrome_release): parser.add_argument("--chrome_channel", default="Stable", help="Set the Chrome channel (use Beta for early stable)") args = parser.parse_args() - chrome_release = latest_for_channel(args.chrome_channel) - add_pdls(chrome_release) - update_java(chrome_release) - update_dotnet(chrome_release) - update_ruby(chrome_release) - update_python(chrome_release) - update_js(chrome_release) + chrome_milestone = latest_for_channel(args.chrome_channel) + add_pdls(chrome_milestone) + update_java(chrome_milestone) + update_dotnet(chrome_milestone) + update_ruby(chrome_milestone) + update_python(chrome_milestone) + update_js(chrome_milestone) - print(f"adding CDP {new_chrome(chrome_release)} and removing {old_chrome(chrome_release)}") + print(f"adding CDP {new_chrome(chrome_milestone)} and removing {old_chrome(chrome_milestone)}") From 8c69597846344855b8c15dbadeaa18acd111fbdc Mon Sep 17 00:00:00 2001 From: Titus Fortner Date: Wed, 8 Jul 2026 10:28:52 -0500 Subject: [PATCH 7/7] [build] Reduce to minimal resolver swap and silent-fetch guards --- scripts/pinned_browsers.py | 17 ++++++++--------- scripts/update_cdp.py | 25 +++++++++++++++---------- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/scripts/pinned_browsers.py b/scripts/pinned_browsers.py index 0b4bc942dbb73..f8cbdca353a5b 100755 --- a/scripts/pinned_browsers.py +++ b/scripts/pinned_browsers.py @@ -27,19 +27,18 @@ def calculate_hash(url): return h.hexdigest() -def latest_for_channel(channel): - """Newest Chrome-for-Testing version entry (version + downloads) for a channel. - - Uses Chrome-for-Testing's channel designation, which tracks the latest milestone and is - unaffected by N-1 security respins. - """ - r = http.request("GET", "https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions.json") +def get_chrome_info_for_channel(channel): + r = http.request( + "GET", + "https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions.json", + ) milestone = json.loads(r.data)["channels"][channel]["version"].split(".")[0] r = http.request( "GET", "https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json", ) versions = json.loads(r.data)["versions"] + return sorted( filter(lambda v: v["version"].split(".")[0] == str(milestone), versions), key=lambda v: parse(v["version"]), @@ -549,12 +548,12 @@ def pin_browsers(): content = content + edge_and_edgedriver() # Stable Chrome - stable_chrome_info = latest_for_channel("Stable") + stable_chrome_info = get_chrome_info_for_channel(channel="Stable") content = content + chrome(stable_chrome_info, workspace_prefix="") content = content + chromedriver(stable_chrome_info, workspace_prefix="") # Beta Chrome - beta_chrome_info = latest_for_channel("Beta") + beta_chrome_info = get_chrome_info_for_channel(channel="Beta") content = content + chrome(beta_chrome_info, workspace_prefix="beta_") content = content + chromedriver(beta_chrome_info, workspace_prefix="beta_") diff --git a/scripts/update_cdp.py b/scripts/update_cdp.py index eb71b18b5e447..56bf9548888f8 100755 --- a/scripts/update_cdp.py +++ b/scripts/update_cdp.py @@ -14,19 +14,28 @@ root_dir = Path(os.path.realpath(__file__)).parent.parent -def latest_for_channel(channel): - """Newest Chrome-for-Testing version entry for a channel. +def get_chrome_milestone(): + """Get the Chrome milestone from the channel. - Uses Chrome-for-Testing's channel designation, which tracks the latest milestone and is - unaffected by N-1 security respins. + This is the same method from pinned_browser. Use --chrome_channel=Beta if + using early stable release. """ - r = http.request("GET", "https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions.json") + parser = argparse.ArgumentParser() + parser.add_argument("--chrome_channel", default="Stable", help="Set the Chrome channel") + args = parser.parse_args() + channel = args.chrome_channel + + r = http.request( + "GET", + "https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions.json", + ) milestone = json.loads(r.data)["channels"][channel]["version"].split(".")[0] r = http.request( "GET", "https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json", ) versions = json.loads(r.data)["versions"] + return sorted( filter(lambda v: v["version"].split(".")[0] == str(milestone), versions), key=lambda v: parse(v["version"]), @@ -203,11 +212,7 @@ def update_js(chrome_milestone): if __name__ == "__main__": - parser = argparse.ArgumentParser() - parser.add_argument("--chrome_channel", default="Stable", help="Set the Chrome channel (use Beta for early stable)") - args = parser.parse_args() - - chrome_milestone = latest_for_channel(args.chrome_channel) + chrome_milestone = get_chrome_milestone() add_pdls(chrome_milestone) update_java(chrome_milestone) update_dotnet(chrome_milestone)