Skip to content

Commit aaeb4a5

Browse files
committed
[build] ensure compatible edge browser and driver when pinning
1 parent 492b6c4 commit aaeb4a5

1 file changed

Lines changed: 130 additions & 84 deletions

File tree

scripts/pinned_browsers.py

Lines changed: 130 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -174,34 +174,95 @@ def case_insensitive_json_loads(json_str):
174174
return convert_keys_to_lowercase(data)
175175

176176

177-
def edge():
178-
content = ""
179-
r = http.request("GET", "https://edgeupdates.microsoft.com/api/products")
177+
def get_edge_versions(platform):
178+
"""Fetch all available Edge browser versions for a platform from enterprise API."""
179+
r = http.request(
180+
"GET", "https://edgeupdates.microsoft.com/api/products?view=enterprise"
181+
)
180182
all_data = case_insensitive_json_loads(r.data)
181183

182-
linux = None
183-
linux_hash = None
184-
mac = None
185-
mac_hash = None
184+
platform_name = "MacOS" if platform == "mac" else "Linux"
185+
artifact_name = "pkg" if platform == "mac" else "deb"
186186

187+
versions = []
187188
for data in all_data:
188-
if not "Stable" == data.get("product"):
189+
if data.get("product") != "Stable":
189190
continue
190191
for release in data["releases"]:
191-
if "MacOS" == release.get("platform"):
192-
for artifact in release["artifacts"]:
193-
if "pkg" == artifact["artifactname"]:
194-
mac = artifact["location"]
195-
mac_hash = artifact["hash"]
196-
mac_version = release["productversion"]
197-
elif "Linux" == release.get("platform"):
198-
for artifact in release["artifacts"]:
199-
if "deb" == artifact["artifactname"]:
200-
linux = artifact["location"]
201-
linux_hash = artifact["hash"]
202-
203-
if mac and mac_hash:
204-
content += """
192+
if release.get("platform") != platform_name:
193+
continue
194+
for artifact in release["artifacts"]:
195+
if artifact["artifactname"] == artifact_name:
196+
versions.append(
197+
{
198+
"url": artifact["location"],
199+
"hash": artifact["hash"],
200+
"version": release["productversion"],
201+
}
202+
)
203+
return versions
204+
205+
206+
def get_edgedriver_version(major, platform):
207+
"""Get the latest EdgeDriver version for a given major version and platform."""
208+
platform_suffix = "LINUX" if platform == "linux" else "MACOS"
209+
r = http.request(
210+
"GET",
211+
f"https://msedgedriver.microsoft.com/LATEST_RELEASE_{major}_{platform_suffix}",
212+
)
213+
if r.status != 200:
214+
return None
215+
return r.data.decode("utf-16").strip()
216+
217+
218+
def get_edgedriver_url(version, platform):
219+
"""Get EdgeDriver download URL if it exists."""
220+
if platform == "linux":
221+
url = f"https://msedgedriver.microsoft.com/{version}/edgedriver_linux64.zip"
222+
else:
223+
url = f"https://msedgedriver.microsoft.com/{version}/edgedriver_mac64_m1.zip"
224+
r = http.request("HEAD", url)
225+
return url if r.status == 200 else None
226+
227+
228+
def find_matching_edge_version(platform):
229+
"""Find the latest Edge version where both browser and driver are available."""
230+
browsers = get_edge_versions(platform)
231+
232+
# Sort by version descending (newest first)
233+
browsers.sort(key=lambda x: parse(x["version"]), reverse=True)
234+
235+
for browser in browsers:
236+
major = browser["version"].split(".")[0]
237+
driver_version = get_edgedriver_version(major, platform)
238+
if not driver_version:
239+
print(f" No driver for {platform} major version {major}", file=sys.stderr)
240+
continue
241+
242+
driver_url = get_edgedriver_url(driver_version, platform)
243+
if not driver_url:
244+
print(
245+
f" Driver {driver_version} not downloadable for {platform}",
246+
file=sys.stderr,
247+
)
248+
continue
249+
250+
print(
251+
f" Found match: browser={browser['version']}, driver={driver_version}",
252+
file=sys.stderr,
253+
)
254+
return {
255+
"browser": browser,
256+
"driver_version": driver_version,
257+
"driver_url": driver_url,
258+
}
259+
260+
return None
261+
262+
263+
def mac_edge_browser_content(browser_url, browser_hash, browser_version):
264+
"""Generate Bazel content for Mac Edge browser."""
265+
return """
205266
pkg_archive(
206267
name = "mac_edge",
207268
url = "%s",
@@ -221,14 +282,12 @@ def edge():
221282
)
222283
\"\"\",
223284
)
224-
""" % (
225-
mac,
226-
mac_hash.lower(),
227-
mac_version,
228-
)
285+
""" % (browser_url, browser_hash.lower(), browser_version)
286+
229287

230-
if linux and linux_hash:
231-
content += """
288+
def linux_edge_browser_content(browser_url, browser_hash):
289+
"""Generate Bazel content for Linux Edge browser."""
290+
return """
232291
deb_archive(
233292
name = "linux_edge",
234293
url = "%s",
@@ -250,64 +309,55 @@ def edge():
250309
)
251310
\"\"\",
252311
)
253-
""" % (linux, linux_hash.lower())
312+
""" % (browser_url, browser_hash.lower())
313+
314+
315+
def edge_and_edgedriver():
316+
"""Fetch Edge browser and EdgeDriver, ensuring versions are compatible."""
317+
matches = {}
318+
319+
for platform in ["mac", "linux"]:
320+
print(f"Finding matching Edge version for {platform}...", file=sys.stderr)
321+
match = find_matching_edge_version(platform)
322+
if match:
323+
matches[platform] = match
324+
else:
325+
print(
326+
f"Warning: No matching Edge browser/driver found for {platform}",
327+
file=sys.stderr,
328+
)
254329

255-
return content
330+
content = ""
256331

332+
# Output browsers first: mac, then linux
333+
if "mac" in matches:
334+
browser = matches["mac"]["browser"]
335+
content += mac_edge_browser_content(
336+
browser["url"], browser["hash"], browser["version"]
337+
)
257338

258-
def edgedriver():
259-
r_stable = http.request("GET", "https://msedgedriver.microsoft.com/LATEST_STABLE")
260-
stable_version = r_stable.data.decode("utf-16").strip()
261-
major_version = stable_version.split(".")[0]
262-
r = http.request(
263-
"GET",
264-
f"https://msedgedriver.microsoft.com/LATEST_RELEASE_{major_version}_LINUX",
265-
)
266-
linux_version = r.data.decode("utf-16").strip()
339+
if "linux" in matches:
340+
browser = matches["linux"]["browser"]
341+
content += linux_edge_browser_content(browser["url"], browser["hash"])
267342

268-
content = ""
343+
# Output drivers: linux, then mac
344+
if "linux" in matches:
345+
content += edgedriver_content(
346+
"linux_edgedriver", matches["linux"]["driver_url"]
347+
)
269348

270-
linux = (
271-
"https://msedgedriver.microsoft.com/%s/edgedriver_linux64.zip" % linux_version
272-
)
273-
sha = calculate_hash(linux)
274-
content = (
275-
content
276-
+ """
277-
http_archive(
278-
name = "linux_edgedriver",
279-
url = "%s",
280-
sha256 = "%s",
281-
build_file_content = \"\"\"
282-
load("@aspect_rules_js//js:defs.bzl", "js_library")
283-
package(default_visibility = ["//visibility:public"])
349+
if "mac" in matches:
350+
content += edgedriver_content("mac_edgedriver", matches["mac"]["driver_url"])
284351

285-
exports_files(["msedgedriver"])
352+
return content
286353

287-
js_library(
288-
name = "msedgedriver-js",
289-
data = ["msedgedriver"],
290-
)
291-
\"\"\",
292-
)
293-
"""
294-
% (linux, sha)
295-
)
296354

297-
r = http.request(
298-
"GET",
299-
f"https://msedgedriver.microsoft.com/LATEST_RELEASE_{major_version}_MACOS",
300-
)
301-
macos_version = r.data.decode("utf-16").strip()
302-
mac = (
303-
"https://msedgedriver.microsoft.com/%s/edgedriver_mac64_m1.zip" % macos_version
304-
)
305-
sha = calculate_hash(mac)
306-
content = (
307-
content
308-
+ """
355+
def edgedriver_content(name, driver_url):
356+
"""Generate Bazel content for EdgeDriver."""
357+
driver_sha = calculate_hash(driver_url)
358+
return """
309359
http_archive(
310-
name = "mac_edgedriver",
360+
name = "%s",
311361
url = "%s",
312362
sha256 = "%s",
313363
build_file_content = \"\"\"
@@ -322,10 +372,7 @@ def edgedriver():
322372
)
323373
\"\"\",
324374
)
325-
"""
326-
% (mac, sha)
327-
)
328-
return content
375+
""" % (name, driver_url, driver_sha)
329376

330377

331378
def geckodriver():
@@ -500,8 +547,7 @@ def pin_browsers():
500547
"""
501548
content = content + firefox()
502549
content = content + geckodriver()
503-
content = content + edge()
504-
content = content + edgedriver()
550+
content = content + edge_and_edgedriver()
505551

506552
# Stable Chrome
507553
stable_chrome_info = get_chrome_info_for_channel(channel="Stable")

0 commit comments

Comments
 (0)