Pier Angelo Vendrame pushed to branch main at The Tor Project / Applications / tor-browser-build
Commits:
-
1fb6aaae
by Pier Angelo Vendrame at 2024-07-30T11:10:15+02:00
-
f51f78b2
by Pier Angelo Vendrame at 2024-07-30T11:10:28+02:00
9 changed files:
- − .gitattributes
- .gitlab/issue_templates/Release Prep - Tor Browser Alpha.md
- .gitlab/issue_templates/Release Prep - Tor Browser Stable.md
- − projects/browser/allowed_addons.json
- projects/browser/build.android
- projects/browser/config
- − projects/browser/verify_allowed_addons.py
- − tools/fetch_allowed_addons.py
- tools/relprep.py
Changes:
| 1 | -projects/browser/allowed_addons.json -diff |
| ... | ... | @@ -59,8 +59,6 @@ Tor Browser Alpha (and Nightly) are on the `main` branch |
| 59 | 59 | - [ ] `fenix_version` : update to match alpha `firefox-android` build tag
|
| 60 | 60 | - [ ] `browser_branch` : update to match alpha `firefox-android` build tag
|
| 61 | 61 | - [ ] `browser_build` : update to match alpha `firefox-android` build tag
|
| 62 | - - [ ] Update allowed_addons.json by running (from `tor-browser-build` root):
|
|
| 63 | - - `./tools/fetch_allowed_addons.py > projects/browser/allowed_addons.json`
|
|
| 64 | 62 | - [ ] Update `projects/translation/config`:
|
| 65 | 63 | - [ ] run `make list_translation_updates-alpha` to get updated hashes
|
| 66 | 64 | - [ ] `steps/base-browser/git_hash` : update with `HEAD` commit of project's `base-browser` branch
|
| ... | ... | @@ -60,8 +60,6 @@ Tor Browser Stable lives in the various `maint-$(TOR_BROWSER_MAJOR).$(TOR_BROWSE |
| 60 | 60 | - [ ] `browser_branch` : update to match stable `firefox-android` build tag
|
| 61 | 61 | - [ ] `browser_build` : update to match stable `firefox-android` build tag
|
| 62 | 62 | variant: Beta
|
| 63 | - - [ ] Update allowed_addons.json by running (from `tor-browser-build` root):
|
|
| 64 | - - `./tools/fetch_allowed_addons.py > projects/browser/allowed_addons.json`
|
|
| 65 | 63 | - [ ] Update `projects/translation/config`:
|
| 66 | 64 | - [ ] run `make list_translation_updates-release` to get updated hashes
|
| 67 | 65 | - [ ] `steps/base-browser/git_hash` : update with `HEAD` commit of project's `base-browser` branch
|
| ... | ... | @@ -39,15 +39,6 @@ unzip ../omni.ja |
| 39 | 39 | }) %]
|
| 40 | 40 | popd
|
| 41 | 41 | |
| 42 | - |
|
| 43 | -[% IF c("var/verify_allowed_addons") %]
|
|
| 44 | - # Check that allowed_addons.json contains the right versions of our bundled extension(s).
|
|
| 45 | - # If so, replace the default allowed_addons.json by ours in the apk assets folder.
|
|
| 46 | - $rootdir/verify_allowed_addons.py "$rootdir/allowed_addons.json" "$noscript_path"
|
|
| 47 | -[% END %]
|
|
| 48 | - |
|
| 49 | -mv $rootdir/allowed_addons.json $assets_dir/allowed_addons.json
|
|
| 50 | - |
|
| 51 | 42 | mkdir apk
|
| 52 | 43 | pushd apk
|
| 53 | 44 | 7zz x "$apk"
|
| ... | ... | @@ -49,7 +49,6 @@ targets: |
| 49 | 49 | android:
|
| 50 | 50 | build: '[% INCLUDE build.android %]'
|
| 51 | 51 | var:
|
| 52 | - verify_allowed_addons: 1
|
|
| 53 | 52 | arch_deps:
|
| 54 | 53 | - 7zip
|
| 55 | 54 | - openjdk-17-jdk-headless
|
| ... | ... | @@ -160,10 +159,6 @@ input_files: |
| 160 | 159 | enable: '[% c("var/namecoin") %]'
|
| 161 | 160 | - filename: namecoin.patch
|
| 162 | 161 | enable: '[% c("var/namecoin") %]'
|
| 163 | - - filename: allowed_addons.json
|
|
| 164 | - enable: '[% c("var/android") %]'
|
|
| 165 | - - filename: verify_allowed_addons.py
|
|
| 166 | - enable: '[% c("var/android") && c("var/verify_allowed_addons") %]'
|
|
| 167 | 162 | - project: manual
|
| 168 | 163 | name: manual
|
| 169 | 164 | enable: '[% ! c("var/android") && c("var/tor-browser") %]'
|
| 1 | -#!/usr/bin/env python3
|
|
| 2 | - |
|
| 3 | -import json
|
|
| 4 | -import sys
|
|
| 5 | -import hashlib
|
|
| 6 | -import zipfile
|
|
| 7 | - |
|
| 8 | -def find_addon(addons, addon_id):
|
|
| 9 | - results = addons['results']
|
|
| 10 | - for x in results:
|
|
| 11 | - addon = x['addon']
|
|
| 12 | - if addon['guid'] == addon_id:
|
|
| 13 | - return addon
|
|
| 14 | - sys.exit("Error: cannot find addon " + addon_id)
|
|
| 15 | - |
|
| 16 | -def verify_extension_version(addons, addon_id, version):
|
|
| 17 | - addon = find_addon(addons, addon_id)
|
|
| 18 | - expected_version = addon['current_version']['version']
|
|
| 19 | - if version != expected_version:
|
|
| 20 | - sys.exit("Error: version " + version + " != " + expected_version)
|
|
| 21 | - |
|
| 22 | -def verify_extension_hash(addons, addon_id, hash):
|
|
| 23 | - addon = find_addon(addons, addon_id)
|
|
| 24 | - expected_hash = addon["current_version"]["files"][0]["hash"]
|
|
| 25 | - if hash != expected_hash:
|
|
| 26 | - sys.exit("Error: hash " + hash + " != " + expected_hash)
|
|
| 27 | - |
|
| 28 | -def read_extension_manifest(path):
|
|
| 29 | - return json.loads(zipfile.ZipFile(path, 'r').read('manifest.json'))
|
|
| 30 | - |
|
| 31 | -def main(argv):
|
|
| 32 | - allowed_addons_path = argv[0]
|
|
| 33 | - noscript_path = argv[1]
|
|
| 34 | - |
|
| 35 | - addons = None
|
|
| 36 | - with open(allowed_addons_path, 'r') as file:
|
|
| 37 | - addons = json.loads(file.read())
|
|
| 38 | - |
|
| 39 | - noscript_hash = None
|
|
| 40 | - with open(noscript_path, 'rb') as file:
|
|
| 41 | - noscript_hash = "sha256:" + hashlib.sha256(file.read()).hexdigest()
|
|
| 42 | - |
|
| 43 | - noscript_version = read_extension_manifest(noscript_path)["version"]
|
|
| 44 | - |
|
| 45 | - verify_extension_hash(addons, '{73a6fe31-595d-460b-a920-fcc0f8843232}', noscript_hash)
|
|
| 46 | - verify_extension_version(addons, '{73a6fe31-595d-460b-a920-fcc0f8843232}', noscript_version)
|
|
| 47 | - |
|
| 48 | -if __name__ == "__main__":
|
|
| 49 | - main(sys.argv[1:]) |
| 1 | -#!/usr/bin/env python3
|
|
| 2 | - |
|
| 3 | -import urllib.request
|
|
| 4 | -import json
|
|
| 5 | -import base64
|
|
| 6 | -import sys
|
|
| 7 | - |
|
| 8 | -NOSCRIPT = "{73a6fe31-595d-460b-a920-fcc0f8843232}"
|
|
| 9 | - |
|
| 10 | - |
|
| 11 | -def fetch(x):
|
|
| 12 | - with urllib.request.urlopen(x) as response:
|
|
| 13 | - return response.read()
|
|
| 14 | - |
|
| 15 | - |
|
| 16 | -def find_addon(addons, addon_id):
|
|
| 17 | - results = addons["results"]
|
|
| 18 | - for x in results:
|
|
| 19 | - addon = x["addon"]
|
|
| 20 | - if addon["guid"] == addon_id:
|
|
| 21 | - return addon
|
|
| 22 | - |
|
| 23 | - |
|
| 24 | -def fetch_and_embed_icons(addons):
|
|
| 25 | - results = addons["results"]
|
|
| 26 | - for x in results:
|
|
| 27 | - addon = x["addon"]
|
|
| 28 | - icon_data = fetch(addon["icon_url"])
|
|
| 29 | - addon["icon_url"] = "data:image/png;base64," + str(
|
|
| 30 | - base64.b64encode(icon_data), "utf8"
|
|
| 31 | - )
|
|
| 32 | - |
|
| 33 | - |
|
| 34 | -def fetch_allowed_addons(amo_collection=None):
|
|
| 35 | - if amo_collection is None:
|
|
| 36 | - amo_collection = "83a9cccfe6e24a34bd7b155ff9ee32"
|
|
| 37 | - url = f"https://services.addons.mozilla.org/api/v4/accounts/account/mozilla/collections/{amo_collection}/addons/"
|
|
| 38 | - data = json.loads(fetch(url))
|
|
| 39 | - fetch_and_embed_icons(data)
|
|
| 40 | - data["results"].sort(key=lambda x: x["addon"]["guid"])
|
|
| 41 | - return data
|
|
| 42 | - |
|
| 43 | - |
|
| 44 | -def main(argv):
|
|
| 45 | - data = fetch_allowed_addons(argv[0] if len(argv) > 1 else None)
|
|
| 46 | - # Check that NoScript is present
|
|
| 47 | - if find_addon(data, NOSCRIPT) is None:
|
|
| 48 | - sys.exit("Error: cannot find NoScript.")
|
|
| 49 | - print(json.dumps(data, indent=2, ensure_ascii=False))
|
|
| 50 | - |
|
| 51 | - |
|
| 52 | -if __name__ == "__main__":
|
|
| 53 | - main(sys.argv[1:]) |
| ... | ... | @@ -4,7 +4,6 @@ from collections import namedtuple |
| 4 | 4 | import configparser
|
| 5 | 5 | from datetime import datetime, timezone
|
| 6 | 6 | from hashlib import sha256
|
| 7 | -import json
|
|
| 8 | 7 | import locale
|
| 9 | 8 | import logging
|
| 10 | 9 | from pathlib import Path
|
| ... | ... | @@ -16,7 +15,6 @@ from git import Repo |
| 16 | 15 | import requests
|
| 17 | 16 | import ruamel.yaml
|
| 18 | 17 | |
| 19 | -from fetch_allowed_addons import NOSCRIPT, fetch_allowed_addons, find_addon
|
|
| 20 | 18 | import fetch_changelogs
|
| 21 | 19 | from update_manual import update_manual
|
| 22 | 20 | |
| ... | ... | @@ -303,28 +301,27 @@ class ReleasePreparation: |
| 303 | 301 | logger.info("Updating addons")
|
| 304 | 302 | config = self.load_config("browser")
|
| 305 | 303 | |
| 306 | - amo_data = fetch_allowed_addons()
|
|
| 307 | - logger.debug("Fetched AMO data")
|
|
| 308 | - if self.android:
|
|
| 309 | - with (
|
|
| 310 | - self.base_path / "projects/browser/allowed_addons.json"
|
|
| 311 | - ).open("w") as f:
|
|
| 312 | - json.dump(amo_data, f, indent=2)
|
|
| 313 | - |
|
| 314 | - noscript = find_addon(amo_data, NOSCRIPT)
|
|
| 315 | 304 | logger.debug("Updating NoScript")
|
| 316 | - self.update_addon_amo(config, "noscript", noscript)
|
|
| 305 | + self.update_addon_amo(
|
|
| 306 | + config, "noscript", "{73a6fe31-595d-460b-a920-fcc0f8843232}"
|
|
| 307 | + )
|
|
| 317 | 308 | if self.mullvad_browser:
|
| 318 | 309 | logger.debug("Updating uBlock Origin")
|
| 319 | - ublock = find_addon(amo_data, "uBlock0@raymondhill.net")
|
|
| 320 | - self.update_addon_amo(config, "ublock-origin", ublock)
|
|
| 310 | + self.update_addon_amo(
|
|
| 311 | + config, "ublock-origin", "uBlock0@raymondhill.net"
|
|
| 312 | + )
|
|
| 321 | 313 | logger.debug("Updating the Mullvad Browser extension")
|
| 322 | 314 | self.update_mullvad_addon(config)
|
| 323 | 315 | |
| 324 | 316 | self.save_config("browser", config)
|
| 325 | 317 | |
| 326 | - def update_addon_amo(self, config, name, addon):
|
|
| 327 | - addon = addon["current_version"]["files"][0]
|
|
| 318 | + def update_addon_amo(self, config, name, addon_id):
|
|
| 319 | + r = requests.get(
|
|
| 320 | + f"https://services.addons.mozilla.org/api/v4/addons/addon/{addon_id}"
|
|
| 321 | + )
|
|
| 322 | + r.raise_for_status()
|
|
| 323 | + amo_data = r.json()
|
|
| 324 | + addon = amo_data["current_version"]["files"][0]
|
|
| 328 | 325 | assert addon["hash"].startswith("sha256:")
|
| 329 | 326 | addon_input = self.find_input(config, name)
|
| 330 | 327 | addon_input["URL"] = addon["url"]
|
| ... | ... | @@ -448,9 +445,9 @@ class ReleasePreparation: |
| 448 | 445 | major = major[2:]
|
| 449 | 446 | return major
|
| 450 | 447 | |
| 448 | + logger.info("Updating Go")
|
|
| 451 | 449 | config = self.load_config("go")
|
| 452 | - # TODO: When Windows 7 goes EOL use config["version"]
|
|
| 453 | - major = get_major(config["var"]["go_1_21"])
|
|
| 450 | + major = get_major(config["version"])
|
|
| 454 | 451 | |
| 455 | 452 | r = requests.get("https://go.dev/dl/?mode=json")
|
| 456 | 453 | r.raise_for_status()
|
| ... | ... | @@ -463,7 +460,7 @@ class ReleasePreparation: |
| 463 | 460 | if not data:
|
| 464 | 461 | raise KeyError("Could not find information for our Go series.")
|
| 465 | 462 | # Skip the "go" prefix in the version.
|
| 466 | - config["var"]["go_1_21"] = data["version"][2:]
|
|
| 463 | + config["version"] = data["version"][2:]
|
|
| 467 | 464 | |
| 468 | 465 | sha256sum = ""
|
| 469 | 466 | for f in data["files"]:
|
| ... | ... | @@ -472,15 +469,7 @@ class ReleasePreparation: |
| 472 | 469 | break
|
| 473 | 470 | if not sha256sum:
|
| 474 | 471 | raise KeyError("Go source package not found.")
|
| 475 | - updated_hash = False
|
|
| 476 | - for input_ in config["input_files"]:
|
|
| 477 | - if "URL" in input_ and "var/go_1_21" in input_["URL"]:
|
|
| 478 | - input_["sha256sum"] = sha256sum
|
|
| 479 | - updated_hash = True
|
|
| 480 | - break
|
|
| 481 | - if not updated_hash:
|
|
| 482 | - raise KeyError("Could not find a matching entry in input_files.")
|
|
| 483 | - |
|
| 472 | + self.find_input(config, "go")["sha256sum"] = sha256sum
|
|
| 484 | 473 | self.save_config("go", config)
|
| 485 | 474 | |
| 486 | 475 | def update_manual(self):
|
| ... | ... | @@ -556,18 +545,11 @@ class ReleasePreparation: |
| 556 | 545 | # Sometimes this might be incorrect for alphas, but let's
|
| 557 | 546 | # keep it for now.
|
| 558 | 547 | kwargs["firefox"] += "esr"
|
| 559 | - self.check_update_simple(kwargs, prev_tag, "tor")
|
|
| 560 | - self.check_update_simple(kwargs, prev_tag, "openssl")
|
|
| 561 | - self.check_update_simple(kwargs, prev_tag, "zlib")
|
|
| 562 | - self.check_update_simple(kwargs, prev_tag, "zstd")
|
|
| 563 | - try:
|
|
| 564 | - self.check_update(kwargs, prev_tag, "go", ["var", "go_1_21"])
|
|
| 565 | - except KeyError as e:
|
|
| 566 | - logger.warning(
|
|
| 567 | - "Go: var/go_1_21 not found, marking Go as not updated.",
|
|
| 568 | - exc_info=e,
|
|
| 569 | - )
|
|
| 570 | - pass
|
|
| 548 | + self.check_update(kwargs, prev_tag, "tor")
|
|
| 549 | + self.check_update(kwargs, prev_tag, "openssl")
|
|
| 550 | + self.check_update(kwargs, prev_tag, "zlib")
|
|
| 551 | + self.check_update(kwargs, prev_tag, "zstd")
|
|
| 552 | + self.check_update(kwargs, prev_tag, "go")
|
|
| 571 | 553 | self.check_update_extensions(kwargs, prev_tag)
|
| 572 | 554 | logger.debug("Changelog arguments for %s: %s", tag_prefix, kwargs)
|
| 573 | 555 | cb = fetch_changelogs.ChangelogBuilder(
|
| ... | ... | @@ -587,7 +569,7 @@ class ReleasePreparation: |
| 587 | 569 | with (self.base_path / path).open("w") as f:
|
| 588 | 570 | f.write(changelogs + "\n" + last_changelogs + "\n")
|
| 589 | 571 | |
| 590 | - def check_update(self, updates, prev_tag, project, key):
|
|
| 572 | + def check_update(self, updates, prev_tag, project, key=["version"]):
|
|
| 591 | 573 | old_val = self.load_old_config(prev_tag.tag, project)
|
| 592 | 574 | new_val = self.load_config(project)
|
| 593 | 575 | for k in key:
|
| ... | ... | @@ -596,9 +578,6 @@ class ReleasePreparation: |
| 596 | 578 | if old_val != new_val:
|
| 597 | 579 | updates[project] = new_val
|
| 598 | 580 | |
| 599 | - def check_update_simple(self, updates, prev_tag, project):
|
|
| 600 | - self.check_update(updates, prev_tag, project, ["version"])
|
|
| 601 | - |
|
| 602 | 581 | def check_update_extensions(self, updates, prev_tag):
|
| 603 | 582 | old_config = self.load_old_config(prev_tag, "browser")
|
| 604 | 583 | new_config = self.load_config("browser")
|