tor-commits
Threads by month
- ----- 2025 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- 1 participants
- 213897 discussions

[Git][tpo/applications/mullvad-browser][mullvad-browser-140.2.0esr-15.0-1] fixup! Add CI for Base Browser
by brizental (@brizental) 09 Sep '25
by brizental (@brizental) 09 Sep '25
09 Sep '25
brizental pushed to branch mullvad-browser-140.2.0esr-15.0-1 at The Tor Project / Applications / Mullvad Browser
Commits:
081b9f68 by Beatriz Rizental at 2025-09-09T13:10:41+02:00
fixup! Add CI for Base Browser
- - - - -
5 changed files:
- .gitlab-ci.yml
- .gitlab/ci/jobs/lint/helpers.py → .gitlab/ci/jobs/helpers.py
- .gitlab/ci/jobs/lint/lint.yml
- + .gitlab/ci/jobs/test/python-test.yml
- .gitlab/ci/jobs/update-translations.yml
Changes:
=====================================
.gitlab-ci.yml
=====================================
@@ -1,5 +1,6 @@
stages:
- lint
+ - test
- update-translations
variables:
@@ -9,4 +10,5 @@ variables:
include:
- local: '.gitlab/ci/mixins.yml'
- local: '.gitlab/ci/jobs/lint/lint.yml'
+ - local: '.gitlab/ci/jobs/test/python-test.yml'
- local: '.gitlab/ci/jobs/update-translations.yml'
=====================================
.gitlab/ci/jobs/lint/helpers.py → .gitlab/ci/jobs/helpers.py
=====================================
@@ -112,7 +112,7 @@ if __name__ == "__main__":
parser.add_argument(
"--get-changed-files",
help="Get list of changed files."
- "When running from a merge request get sthe list of changed files since the merge-base of the current branch."
+ "When running from a merge request gets the list of changed files since the merge-base of the current branch."
"When running from a protected branch i.e. any branch that starts with <something>-browser-, gets the list of files changed since the FIREFOX_ tag.",
action="store_true",
)
=====================================
.gitlab/ci/jobs/lint/lint.yml
=====================================
@@ -18,7 +18,7 @@ lint-all:
- firefox
script:
- ./mach configure --with-base-browser-version=0.0.0
- - .gitlab/ci/jobs/lint/helpers.py --get-changed-files | xargs -0 --no-run-if-empty ./mach lint -v
+ - .gitlab/ci/jobs/helpers.py --get-changed-files | xargs -0 --no-run-if-empty ./mach lint -v
rules:
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
# Run job whenever a commit is merged to a protected branch
=====================================
.gitlab/ci/jobs/test/python-test.yml
=====================================
@@ -0,0 +1,24 @@
+python-test:
+ extends: .with-local-repo-bash
+ stage: test
+ image: $IMAGE_PATH
+ interruptible: true
+ variables:
+ MOZBUILD_STATE_PATH: "/var/tmp/mozbuild"
+ cache:
+ paths:
+ - node_modules
+ # Store the cache regardless on job outcome
+ when: 'always'
+ # Share the cache throughout all pipelines running for a given branch
+ key: $CI_COMMIT_REF_SLUG
+ tags:
+ # Run these jobs in the browser dedicated runners.
+ - firefox
+ script:
+ - ./mach configure --with-base-browser-version=0.0.0
+ - .gitlab/ci/jobs/helpers.py --get-changed-files | xargs -0 --no-run-if-empty ./mach python-test -v
+ rules:
+ - if: $CI_PIPELINE_SOURCE == 'merge_request_event' || ($CI_COMMIT_BRANCH && $CI_COMMIT_REF_PROTECTED == 'true' && $CI_PIPELINE_SOURCE == 'push')
+ changes:
+ - "**/test_*.py"
=====================================
.gitlab/ci/jobs/update-translations.yml
=====================================
@@ -81,7 +81,7 @@ combine-en-US-translations:
# push-en-US-translations job.
- echo 'COMBINE_TRANSLATIONS_JOB_ID='"$CI_JOB_ID" >job_id.env
- pip install compare_locales
- - python ./tools/base-browser/l10n/combine-translation-versions.py "$CI_COMMIT_BRANCH" "$TRANSLATION_FILES" "$COMBINED_FILES_JSON"
+ - python ./tools/base_browser/l10n/combine-translation-versions.py "$CI_COMMIT_BRANCH" "$TRANSLATION_FILES" "$COMBINED_FILES_JSON"
push-en-US-translations:
extends: .update-translation-base
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/081…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/081…
You're receiving this email because of your account on gitlab.torproject.org.
1
0

[Git][tpo/applications/tor-browser][tor-browser-115.27.0esr-13.5-1] fixup! Bug 43125: Extend the 13.5 EOL expiry date for tor-browser.
by Pier Angelo Vendrame (@pierov) 09 Sep '25
by Pier Angelo Vendrame (@pierov) 09 Sep '25
09 Sep '25
Pier Angelo Vendrame pushed to branch tor-browser-115.27.0esr-13.5-1 at The Tor Project / Applications / Tor Browser
Commits:
55d160b3 by Henry Wilkes at 2025-09-08T17:57:36+01:00
fixup! Bug 43125: Extend the 13.5 EOL expiry date for tor-browser.
TB 43168: Extend the 13.5 EOL to 24th March 2026.
- - - - -
1 changed file:
- browser/base/content/droppedSupportNotification.js
Changes:
=====================================
browser/base/content/droppedSupportNotification.js
=====================================
@@ -3,8 +3,8 @@
// Show a prompt that a user's system will no longer be supported.
window.addEventListener("load", () => {
let labelId;
- // ESR 115 EOL pushed to 14th October 2025.
- const isExpired = Date.now() > Date.UTC(2025, 9, 14);
+ // ESR 115 EOL pushed to 24th March 2026.
+ const isExpired = Date.now() > Date.UTC(2026, 2, 24);
if (
AppConstants.platform === "macosx" &&
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/55d160b…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/55d160b…
You're receiving this email because of your account on gitlab.torproject.org.
1
0

[Git][tpo/applications/tor-browser] Pushed new tag tor-browser-143.0a1-16.0-1-build1
by brizental (@brizental) 08 Sep '25
by brizental (@brizental) 08 Sep '25
08 Sep '25
brizental pushed new tag tor-browser-143.0a1-16.0-1-build1 at The Tor Project / Applications / Tor Browser
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/tree/tor-brows…
You're receiving this email because of your account on gitlab.torproject.org.
1
0

[Git][tpo/applications/mullvad-browser][mullvad-browser-140.2.0esr-15.0-1] 6 commits: BB 43564: Modify ./mach bootstrap for Base Browser
by brizental (@brizental) 08 Sep '25
by brizental (@brizental) 08 Sep '25
08 Sep '25
brizental pushed to branch mullvad-browser-140.2.0esr-15.0-1 at The Tor Project / Applications / Mullvad Browser
Commits:
c3546be5 by Beatriz Rizental at 2025-09-08T19:32:45+02:00
BB 43564: Modify ./mach bootstrap for Base Browser
- - - - -
802cceaf by Beatriz Rizental at 2025-09-08T19:32:46+02:00
fixup! BB 43564: Modify ./mach bootstrap for Base Browser
EXTRA: Stop asking to configure git during bootstrap.
- - - - -
856dc4ee by Beatriz Rizental at 2025-09-08T19:32:47+02:00
fixup! BB 43564: Modify ./mach bootstrap for Base Browser
- - - - -
a1b3a8cf by Beatriz Rizental at 2025-09-08T19:32:47+02:00
fixup! BB 41803: Add some developer tools for working on tor-browser.
- - - - -
4d66d017 by Beatriz Rizental at 2025-09-08T19:32:48+02:00
fixup! BB 43564: Modify ./mach bootstrap for Base Browser
- - - - -
642024c9 by Beatriz Rizental at 2025-09-08T19:32:49+02:00
fixup! BB 43564: Modify ./mach bootstrap for Base Browser
- - - - -
25 changed files:
- + build/moz.configure/basebrowser-resources.configure
- build/moz.configure/bootstrap.configure
- build/moz.configure/init.configure
- moz.configure
- python/mozboot/mozboot/bootstrap.py
- python/mozbuild/mozbuild/action/tooltool.py
- python/mozbuild/mozbuild/artifact_commands.py
- python/mozbuild/mozbuild/backend/base.py
- + python/mozbuild/mozbuild/tbbutils.py
- python/mozbuild/mozbuild/test/python.toml
- + python/mozbuild/mozbuild/test/test_tbbutils.py
- − tools/base-browser/l10n/combine/tests/README
- tools/base-browser/git-rebase-fixup-preprocessor → tools/base_browser/git-rebase-fixup-preprocessor
- tools/base-browser/l10n/combine-translation-versions.py → tools/base_browser/l10n/combine-translation-versions.py
- tools/base-browser/l10n/combine/__init__.py → tools/base_browser/l10n/combine/__init__.py
- tools/base-browser/l10n/combine/combine.py → tools/base_browser/l10n/combine/combine.py
- tools/base-browser/l10n/combine/tests/__init__.py → tools/base_browser/l10n/combine/tests/__init__.py
- + tools/base_browser/l10n/combine/tests/python.toml
- tools/base-browser/l10n/combine/tests/test_android.py → tools/base_browser/l10n/combine/tests/test_android.py
- tools/base-browser/l10n/combine/tests/test_dtd.py → tools/base_browser/l10n/combine/tests/test_dtd.py
- tools/base-browser/l10n/combine/tests/test_fluent.py → tools/base_browser/l10n/combine/tests/test_fluent.py
- tools/base-browser/l10n/combine/tests/test_properties.py → tools/base_browser/l10n/combine/tests/test_properties.py
- tools/base-browser/missing-css-variables.py → tools/base_browser/missing-css-variables.py
- tools/base-browser/tb-dev → tools/base_browser/tb-dev
- tools/moz.build
Changes:
=====================================
build/moz.configure/basebrowser-resources.configure
=====================================
@@ -0,0 +1,88 @@
+# Helpers
+# -------------------------------------------------
+
+
+@depends(build_project)
+def is_desktop_build(build_project):
+ return build_project == "browser"
+
+
+# Bootstrap resources
+# -------------------------------------------------
+
+
+option(
+ "--with-noscript",
+ env="NOSCRIPT",
+ nargs=1,
+ default=None,
+ help="Path to noscript .xpi extension archive.",
+)
+
+
+@depends(
+ "--with-noscript",
+ mozbuild_state_path,
+ bootstrap_path(
+ "noscript", no_unpack=True, when=depends("--with-noscript")(lambda x: not x)
+ ),
+)
+@checking("for noscript")
+@imports(_from="pathlib", _import="Path")
+def noscript(value, mozbuild_state_path, _bootstrapped):
+ if value:
+ path = Path(value[0])
+ if path.is_file() and path.suffix == ".xpi":
+ return value[0]
+ else:
+ die("--with-noscript must be an existing .xpi file")
+
+ bootstrapped_location = Path(mozbuild_state_path) / "browser"
+ for file in bootstrapped_location.glob(f"*.xpi"):
+ if "noscript" in file.name:
+ return str(bootstrapped_location / file)
+
+ # noscript is not required for building.
+ return None
+
+
+set_config("NOSCRIPT", noscript)
+
+
+option(
+ "--with-tor-browser-fonts",
+ env="TOR_BROWSER_FONTS",
+ nargs=1,
+ default=None,
+ help="Path to location of fonts directory.",
+)
+
+
+@depends(
+ "--with-tor-browser-fonts",
+ mozbuild_state_path,
+ bootstrap_path(
+ "fonts",
+ when=depends("--with-tor-browser-fonts")(lambda x: not x) & is_desktop_build,
+ ),
+)
+@checking("for tor-browser fonts directory")
+@imports(_from="pathlib", _import="Path")
+def tor_browser_fonts(value, mozbuild_state_path, _bootstrapped):
+ if value:
+ path = Path(value[0])
+ # TODO: Do a more thorough check on the directory.
+ if path.is_dir():
+ return value[0]
+ else:
+ die("--with-tor-browser-fonts must point to a real directory.")
+
+ bootstrapped_location = Path(mozbuild_state_path) / "fonts"
+ if bootstrapped_location.is_dir():
+ return str(bootstrapped_location)
+
+ # tor browser fonts directory is not required for building.
+ return None
+
+
+set_config("TOR_BROWSER_FONTS", tor_browser_fonts)
=====================================
build/moz.configure/bootstrap.configure
=====================================
@@ -4,6 +4,29 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+option(
+ "--with-tor-browser-build-out",
+ env="TOR_BROWSER_BUILD_OUT",
+ nargs=1,
+ default="https://tb-build-06.torproject.org/~tb-builder/tor-browser-build/out",
+ help="URL pointing to a Tor Browser Build out folder, served over HTTP[S].",
+)
+
+
+@depends("--with-tor-browser-build-out")
+def tor_browser_build_out(value):
+ if value:
+ return value[0]
+
+
+option(
+ "--enable-tor-browser-build-only-bootstrap",
+ env="TBB_ONLY_BOOTSTRAP",
+ default=False,
+ help="Flag that disables bootstrapping any artifact from Mozilla's Taskcluster. Will only bootstrap artifacts from tor-browser-build.",
+)
+
+
option(
env="MOZ_FETCHES_DIR",
nargs=1,
@@ -115,9 +138,10 @@ def bootstrap_toolchain_tasks(host):
def bootstrap_path(path, **kwargs):
when = kwargs.pop("when", None)
allow_failure = kwargs.pop("allow_failure", None)
+ no_unpack = kwargs.pop("no_unpack", False)
if kwargs:
configure_error(
- "bootstrap_path only takes `when` and `allow_failure` as a keyword argument"
+ "bootstrap_path only takes `when`, `allow_failure` and `no_unpack` as keyword arguments"
)
@depends(
@@ -129,11 +153,16 @@ def bootstrap_path(path, **kwargs):
build_environment,
dependable(path),
dependable(allow_failure),
+ dependable(no_unpack),
+ tor_browser_build_out,
+ "--enable-tor-browser-build-only-bootstrap",
+ target,
when=when,
)
@imports("os")
@imports("subprocess")
@imports("sys")
+ @imports("mozbuild.tbbutils")
@imports(_from="mozbuild.dirutils", _import="ensureParentDir")
@imports(_from="importlib", _import="import_module")
@imports(_from="shutil", _import="rmtree")
@@ -148,6 +177,10 @@ def bootstrap_path(path, **kwargs):
build_env,
path,
allow_failure,
+ no_unpack,
+ tor_browser_build_out,
+ tbb_only_bootstrap,
+ target,
):
if not path:
return
@@ -158,6 +191,83 @@ def bootstrap_path(path, **kwargs):
if path_parts[0] == "clang-tools":
path_prefix = path_parts.pop(0)
+ # Small hack because noscript is inside the browser folder.
+ if path_parts[0] == "noscript":
+ path_prefix = "browser"
+
+ def try_tbb_bootstrap(exists):
+ if not tor_browser_build_out:
+ return False
+
+ # Tor browser build doesn't have artifacts for all targets supported
+ # by the Firefox build system. When this is empty it means we are
+ # building for a platform which tbb doesn't support.
+ if not target.tor_browser_build_alias:
+ return False
+
+ artifact = mozbuild.tbbutils.get_artifact_name(path_parts[0], tasks.prefix)
+ if not artifact:
+ log.info("%s is not mapped to a tbb artifact", path_parts[0])
+ return False
+
+ artifact_path = mozbuild.tbbutils.get_artifact_path(
+ tor_browser_build_out,
+ artifact,
+ target,
+ prefix=path_prefix,
+ log=log.warning,
+ )
+ if not artifact_path:
+ log.info("no path found in tbb/out for %s", artifact)
+ return False
+
+ # We will use the name of the artifact as the index.
+ #
+ # It's usually unique to the artifact version, but each artifact follows
+ # a different naming convention, so we can't really get more specific here.
+ artifact_index = artifact_path.rsplit("/", 1)[-1]
+ index_file = os.path.join(toolchains_base_dir, "indices", artifact)
+ try:
+ with open(index_file) as fh:
+ index = fh.read().strip()
+ except Exception:
+ index = None
+ if index == artifact_index and exists:
+ log.debug("%s is up-to-date", artifact)
+ return True
+
+ command = ["artifact", "toolchain", "--from-url", artifact_path]
+
+ if no_unpack:
+ command.append("--no-unpack")
+
+ # Note to rebasers:
+ # From here on, it's a slightly modified copy/paste
+ # from the end of the try_bootstrap function
+ log.info(
+ "%s bootstrapped toolchain from TBB in %s",
+ "Updating" if exists else "Installing",
+ os.path.join(toolchains_base_dir, path_prefix, artifact),
+ )
+ os.makedirs(os.path.join(toolchains_base_dir, path_prefix), exist_ok=True)
+ proc = subprocess.run(
+ [
+ sys.executable,
+ os.path.join(build_env.topsrcdir, "mach"),
+ "--log-no-times",
+ ]
+ + command,
+ cwd=os.path.join(toolchains_base_dir, path_prefix),
+ check=not allow_failure,
+ )
+ if proc.returncode != 0 and allow_failure:
+ return False
+ ensureParentDir(index_file)
+ with open(index_file, "w") as fh:
+ fh.write(artifact_index)
+
+ return True
+
def try_bootstrap(exists):
if not tasks:
return False
@@ -280,9 +390,10 @@ def bootstrap_path(path, **kwargs):
try:
# With --enable-bootstrap=no-update, we don't `try_bootstrap`, except
# when the toolchain can't be found.
- if (
- "no-update" not in enable_bootstrap or not exists
- ) and not try_bootstrap(exists):
+ if ("no-update" not in enable_bootstrap or not exists) and not (
+ try_tbb_bootstrap(exists)
+ or (not tbb_only_bootstrap and try_bootstrap(exists))
+ ):
# If there aren't toolchain artifacts to use for this build,
# don't return a path.
return None
=====================================
build/moz.configure/init.configure
=====================================
@@ -590,6 +590,21 @@ def split_triplet(triplet, allow_wasi=False):
else:
toolchain = "%s-%s" % (cpu, os)
+ # In tor-browser-build we use slightly different terminology for
+ # the supported platforms. Let's prepare that OS string here.
+ #
+ # Not all possible platforms listed here are supported in tbb,
+ # so this value will be empty sometimes.
+ tor_browser_build_alias = None
+ if canonical_os == "Android" and canonical_kernel == "Linux":
+ tor_browser_build_alias = f"android"
+ elif canonical_os == "GNU" and canonical_kernel == "Linux":
+ tor_browser_build_alias = f"linux"
+ elif canonical_os == "OSX" and canonical_kernel == "Darwin":
+ tor_browser_build_alias = f"macos"
+ elif canonical_os == "WINNT" and canonical_kernel == "WINNT":
+ tor_browser_build_alias = f"windows"
+
return namespace(
alias=triplet,
cpu=CPU(canonical_cpu),
@@ -604,6 +619,7 @@ def split_triplet(triplet, allow_wasi=False):
toolchain=toolchain,
vendor=vendor,
sub_configure_alias=sub_configure_alias,
+ tor_browser_build_alias=tor_browser_build_alias,
)
=====================================
moz.configure
=====================================
@@ -229,6 +229,7 @@ check_prog("WGET", ("wget",), allow_missing=True)
include("build/moz.configure/toolchain.configure", when="--enable-compile-environment")
+include("build/moz.configure/basebrowser-resources.configure")
include("build/moz.configure/pkg.configure")
include("build/moz.configure/memory.configure", when="--enable-compile-environment")
=====================================
python/mozboot/mozboot/bootstrap.py
=====================================
@@ -52,21 +52,28 @@ Note on Artifact Mode:
Artifact builds download prebuilt C++ components rather than building
them locally. Artifact builds are faster!
-Artifact builds are recommended for people working on Firefox or
-Firefox for Android frontends, or the GeckoView Java API. They are unsuitable
+Artifact builds are recommended for people working on Tor Browser or
+Base Browser for Android frontends, or the GeckoView Java API. They are unsuitable
for those working on C++ code. For more information see:
https://firefox-source-docs.mozilla.org/contributing/build/artifact_builds.….
-Please choose the version of Firefox you want to build (see note above):
+# Note to Base Browser developers
+
+This is still highly experimental. Expect bugs!
+
+Please choose the version of Base Browser you want to build (see note above):
%s
Your choice: """
APPLICATIONS = OrderedDict(
[
- ("Firefox for Desktop Artifact Mode", "browser_artifact_mode"),
- ("Firefox for Desktop", "browser"),
- ("GeckoView/Firefox for Android Artifact Mode", "mobile_android_artifact_mode"),
- ("GeckoView/Firefox for Android", "mobile_android"),
+ ("Base Browser for Desktop Artifact Mode", "browser_artifact_mode"),
+ ("Base Browser for Desktop", "browser"),
+ (
+ "GeckoView/Base Browser for Android Artifact Mode",
+ "mobile_android_artifact_mode",
+ ),
+ ("GeckoView/Base Browser for Android", "mobile_android"),
("SpiderMonkey JavaScript engine", "js"),
]
)
@@ -360,6 +367,8 @@ class Bootstrapper:
getattr(self.instance, "ensure_%s_packages" % application)()
def check_code_submission(self, checkout_root: Path):
+ return
+
if self.instance.no_interactive or which("moz-phab"):
return
@@ -474,8 +483,7 @@ class Bootstrapper:
configure_mercurial(hg, state_dir)
# Offer to configure Git, if the current checkout or repo type is Git.
- elif git and checkout_type == "git":
- should_configure_git = False
+ elif False and git and checkout_type == "git":
if not self.instance.no_interactive:
should_configure_git = self.instance.prompt_yesno(prompt=CONFIGURE_GIT)
else:
=====================================
python/mozbuild/mozbuild/action/tooltool.py
=====================================
@@ -1029,14 +1029,29 @@ def unpack_file(filename):
"""Untar `filename`, assuming it is uncompressed or compressed with bzip2,
xz, gzip, zst, or unzip a zip file. The file is assumed to contain a single
directory with a name matching the base of the given filename.
- Xz support is handled by shelling out to 'tar'."""
+ Xz support is handled by shelling out to 'tar'.
+
+ tor-browser#41564 - For supporting tor-browser-build artifacts that contain
+ multiple directories, the archive is extracted into a directory with the
+ same name as the base of the filename. This modification is only applied to
+ tar archives, because that is all that was necessary.
+ """
if os.path.isfile(filename) and tarfile.is_tarfile(filename):
tar_file, zip_ext = os.path.splitext(filename)
base_file, tar_ext = os.path.splitext(tar_file)
clean_path(base_file)
log.info('untarring "%s"' % filename)
with TarFile.open(filename) as tar:
- safe_extract(tar)
+ top_level_directories = set()
+ for name in tar.getnames():
+ dir = name.split("/", 1)[0]
+ top_level_directories.add(dir)
+ if len(top_level_directories) == 1:
+ safe_extract(tar)
+ else:
+ safe_extract(
+ tar, path=os.path.join(os.path.dirname(filename), base_file)
+ )
elif os.path.isfile(filename) and filename.endswith(".tar.zst"):
import zstandard
=====================================
python/mozbuild/mozbuild/artifact_commands.py
=====================================
@@ -244,6 +244,12 @@ def artifact_clear_cache(command_context, tree=None, job=None, verbose=False):
nargs="+",
help="Download toolchain artifact from a given task.",
)
+@CommandArgument(
+ "--from-url",
+ metavar="URL",
+ nargs="+",
+ help="Download toolchain artifact from an arbitrary address.",
+)
@CommandArgument(
"--tooltool-manifest",
metavar="MANIFEST",
@@ -273,6 +279,7 @@ def artifact_toolchain(
skip_cache=False,
from_build=(),
from_task=(),
+ from_url=[],
tooltool_manifest=None,
no_unpack=False,
retry=0,
@@ -504,6 +511,13 @@ def artifact_toolchain(
record = ArtifactRecord(task_id, name)
records[record.filename] = record
+ if from_url:
+ for file in from_url:
+ record = DownloadRecord(
+ file, file.rsplit("/", 1)[-1], None, None, None, True
+ )
+ records[record.filename] = record
+
for record in records.values():
command_context.log(
logging.INFO,
=====================================
python/mozbuild/mozbuild/backend/base.py
=====================================
@@ -2,11 +2,14 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+import errno
import itertools
+import logging
import os
import time
from abc import ABCMeta, abstractmethod
from contextlib import contextmanager
+from pathlib import Path
import mozpack.path as mozpath
from mach.mixin.logging import LoggingMixin
@@ -239,6 +242,72 @@ class BuildBackend(LoggingMixin):
with open(mozpath.join(dir, ".purgecaches"), "w") as f:
f.write("\n")
+ def _setup_tor_browser_environment(self, config):
+ app = config.substs["MOZ_BUILD_APP"]
+
+ noscript_target_filename = "{73a6fe31-595d-460b-a920-fcc0f8843232}.xpi"
+ noscript_location = config.substs.get("NOSCRIPT")
+
+ def _infallible_symlink(src, dst):
+ try:
+ os.symlink(src, dst)
+ except OSError as e:
+ if e.errno == errno.EEXIST:
+ # If the symlink already exists, remove it and try again.
+ os.remove(dst)
+ os.symlink(src, dst)
+ else:
+ return
+
+ if app == "browser":
+ tbdir = Path(config.topobjdir) / "dist" / "bin"
+
+ if config.substs.get("OS_TARGET") == "Darwin":
+ tbdir = next(tbdir.glob("*.app"))
+ paths = {
+ "docs": tbdir / "Contents/Resources/TorBrowser/Docs",
+ "exts": tbdir / "Contents/Resources/distribution/extensions",
+ "fonts": tbdir / "Resources/fonts",
+ }
+ else:
+ paths = {
+ "docs": tbdir / "TorBrowser/Docs",
+ "exts": tbdir / "distribution/extensions",
+ "fonts": tbdir / "fonts",
+ }
+
+ fonts_location = config.substs.get("TOR_BROWSER_FONTS")
+ if fonts_location:
+ self.log(
+ logging.INFO,
+ "_setup_tor_browser_environment",
+ {
+ "fonts_location": fonts_location,
+ "fonts_target": str(paths["fonts"]),
+ },
+ "Creating symlink for fonts files from {fonts_location} to {fonts_target}",
+ )
+
+ for file in Path(fonts_location).iterdir():
+ target = paths["fonts"] / file.name
+ _infallible_symlink(file, target)
+
+ # Set up NoScript extension
+ if noscript_location:
+ noscript_target = paths["exts"] / noscript_target_filename
+ self.log(
+ logging.INFO,
+ "_setup_tor_browser_environment",
+ {
+ "noscript_location": noscript_location,
+ "noscript_target": str(noscript_target),
+ },
+ "Creating symlink for NoScript from {noscript_location} to {noscript_target}",
+ )
+
+ paths["exts"].mkdir(parents=True, exist_ok=True)
+ _infallible_symlink(noscript_location, noscript_target)
+
def post_build(self, config, output, jobs, verbose, status):
"""Called late during 'mach build' execution, after `build(...)` has finished.
@@ -257,6 +326,9 @@ class BuildBackend(LoggingMixin):
"""
self._write_purgecaches(config)
+ if status == 0:
+ self._setup_tor_browser_environment(config)
+
return status
@contextmanager
=====================================
python/mozbuild/mozbuild/tbbutils.py
=====================================
@@ -0,0 +1,103 @@
+import re
+from urllib.request import Request, urlopen
+
+
+def list_files_http(url):
+ try:
+ req = Request(url, method="GET")
+ with urlopen(req) as response:
+ if response.status != 200:
+ return []
+ html = response.read().decode()
+ except Exception:
+ return []
+
+ links = []
+ for href in re.findall(r'<a href="([^"]+)"', html):
+ if href == "../":
+ continue
+
+ links.append(href)
+
+ return links
+
+
+TOR_BROWSER_BUILD_ARTIFACTS = [
+ # Tor Browser Build-only artifacts, these artifacts are not common with Firefox.
+ "noscript",
+ "fonts",
+]
+
+# Mapping of artifacts from taskcluster to tor-browser-build.
+ARTIFACT_NAME_MAP = {
+ "cbindgen": "cbindgen",
+ # FIXME (tor-browser-build#41471): nasm is more or less ready to go, but it needs to have the
+ # executable in the root of the artifact folder instead of nasm/bin.
+ # "nasm": "nasm",
+ # FIXME (tor-browser-build#41421): the clang project as is, is not ready to use. It needs
+ # to be repackaged with a bunch of things that differ per platform. Fun stuff.
+ # "clang": "clang",
+ "node": "node",
+}
+
+
+def get_artifact_name(original_artifact_name, host):
+ # These are not build artifacts, they are pre-built artifacts to be added to the final build,
+ # therefore this check can come before the host check.
+ if original_artifact_name in TOR_BROWSER_BUILD_ARTIFACTS:
+ return original_artifact_name
+
+ if host != "linux64":
+ # Tor browser build only has development artifacts for linux64 host systems.
+ return None
+
+ return ARTIFACT_NAME_MAP.get(original_artifact_name)
+
+
+def get_artifact_path(url, artifact, target, prefix="", log=lambda *args, **kwargs: {}):
+ if prefix:
+ path = prefix
+ else:
+ path = artifact
+
+ # The `?C=M;O=D` parameters make it so links are ordered by
+ # the last modified date. This here to make us get the latest
+ # version of file in the case there are multiple and we just
+ # grab the first one.
+ files = list_files_http(f"{url}/{path}?C=M;O=D")
+
+ if not files:
+ log(f"No files found in {url} for {artifact}.")
+ return None
+
+ def filter_files(files, keyword):
+ return [file for file in files if keyword in file]
+
+ artifact_files = [file for file in files if file.startswith(artifact)]
+
+ if len(artifact_files) == 0:
+ log(f"No files found in {url} for {artifact}.")
+ return None
+
+ if len(artifact_files) == 1:
+ return f"{url}/{path}/{artifact_files[0]}"
+
+ files_per_os = filter_files(artifact_files, target.tor_browser_build_alias)
+
+ # If there are files in the folder, but they don't have the OS in the name
+ # it probably means we can get any of them because they can be used to build
+ # for any OS. So let's just get the first one.
+ #
+ # Note: It could be the case that the artifact _is_ OS dependant, but there
+ # just are no files for the OS we are looking for. In that case, this will
+ # return an incorrect artifact. This should not happen often though and is
+ # something we cannot address until artifact names are standardized on tbb.
+ if len(files_per_os) == 0:
+ return f"{url}/{artifact}/{artifact_files[0]}"
+
+ elif len(files_per_os) == 1:
+ return f"{url}/{artifact}/{files_per_os[0]}"
+
+ matches = filter_files(files_per_os, target.cpu)
+
+ return f"{url}/{artifact}/{matches[0]}" if matches else None
=====================================
python/mozbuild/mozbuild/test/python.toml
=====================================
@@ -111,6 +111,9 @@ subsuite = "mozbuild"
["test_rewrite_mozbuild.py"]
+["test_tbbutils.py"]
+subsuite = "base-browser"
+
["test_telemetry.py"]
["test_telemetry_settings.py"]
=====================================
python/mozbuild/mozbuild/test/test_tbbutils.py
=====================================
@@ -0,0 +1,139 @@
+import unittest
+from types import SimpleNamespace
+from unittest.mock import MagicMock, patch
+
+import mozunit
+
+from mozbuild.tbbutils import get_artifact_path, list_files_http
+
+
+class TestGetArtifactName(unittest.TestCase):
+ def setUp(self):
+ self.artifact = "artifact"
+ self.host = "linux64"
+
+ @patch("mozbuild.tbbutils.TOR_BROWSER_BUILD_ARTIFACTS", new=["artifact"])
+ def test_artifact_in_tbb_artifacts(self):
+ from mozbuild.tbbutils import get_artifact_name
+
+ result = get_artifact_name(self.artifact, self.host)
+ self.assertEqual(result, self.artifact)
+
+ @patch("mozbuild.tbbutils.ARTIFACT_NAME_MAP", new={"artifact": "tcafitra"})
+ def test_host_is_not_linux64(self):
+ from mozbuild.tbbutils import get_artifact_name
+
+ result = get_artifact_name(self.artifact, "linux64-aarch64")
+ self.assertIsNone(result)
+
+ @patch("mozbuild.tbbutils.ARTIFACT_NAME_MAP", new={"artifact": "tcafitra"})
+ def test_mapped_artifact(self):
+ from mozbuild.tbbutils import get_artifact_name
+
+ result = get_artifact_name(self.artifact, self.host)
+ self.assertEqual(result, self.artifact[::-1])
+
+
+class TestGetArtifactPath(unittest.TestCase):
+ def setUp(self):
+ self.url = "http://example.com"
+ self.artifact = "artifact"
+ # This is just an example target which is valid. But it doesn't make
+ # any difference and could be anything for these tests.
+ self.target = SimpleNamespace(tor_browser_build_alias="linux", cpu="x86_64")
+
+ @patch("mozbuild.tbbutils.list_files_http")
+ def test_no_files_returns_none(self, mock_list_files):
+ mock_list_files.return_value = []
+ result = get_artifact_path(self.url, self.artifact, self.target)
+ self.assertIsNone(result)
+
+ @patch("mozbuild.tbbutils.list_files_http")
+ def test_no_matching_files_returns_none(self, mock_list_files):
+ mock_list_files.return_value = ["somethingelse.zip", "yetanotherthing.zip"]
+ result = get_artifact_path(self.url, self.artifact, self.target)
+ self.assertIsNone(result)
+
+ @patch("mozbuild.tbbutils.list_files_http")
+ def test_single_artifact_match(self, mock_list_files):
+ mock_list_files.return_value = ["artifact-1.zip"]
+ result = get_artifact_path(self.url, self.artifact, self.target)
+ self.assertEqual(result, f"{self.url}/{self.artifact}/artifact-1.zip")
+
+ @patch("mozbuild.tbbutils.list_files_http")
+ def test_artifact_without_os_returns_first(self, mock_list_files):
+ mock_list_files.return_value = ["artifact-1.zip", "artifact-2.zip"]
+ result = get_artifact_path(self.url, self.artifact, self.target)
+ self.assertTrue(result.startswith(f"{self.url}/{self.artifact}/"))
+ self.assertIn("artifact-", result)
+
+ @patch("mozbuild.tbbutils.list_files_http")
+ def test_artifact_with_os_match(self, mock_list_files):
+ mock_list_files.return_value = [
+ "artifact-windows.zip",
+ "artifact-linux.zip",
+ ]
+ result = get_artifact_path(self.url, self.artifact, self.target)
+ self.assertEqual(result, f"{self.url}/{self.artifact}/artifact-linux.zip")
+
+ @patch("mozbuild.tbbutils.list_files_http")
+ def test_artifact_with_cpu_match(self, mock_list_files):
+ mock_list_files.return_value = [
+ "artifact-linux-arm.zip",
+ "artifact-linux-x86_64.zip",
+ ]
+ result = get_artifact_path(self.url, self.artifact, self.target)
+ self.assertEqual(
+ result, f"{self.url}/{self.artifact}/artifact-linux-x86_64.zip"
+ )
+
+ @patch("mozbuild.tbbutils.list_files_http")
+ def test_artifact_with_prefix(self, mock_list_files):
+ mock_list_files.return_value = ["artifact-1.zip"]
+
+ prefix = "prefix"
+ result = get_artifact_path(self.url, self.artifact, self.target, prefix=prefix)
+ self.assertEqual(result, f"{self.url}/{prefix}/artifact-1.zip")
+ mock_list_files.assert_called_with(f"{self.url}/{prefix}?C=M;O=D")
+
+
+class TestListFilesHttp(unittest.TestCase):
+ def setUp(self):
+ self.url = "http://example.com"
+
+ @patch("mozbuild.tbbutils.urlopen")
+ def test_non_200_status_returns_empty(self, mock_urlopen):
+ mock_resp = MagicMock()
+ mock_resp.status = 404
+ mock_resp.read.return_value = b""
+ mock_urlopen.return_value.__enter__.return_value = mock_resp
+
+ result = list_files_http(self.url)
+ self.assertEqual(result, [])
+
+ @patch("mozbuild.tbbutils.urlopen")
+ def test_exception_returns_empty(self, mock_urlopen):
+ mock_urlopen.side_effect = Exception("network error")
+ result = list_files_http(self.url)
+ self.assertEqual(result, [])
+
+ @patch("mozbuild.tbbutils.urlopen")
+ def test_regular_links(self, mock_urlopen):
+ html = b"""
+ <html><body>
+ <a href="../">Parent</a>
+ <a href="file1.zip">file1</a>
+ <a href="file2.zip">file2</a>
+ </body></html>
+ """
+ mock_resp = MagicMock()
+ mock_resp.status = 200
+ mock_resp.read.return_value = html
+ mock_urlopen.return_value.__enter__.return_value = mock_resp
+
+ result = list_files_http(self.url)
+ self.assertEqual(result, ["file1.zip", "file2.zip"])
+
+
+if __name__ == "__main__":
+ mozunit.main()
=====================================
tools/base-browser/l10n/combine/tests/README deleted
=====================================
@@ -1,2 +0,0 @@
-python tests to be run with pytest.
-Requires the compare-locales package.
=====================================
tools/base-browser/git-rebase-fixup-preprocessor → tools/base_browser/git-rebase-fixup-preprocessor
=====================================
=====================================
tools/base-browser/l10n/combine-translation-versions.py → tools/base_browser/l10n/combine-translation-versions.py
=====================================
=====================================
tools/base-browser/l10n/combine/__init__.py → tools/base_browser/l10n/combine/__init__.py
=====================================
=====================================
tools/base-browser/l10n/combine/combine.py → tools/base_browser/l10n/combine/combine.py
=====================================
=====================================
tools/base-browser/l10n/combine/tests/__init__.py → tools/base_browser/l10n/combine/tests/__init__.py
=====================================
=====================================
tools/base_browser/l10n/combine/tests/python.toml
=====================================
@@ -0,0 +1,10 @@
+[DEFAULT]
+subsuite = "base-browser"
+
+["test_android.py"]
+
+["test_dtd.py"]
+
+["test_fluent.py"]
+
+["test_properties.py"]
=====================================
tools/base-browser/l10n/combine/tests/test_android.py → tools/base_browser/l10n/combine/tests/test_android.py
=====================================
@@ -1,6 +1,7 @@
import textwrap
-from combine import combine_files
+import mozunit
+from base_browser.l10n.combine import combine_files
def wrap_in_xml(content):
@@ -413,3 +414,7 @@ def test_alternatives():
<string name="string_4_alt">Other string</string>
""",
)
+
+
+if __name__ == "__main__":
+ mozunit.main()
=====================================
tools/base-browser/l10n/combine/tests/test_dtd.py → tools/base_browser/l10n/combine/tests/test_dtd.py
=====================================
@@ -1,6 +1,7 @@
import textwrap
-from combine import combine_files
+import mozunit
+from base_browser.l10n.combine import combine_files
def assert_result(new_content, old_content, expect):
@@ -411,3 +412,7 @@ def test_alternatives():
<!ENTITY string.4.alt "Other string">
""",
)
+
+
+if __name__ == "__main__":
+ mozunit.main()
=====================================
tools/base-browser/l10n/combine/tests/test_fluent.py → tools/base_browser/l10n/combine/tests/test_fluent.py
=====================================
@@ -1,6 +1,7 @@
import textwrap
-from combine import combine_files
+import mozunit
+from base_browser.l10n.combine import combine_files
def assert_result(new_content, old_content, expect):
@@ -475,3 +476,7 @@ def test_alternatives():
-string-4-alt = Other string
""",
)
+
+
+if __name__ == "__main__":
+ mozunit.main()
=====================================
tools/base-browser/l10n/combine/tests/test_properties.py → tools/base_browser/l10n/combine/tests/test_properties.py
=====================================
@@ -1,6 +1,7 @@
import textwrap
-from combine import combine_files
+import mozunit
+from base_browser.l10n.combine import combine_files
def assert_result(new_content, old_content, expect):
@@ -408,3 +409,7 @@ def test_alternatives():
string.4.alt = Other string
""",
)
+
+
+if __name__ == "__main__":
+ mozunit.main()
=====================================
tools/base-browser/missing-css-variables.py → tools/base_browser/missing-css-variables.py
=====================================
=====================================
tools/base-browser/tb-dev → tools/base_browser/tb-dev
=====================================
=====================================
tools/moz.build
=====================================
@@ -71,6 +71,7 @@ with Files("tryselect/docs/**"):
SCHEDULES.exclusive = ["docs"]
PYTHON_UNITTEST_MANIFESTS += [
+ "base_browser/l10n/combine/tests/python.toml",
"fuzzing/smoke/python.toml",
"lint/test/python.toml",
"tryselect/test/python.toml",
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/compare/a5…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/compare/a5…
You're receiving this email because of your account on gitlab.torproject.org.
1
0

[Git][tpo/applications/tor-browser][base-browser-140.2.0esr-15.0-1] 6 commits: BB 43564: Modify ./mach bootstrap for Base Browser
by brizental (@brizental) 08 Sep '25
by brizental (@brizental) 08 Sep '25
08 Sep '25
brizental pushed to branch base-browser-140.2.0esr-15.0-1 at The Tor Project / Applications / Tor Browser
Commits:
85b4d8d5 by Beatriz Rizental at 2025-09-08T19:22:50+02:00
BB 43564: Modify ./mach bootstrap for Base Browser
- - - - -
02a18b4d by Beatriz Rizental at 2025-09-08T19:22:58+02:00
fixup! BB 43564: Modify ./mach bootstrap for Base Browser
EXTRA: Stop asking to configure git during bootstrap.
- - - - -
4937c1b6 by Beatriz Rizental at 2025-09-08T19:23:06+02:00
fixup! BB 43564: Modify ./mach bootstrap for Base Browser
- - - - -
98a01dbd by Beatriz Rizental at 2025-09-08T19:23:32+02:00
fixup! BB 41803: Add some developer tools for working on tor-browser.
- - - - -
10ce4ee0 by Beatriz Rizental at 2025-09-08T19:28:44+02:00
fixup! BB 43564: Modify ./mach bootstrap for Base Browser
- - - - -
e841a083 by Beatriz Rizental at 2025-09-08T19:28:49+02:00
fixup! BB 43564: Modify ./mach bootstrap for Base Browser
- - - - -
25 changed files:
- + build/moz.configure/basebrowser-resources.configure
- build/moz.configure/bootstrap.configure
- build/moz.configure/init.configure
- moz.configure
- python/mozboot/mozboot/bootstrap.py
- python/mozbuild/mozbuild/action/tooltool.py
- python/mozbuild/mozbuild/artifact_commands.py
- python/mozbuild/mozbuild/backend/base.py
- + python/mozbuild/mozbuild/tbbutils.py
- python/mozbuild/mozbuild/test/python.toml
- + python/mozbuild/mozbuild/test/test_tbbutils.py
- − tools/base-browser/l10n/combine/tests/README
- tools/base-browser/git-rebase-fixup-preprocessor → tools/base_browser/git-rebase-fixup-preprocessor
- tools/base-browser/l10n/combine-translation-versions.py → tools/base_browser/l10n/combine-translation-versions.py
- tools/base-browser/l10n/combine/__init__.py → tools/base_browser/l10n/combine/__init__.py
- tools/base-browser/l10n/combine/combine.py → tools/base_browser/l10n/combine/combine.py
- tools/base-browser/l10n/combine/tests/__init__.py → tools/base_browser/l10n/combine/tests/__init__.py
- + tools/base_browser/l10n/combine/tests/python.toml
- tools/base-browser/l10n/combine/tests/test_android.py → tools/base_browser/l10n/combine/tests/test_android.py
- tools/base-browser/l10n/combine/tests/test_dtd.py → tools/base_browser/l10n/combine/tests/test_dtd.py
- tools/base-browser/l10n/combine/tests/test_fluent.py → tools/base_browser/l10n/combine/tests/test_fluent.py
- tools/base-browser/l10n/combine/tests/test_properties.py → tools/base_browser/l10n/combine/tests/test_properties.py
- tools/base-browser/missing-css-variables.py → tools/base_browser/missing-css-variables.py
- tools/base-browser/tb-dev → tools/base_browser/tb-dev
- tools/moz.build
Changes:
=====================================
build/moz.configure/basebrowser-resources.configure
=====================================
@@ -0,0 +1,88 @@
+# Helpers
+# -------------------------------------------------
+
+
+@depends(build_project)
+def is_desktop_build(build_project):
+ return build_project == "browser"
+
+
+# Bootstrap resources
+# -------------------------------------------------
+
+
+option(
+ "--with-noscript",
+ env="NOSCRIPT",
+ nargs=1,
+ default=None,
+ help="Path to noscript .xpi extension archive.",
+)
+
+
+@depends(
+ "--with-noscript",
+ mozbuild_state_path,
+ bootstrap_path(
+ "noscript", no_unpack=True, when=depends("--with-noscript")(lambda x: not x)
+ ),
+)
+@checking("for noscript")
+@imports(_from="pathlib", _import="Path")
+def noscript(value, mozbuild_state_path, _bootstrapped):
+ if value:
+ path = Path(value[0])
+ if path.is_file() and path.suffix == ".xpi":
+ return value[0]
+ else:
+ die("--with-noscript must be an existing .xpi file")
+
+ bootstrapped_location = Path(mozbuild_state_path) / "browser"
+ for file in bootstrapped_location.glob(f"*.xpi"):
+ if "noscript" in file.name:
+ return str(bootstrapped_location / file)
+
+ # noscript is not required for building.
+ return None
+
+
+set_config("NOSCRIPT", noscript)
+
+
+option(
+ "--with-tor-browser-fonts",
+ env="TOR_BROWSER_FONTS",
+ nargs=1,
+ default=None,
+ help="Path to location of fonts directory.",
+)
+
+
+@depends(
+ "--with-tor-browser-fonts",
+ mozbuild_state_path,
+ bootstrap_path(
+ "fonts",
+ when=depends("--with-tor-browser-fonts")(lambda x: not x) & is_desktop_build,
+ ),
+)
+@checking("for tor-browser fonts directory")
+@imports(_from="pathlib", _import="Path")
+def tor_browser_fonts(value, mozbuild_state_path, _bootstrapped):
+ if value:
+ path = Path(value[0])
+ # TODO: Do a more thorough check on the directory.
+ if path.is_dir():
+ return value[0]
+ else:
+ die("--with-tor-browser-fonts must point to a real directory.")
+
+ bootstrapped_location = Path(mozbuild_state_path) / "fonts"
+ if bootstrapped_location.is_dir():
+ return str(bootstrapped_location)
+
+ # tor browser fonts directory is not required for building.
+ return None
+
+
+set_config("TOR_BROWSER_FONTS", tor_browser_fonts)
=====================================
build/moz.configure/bootstrap.configure
=====================================
@@ -4,6 +4,29 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+option(
+ "--with-tor-browser-build-out",
+ env="TOR_BROWSER_BUILD_OUT",
+ nargs=1,
+ default="https://tb-build-06.torproject.org/~tb-builder/tor-browser-build/out",
+ help="URL pointing to a Tor Browser Build out folder, served over HTTP[S].",
+)
+
+
+@depends("--with-tor-browser-build-out")
+def tor_browser_build_out(value):
+ if value:
+ return value[0]
+
+
+option(
+ "--enable-tor-browser-build-only-bootstrap",
+ env="TBB_ONLY_BOOTSTRAP",
+ default=False,
+ help="Flag that disables bootstrapping any artifact from Mozilla's Taskcluster. Will only bootstrap artifacts from tor-browser-build.",
+)
+
+
option(
env="MOZ_FETCHES_DIR",
nargs=1,
@@ -115,9 +138,10 @@ def bootstrap_toolchain_tasks(host):
def bootstrap_path(path, **kwargs):
when = kwargs.pop("when", None)
allow_failure = kwargs.pop("allow_failure", None)
+ no_unpack = kwargs.pop("no_unpack", False)
if kwargs:
configure_error(
- "bootstrap_path only takes `when` and `allow_failure` as a keyword argument"
+ "bootstrap_path only takes `when`, `allow_failure` and `no_unpack` as keyword arguments"
)
@depends(
@@ -129,11 +153,16 @@ def bootstrap_path(path, **kwargs):
build_environment,
dependable(path),
dependable(allow_failure),
+ dependable(no_unpack),
+ tor_browser_build_out,
+ "--enable-tor-browser-build-only-bootstrap",
+ target,
when=when,
)
@imports("os")
@imports("subprocess")
@imports("sys")
+ @imports("mozbuild.tbbutils")
@imports(_from="mozbuild.dirutils", _import="ensureParentDir")
@imports(_from="importlib", _import="import_module")
@imports(_from="shutil", _import="rmtree")
@@ -148,6 +177,10 @@ def bootstrap_path(path, **kwargs):
build_env,
path,
allow_failure,
+ no_unpack,
+ tor_browser_build_out,
+ tbb_only_bootstrap,
+ target,
):
if not path:
return
@@ -158,6 +191,83 @@ def bootstrap_path(path, **kwargs):
if path_parts[0] == "clang-tools":
path_prefix = path_parts.pop(0)
+ # Small hack because noscript is inside the browser folder.
+ if path_parts[0] == "noscript":
+ path_prefix = "browser"
+
+ def try_tbb_bootstrap(exists):
+ if not tor_browser_build_out:
+ return False
+
+ # Tor browser build doesn't have artifacts for all targets supported
+ # by the Firefox build system. When this is empty it means we are
+ # building for a platform which tbb doesn't support.
+ if not target.tor_browser_build_alias:
+ return False
+
+ artifact = mozbuild.tbbutils.get_artifact_name(path_parts[0], tasks.prefix)
+ if not artifact:
+ log.info("%s is not mapped to a tbb artifact", path_parts[0])
+ return False
+
+ artifact_path = mozbuild.tbbutils.get_artifact_path(
+ tor_browser_build_out,
+ artifact,
+ target,
+ prefix=path_prefix,
+ log=log.warning,
+ )
+ if not artifact_path:
+ log.info("no path found in tbb/out for %s", artifact)
+ return False
+
+ # We will use the name of the artifact as the index.
+ #
+ # It's usually unique to the artifact version, but each artifact follows
+ # a different naming convention, so we can't really get more specific here.
+ artifact_index = artifact_path.rsplit("/", 1)[-1]
+ index_file = os.path.join(toolchains_base_dir, "indices", artifact)
+ try:
+ with open(index_file) as fh:
+ index = fh.read().strip()
+ except Exception:
+ index = None
+ if index == artifact_index and exists:
+ log.debug("%s is up-to-date", artifact)
+ return True
+
+ command = ["artifact", "toolchain", "--from-url", artifact_path]
+
+ if no_unpack:
+ command.append("--no-unpack")
+
+ # Note to rebasers:
+ # From here on, it's a slightly modified copy/paste
+ # from the end of the try_bootstrap function
+ log.info(
+ "%s bootstrapped toolchain from TBB in %s",
+ "Updating" if exists else "Installing",
+ os.path.join(toolchains_base_dir, path_prefix, artifact),
+ )
+ os.makedirs(os.path.join(toolchains_base_dir, path_prefix), exist_ok=True)
+ proc = subprocess.run(
+ [
+ sys.executable,
+ os.path.join(build_env.topsrcdir, "mach"),
+ "--log-no-times",
+ ]
+ + command,
+ cwd=os.path.join(toolchains_base_dir, path_prefix),
+ check=not allow_failure,
+ )
+ if proc.returncode != 0 and allow_failure:
+ return False
+ ensureParentDir(index_file)
+ with open(index_file, "w") as fh:
+ fh.write(artifact_index)
+
+ return True
+
def try_bootstrap(exists):
if not tasks:
return False
@@ -280,9 +390,10 @@ def bootstrap_path(path, **kwargs):
try:
# With --enable-bootstrap=no-update, we don't `try_bootstrap`, except
# when the toolchain can't be found.
- if (
- "no-update" not in enable_bootstrap or not exists
- ) and not try_bootstrap(exists):
+ if ("no-update" not in enable_bootstrap or not exists) and not (
+ try_tbb_bootstrap(exists)
+ or (not tbb_only_bootstrap and try_bootstrap(exists))
+ ):
# If there aren't toolchain artifacts to use for this build,
# don't return a path.
return None
=====================================
build/moz.configure/init.configure
=====================================
@@ -590,6 +590,21 @@ def split_triplet(triplet, allow_wasi=False):
else:
toolchain = "%s-%s" % (cpu, os)
+ # In tor-browser-build we use slightly different terminology for
+ # the supported platforms. Let's prepare that OS string here.
+ #
+ # Not all possible platforms listed here are supported in tbb,
+ # so this value will be empty sometimes.
+ tor_browser_build_alias = None
+ if canonical_os == "Android" and canonical_kernel == "Linux":
+ tor_browser_build_alias = f"android"
+ elif canonical_os == "GNU" and canonical_kernel == "Linux":
+ tor_browser_build_alias = f"linux"
+ elif canonical_os == "OSX" and canonical_kernel == "Darwin":
+ tor_browser_build_alias = f"macos"
+ elif canonical_os == "WINNT" and canonical_kernel == "WINNT":
+ tor_browser_build_alias = f"windows"
+
return namespace(
alias=triplet,
cpu=CPU(canonical_cpu),
@@ -604,6 +619,7 @@ def split_triplet(triplet, allow_wasi=False):
toolchain=toolchain,
vendor=vendor,
sub_configure_alias=sub_configure_alias,
+ tor_browser_build_alias=tor_browser_build_alias,
)
=====================================
moz.configure
=====================================
@@ -229,6 +229,7 @@ check_prog("WGET", ("wget",), allow_missing=True)
include("build/moz.configure/toolchain.configure", when="--enable-compile-environment")
+include("build/moz.configure/basebrowser-resources.configure")
include("build/moz.configure/pkg.configure")
include("build/moz.configure/memory.configure", when="--enable-compile-environment")
=====================================
python/mozboot/mozboot/bootstrap.py
=====================================
@@ -52,21 +52,28 @@ Note on Artifact Mode:
Artifact builds download prebuilt C++ components rather than building
them locally. Artifact builds are faster!
-Artifact builds are recommended for people working on Firefox or
-Firefox for Android frontends, or the GeckoView Java API. They are unsuitable
+Artifact builds are recommended for people working on Tor Browser or
+Base Browser for Android frontends, or the GeckoView Java API. They are unsuitable
for those working on C++ code. For more information see:
https://firefox-source-docs.mozilla.org/contributing/build/artifact_builds.….
-Please choose the version of Firefox you want to build (see note above):
+# Note to Base Browser developers
+
+This is still highly experimental. Expect bugs!
+
+Please choose the version of Base Browser you want to build (see note above):
%s
Your choice: """
APPLICATIONS = OrderedDict(
[
- ("Firefox for Desktop Artifact Mode", "browser_artifact_mode"),
- ("Firefox for Desktop", "browser"),
- ("GeckoView/Firefox for Android Artifact Mode", "mobile_android_artifact_mode"),
- ("GeckoView/Firefox for Android", "mobile_android"),
+ ("Base Browser for Desktop Artifact Mode", "browser_artifact_mode"),
+ ("Base Browser for Desktop", "browser"),
+ (
+ "GeckoView/Base Browser for Android Artifact Mode",
+ "mobile_android_artifact_mode",
+ ),
+ ("GeckoView/Base Browser for Android", "mobile_android"),
("SpiderMonkey JavaScript engine", "js"),
]
)
@@ -360,6 +367,8 @@ class Bootstrapper:
getattr(self.instance, "ensure_%s_packages" % application)()
def check_code_submission(self, checkout_root: Path):
+ return
+
if self.instance.no_interactive or which("moz-phab"):
return
@@ -474,8 +483,7 @@ class Bootstrapper:
configure_mercurial(hg, state_dir)
# Offer to configure Git, if the current checkout or repo type is Git.
- elif git and checkout_type == "git":
- should_configure_git = False
+ elif False and git and checkout_type == "git":
if not self.instance.no_interactive:
should_configure_git = self.instance.prompt_yesno(prompt=CONFIGURE_GIT)
else:
=====================================
python/mozbuild/mozbuild/action/tooltool.py
=====================================
@@ -1029,14 +1029,29 @@ def unpack_file(filename):
"""Untar `filename`, assuming it is uncompressed or compressed with bzip2,
xz, gzip, zst, or unzip a zip file. The file is assumed to contain a single
directory with a name matching the base of the given filename.
- Xz support is handled by shelling out to 'tar'."""
+ Xz support is handled by shelling out to 'tar'.
+
+ tor-browser#41564 - For supporting tor-browser-build artifacts that contain
+ multiple directories, the archive is extracted into a directory with the
+ same name as the base of the filename. This modification is only applied to
+ tar archives, because that is all that was necessary.
+ """
if os.path.isfile(filename) and tarfile.is_tarfile(filename):
tar_file, zip_ext = os.path.splitext(filename)
base_file, tar_ext = os.path.splitext(tar_file)
clean_path(base_file)
log.info('untarring "%s"' % filename)
with TarFile.open(filename) as tar:
- safe_extract(tar)
+ top_level_directories = set()
+ for name in tar.getnames():
+ dir = name.split("/", 1)[0]
+ top_level_directories.add(dir)
+ if len(top_level_directories) == 1:
+ safe_extract(tar)
+ else:
+ safe_extract(
+ tar, path=os.path.join(os.path.dirname(filename), base_file)
+ )
elif os.path.isfile(filename) and filename.endswith(".tar.zst"):
import zstandard
=====================================
python/mozbuild/mozbuild/artifact_commands.py
=====================================
@@ -244,6 +244,12 @@ def artifact_clear_cache(command_context, tree=None, job=None, verbose=False):
nargs="+",
help="Download toolchain artifact from a given task.",
)
+@CommandArgument(
+ "--from-url",
+ metavar="URL",
+ nargs="+",
+ help="Download toolchain artifact from an arbitrary address.",
+)
@CommandArgument(
"--tooltool-manifest",
metavar="MANIFEST",
@@ -273,6 +279,7 @@ def artifact_toolchain(
skip_cache=False,
from_build=(),
from_task=(),
+ from_url=[],
tooltool_manifest=None,
no_unpack=False,
retry=0,
@@ -504,6 +511,13 @@ def artifact_toolchain(
record = ArtifactRecord(task_id, name)
records[record.filename] = record
+ if from_url:
+ for file in from_url:
+ record = DownloadRecord(
+ file, file.rsplit("/", 1)[-1], None, None, None, True
+ )
+ records[record.filename] = record
+
for record in records.values():
command_context.log(
logging.INFO,
=====================================
python/mozbuild/mozbuild/backend/base.py
=====================================
@@ -2,11 +2,14 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+import errno
import itertools
+import logging
import os
import time
from abc import ABCMeta, abstractmethod
from contextlib import contextmanager
+from pathlib import Path
import mozpack.path as mozpath
from mach.mixin.logging import LoggingMixin
@@ -239,6 +242,72 @@ class BuildBackend(LoggingMixin):
with open(mozpath.join(dir, ".purgecaches"), "w") as f:
f.write("\n")
+ def _setup_tor_browser_environment(self, config):
+ app = config.substs["MOZ_BUILD_APP"]
+
+ noscript_target_filename = "{73a6fe31-595d-460b-a920-fcc0f8843232}.xpi"
+ noscript_location = config.substs.get("NOSCRIPT")
+
+ def _infallible_symlink(src, dst):
+ try:
+ os.symlink(src, dst)
+ except OSError as e:
+ if e.errno == errno.EEXIST:
+ # If the symlink already exists, remove it and try again.
+ os.remove(dst)
+ os.symlink(src, dst)
+ else:
+ return
+
+ if app == "browser":
+ tbdir = Path(config.topobjdir) / "dist" / "bin"
+
+ if config.substs.get("OS_TARGET") == "Darwin":
+ tbdir = next(tbdir.glob("*.app"))
+ paths = {
+ "docs": tbdir / "Contents/Resources/TorBrowser/Docs",
+ "exts": tbdir / "Contents/Resources/distribution/extensions",
+ "fonts": tbdir / "Resources/fonts",
+ }
+ else:
+ paths = {
+ "docs": tbdir / "TorBrowser/Docs",
+ "exts": tbdir / "distribution/extensions",
+ "fonts": tbdir / "fonts",
+ }
+
+ fonts_location = config.substs.get("TOR_BROWSER_FONTS")
+ if fonts_location:
+ self.log(
+ logging.INFO,
+ "_setup_tor_browser_environment",
+ {
+ "fonts_location": fonts_location,
+ "fonts_target": str(paths["fonts"]),
+ },
+ "Creating symlink for fonts files from {fonts_location} to {fonts_target}",
+ )
+
+ for file in Path(fonts_location).iterdir():
+ target = paths["fonts"] / file.name
+ _infallible_symlink(file, target)
+
+ # Set up NoScript extension
+ if noscript_location:
+ noscript_target = paths["exts"] / noscript_target_filename
+ self.log(
+ logging.INFO,
+ "_setup_tor_browser_environment",
+ {
+ "noscript_location": noscript_location,
+ "noscript_target": str(noscript_target),
+ },
+ "Creating symlink for NoScript from {noscript_location} to {noscript_target}",
+ )
+
+ paths["exts"].mkdir(parents=True, exist_ok=True)
+ _infallible_symlink(noscript_location, noscript_target)
+
def post_build(self, config, output, jobs, verbose, status):
"""Called late during 'mach build' execution, after `build(...)` has finished.
@@ -257,6 +326,9 @@ class BuildBackend(LoggingMixin):
"""
self._write_purgecaches(config)
+ if status == 0:
+ self._setup_tor_browser_environment(config)
+
return status
@contextmanager
=====================================
python/mozbuild/mozbuild/tbbutils.py
=====================================
@@ -0,0 +1,103 @@
+import re
+from urllib.request import Request, urlopen
+
+
+def list_files_http(url):
+ try:
+ req = Request(url, method="GET")
+ with urlopen(req) as response:
+ if response.status != 200:
+ return []
+ html = response.read().decode()
+ except Exception:
+ return []
+
+ links = []
+ for href in re.findall(r'<a href="([^"]+)"', html):
+ if href == "../":
+ continue
+
+ links.append(href)
+
+ return links
+
+
+TOR_BROWSER_BUILD_ARTIFACTS = [
+ # Tor Browser Build-only artifacts, these artifacts are not common with Firefox.
+ "noscript",
+ "fonts",
+]
+
+# Mapping of artifacts from taskcluster to tor-browser-build.
+ARTIFACT_NAME_MAP = {
+ "cbindgen": "cbindgen",
+ # FIXME (tor-browser-build#41471): nasm is more or less ready to go, but it needs to have the
+ # executable in the root of the artifact folder instead of nasm/bin.
+ # "nasm": "nasm",
+ # FIXME (tor-browser-build#41421): the clang project as is, is not ready to use. It needs
+ # to be repackaged with a bunch of things that differ per platform. Fun stuff.
+ # "clang": "clang",
+ "node": "node",
+}
+
+
+def get_artifact_name(original_artifact_name, host):
+ # These are not build artifacts, they are pre-built artifacts to be added to the final build,
+ # therefore this check can come before the host check.
+ if original_artifact_name in TOR_BROWSER_BUILD_ARTIFACTS:
+ return original_artifact_name
+
+ if host != "linux64":
+ # Tor browser build only has development artifacts for linux64 host systems.
+ return None
+
+ return ARTIFACT_NAME_MAP.get(original_artifact_name)
+
+
+def get_artifact_path(url, artifact, target, prefix="", log=lambda *args, **kwargs: {}):
+ if prefix:
+ path = prefix
+ else:
+ path = artifact
+
+ # The `?C=M;O=D` parameters make it so links are ordered by
+ # the last modified date. This here to make us get the latest
+ # version of file in the case there are multiple and we just
+ # grab the first one.
+ files = list_files_http(f"{url}/{path}?C=M;O=D")
+
+ if not files:
+ log(f"No files found in {url} for {artifact}.")
+ return None
+
+ def filter_files(files, keyword):
+ return [file for file in files if keyword in file]
+
+ artifact_files = [file for file in files if file.startswith(artifact)]
+
+ if len(artifact_files) == 0:
+ log(f"No files found in {url} for {artifact}.")
+ return None
+
+ if len(artifact_files) == 1:
+ return f"{url}/{path}/{artifact_files[0]}"
+
+ files_per_os = filter_files(artifact_files, target.tor_browser_build_alias)
+
+ # If there are files in the folder, but they don't have the OS in the name
+ # it probably means we can get any of them because they can be used to build
+ # for any OS. So let's just get the first one.
+ #
+ # Note: It could be the case that the artifact _is_ OS dependant, but there
+ # just are no files for the OS we are looking for. In that case, this will
+ # return an incorrect artifact. This should not happen often though and is
+ # something we cannot address until artifact names are standardized on tbb.
+ if len(files_per_os) == 0:
+ return f"{url}/{artifact}/{artifact_files[0]}"
+
+ elif len(files_per_os) == 1:
+ return f"{url}/{artifact}/{files_per_os[0]}"
+
+ matches = filter_files(files_per_os, target.cpu)
+
+ return f"{url}/{artifact}/{matches[0]}" if matches else None
=====================================
python/mozbuild/mozbuild/test/python.toml
=====================================
@@ -111,6 +111,9 @@ subsuite = "mozbuild"
["test_rewrite_mozbuild.py"]
+["test_tbbutils.py"]
+subsuite = "base-browser"
+
["test_telemetry.py"]
["test_telemetry_settings.py"]
=====================================
python/mozbuild/mozbuild/test/test_tbbutils.py
=====================================
@@ -0,0 +1,139 @@
+import unittest
+from types import SimpleNamespace
+from unittest.mock import MagicMock, patch
+
+import mozunit
+
+from mozbuild.tbbutils import get_artifact_path, list_files_http
+
+
+class TestGetArtifactName(unittest.TestCase):
+ def setUp(self):
+ self.artifact = "artifact"
+ self.host = "linux64"
+
+ @patch("mozbuild.tbbutils.TOR_BROWSER_BUILD_ARTIFACTS", new=["artifact"])
+ def test_artifact_in_tbb_artifacts(self):
+ from mozbuild.tbbutils import get_artifact_name
+
+ result = get_artifact_name(self.artifact, self.host)
+ self.assertEqual(result, self.artifact)
+
+ @patch("mozbuild.tbbutils.ARTIFACT_NAME_MAP", new={"artifact": "tcafitra"})
+ def test_host_is_not_linux64(self):
+ from mozbuild.tbbutils import get_artifact_name
+
+ result = get_artifact_name(self.artifact, "linux64-aarch64")
+ self.assertIsNone(result)
+
+ @patch("mozbuild.tbbutils.ARTIFACT_NAME_MAP", new={"artifact": "tcafitra"})
+ def test_mapped_artifact(self):
+ from mozbuild.tbbutils import get_artifact_name
+
+ result = get_artifact_name(self.artifact, self.host)
+ self.assertEqual(result, self.artifact[::-1])
+
+
+class TestGetArtifactPath(unittest.TestCase):
+ def setUp(self):
+ self.url = "http://example.com"
+ self.artifact = "artifact"
+ # This is just an example target which is valid. But it doesn't make
+ # any difference and could be anything for these tests.
+ self.target = SimpleNamespace(tor_browser_build_alias="linux", cpu="x86_64")
+
+ @patch("mozbuild.tbbutils.list_files_http")
+ def test_no_files_returns_none(self, mock_list_files):
+ mock_list_files.return_value = []
+ result = get_artifact_path(self.url, self.artifact, self.target)
+ self.assertIsNone(result)
+
+ @patch("mozbuild.tbbutils.list_files_http")
+ def test_no_matching_files_returns_none(self, mock_list_files):
+ mock_list_files.return_value = ["somethingelse.zip", "yetanotherthing.zip"]
+ result = get_artifact_path(self.url, self.artifact, self.target)
+ self.assertIsNone(result)
+
+ @patch("mozbuild.tbbutils.list_files_http")
+ def test_single_artifact_match(self, mock_list_files):
+ mock_list_files.return_value = ["artifact-1.zip"]
+ result = get_artifact_path(self.url, self.artifact, self.target)
+ self.assertEqual(result, f"{self.url}/{self.artifact}/artifact-1.zip")
+
+ @patch("mozbuild.tbbutils.list_files_http")
+ def test_artifact_without_os_returns_first(self, mock_list_files):
+ mock_list_files.return_value = ["artifact-1.zip", "artifact-2.zip"]
+ result = get_artifact_path(self.url, self.artifact, self.target)
+ self.assertTrue(result.startswith(f"{self.url}/{self.artifact}/"))
+ self.assertIn("artifact-", result)
+
+ @patch("mozbuild.tbbutils.list_files_http")
+ def test_artifact_with_os_match(self, mock_list_files):
+ mock_list_files.return_value = [
+ "artifact-windows.zip",
+ "artifact-linux.zip",
+ ]
+ result = get_artifact_path(self.url, self.artifact, self.target)
+ self.assertEqual(result, f"{self.url}/{self.artifact}/artifact-linux.zip")
+
+ @patch("mozbuild.tbbutils.list_files_http")
+ def test_artifact_with_cpu_match(self, mock_list_files):
+ mock_list_files.return_value = [
+ "artifact-linux-arm.zip",
+ "artifact-linux-x86_64.zip",
+ ]
+ result = get_artifact_path(self.url, self.artifact, self.target)
+ self.assertEqual(
+ result, f"{self.url}/{self.artifact}/artifact-linux-x86_64.zip"
+ )
+
+ @patch("mozbuild.tbbutils.list_files_http")
+ def test_artifact_with_prefix(self, mock_list_files):
+ mock_list_files.return_value = ["artifact-1.zip"]
+
+ prefix = "prefix"
+ result = get_artifact_path(self.url, self.artifact, self.target, prefix=prefix)
+ self.assertEqual(result, f"{self.url}/{prefix}/artifact-1.zip")
+ mock_list_files.assert_called_with(f"{self.url}/{prefix}?C=M;O=D")
+
+
+class TestListFilesHttp(unittest.TestCase):
+ def setUp(self):
+ self.url = "http://example.com"
+
+ @patch("mozbuild.tbbutils.urlopen")
+ def test_non_200_status_returns_empty(self, mock_urlopen):
+ mock_resp = MagicMock()
+ mock_resp.status = 404
+ mock_resp.read.return_value = b""
+ mock_urlopen.return_value.__enter__.return_value = mock_resp
+
+ result = list_files_http(self.url)
+ self.assertEqual(result, [])
+
+ @patch("mozbuild.tbbutils.urlopen")
+ def test_exception_returns_empty(self, mock_urlopen):
+ mock_urlopen.side_effect = Exception("network error")
+ result = list_files_http(self.url)
+ self.assertEqual(result, [])
+
+ @patch("mozbuild.tbbutils.urlopen")
+ def test_regular_links(self, mock_urlopen):
+ html = b"""
+ <html><body>
+ <a href="../">Parent</a>
+ <a href="file1.zip">file1</a>
+ <a href="file2.zip">file2</a>
+ </body></html>
+ """
+ mock_resp = MagicMock()
+ mock_resp.status = 200
+ mock_resp.read.return_value = html
+ mock_urlopen.return_value.__enter__.return_value = mock_resp
+
+ result = list_files_http(self.url)
+ self.assertEqual(result, ["file1.zip", "file2.zip"])
+
+
+if __name__ == "__main__":
+ mozunit.main()
=====================================
tools/base-browser/l10n/combine/tests/README deleted
=====================================
@@ -1,2 +0,0 @@
-python tests to be run with pytest.
-Requires the compare-locales package.
=====================================
tools/base-browser/git-rebase-fixup-preprocessor → tools/base_browser/git-rebase-fixup-preprocessor
=====================================
=====================================
tools/base-browser/l10n/combine-translation-versions.py → tools/base_browser/l10n/combine-translation-versions.py
=====================================
=====================================
tools/base-browser/l10n/combine/__init__.py → tools/base_browser/l10n/combine/__init__.py
=====================================
=====================================
tools/base-browser/l10n/combine/combine.py → tools/base_browser/l10n/combine/combine.py
=====================================
=====================================
tools/base-browser/l10n/combine/tests/__init__.py → tools/base_browser/l10n/combine/tests/__init__.py
=====================================
=====================================
tools/base_browser/l10n/combine/tests/python.toml
=====================================
@@ -0,0 +1,10 @@
+[DEFAULT]
+subsuite = "base-browser"
+
+["test_android.py"]
+
+["test_dtd.py"]
+
+["test_fluent.py"]
+
+["test_properties.py"]
=====================================
tools/base-browser/l10n/combine/tests/test_android.py → tools/base_browser/l10n/combine/tests/test_android.py
=====================================
@@ -1,6 +1,7 @@
import textwrap
-from combine import combine_files
+import mozunit
+from base_browser.l10n.combine import combine_files
def wrap_in_xml(content):
@@ -413,3 +414,7 @@ def test_alternatives():
<string name="string_4_alt">Other string</string>
""",
)
+
+
+if __name__ == "__main__":
+ mozunit.main()
=====================================
tools/base-browser/l10n/combine/tests/test_dtd.py → tools/base_browser/l10n/combine/tests/test_dtd.py
=====================================
@@ -1,6 +1,7 @@
import textwrap
-from combine import combine_files
+import mozunit
+from base_browser.l10n.combine import combine_files
def assert_result(new_content, old_content, expect):
@@ -411,3 +412,7 @@ def test_alternatives():
<!ENTITY string.4.alt "Other string">
""",
)
+
+
+if __name__ == "__main__":
+ mozunit.main()
=====================================
tools/base-browser/l10n/combine/tests/test_fluent.py → tools/base_browser/l10n/combine/tests/test_fluent.py
=====================================
@@ -1,6 +1,7 @@
import textwrap
-from combine import combine_files
+import mozunit
+from base_browser.l10n.combine import combine_files
def assert_result(new_content, old_content, expect):
@@ -475,3 +476,7 @@ def test_alternatives():
-string-4-alt = Other string
""",
)
+
+
+if __name__ == "__main__":
+ mozunit.main()
=====================================
tools/base-browser/l10n/combine/tests/test_properties.py → tools/base_browser/l10n/combine/tests/test_properties.py
=====================================
@@ -1,6 +1,7 @@
import textwrap
-from combine import combine_files
+import mozunit
+from base_browser.l10n.combine import combine_files
def assert_result(new_content, old_content, expect):
@@ -408,3 +409,7 @@ def test_alternatives():
string.4.alt = Other string
""",
)
+
+
+if __name__ == "__main__":
+ mozunit.main()
=====================================
tools/base-browser/missing-css-variables.py → tools/base_browser/missing-css-variables.py
=====================================
=====================================
tools/base-browser/tb-dev → tools/base_browser/tb-dev
=====================================
=====================================
tools/moz.build
=====================================
@@ -71,6 +71,7 @@ with Files("tryselect/docs/**"):
SCHEDULES.exclusive = ["docs"]
PYTHON_UNITTEST_MANIFESTS += [
+ "base_browser/l10n/combine/tests/python.toml",
"fuzzing/smoke/python.toml",
"lint/test/python.toml",
"tryselect/test/python.toml",
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/53201c…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/53201c…
You're receiving this email because of your account on gitlab.torproject.org.
1
0

[Git][tpo/applications/tor-browser][tor-browser-140.2.0esr-15.0-1] fixup! BB 43564: Modify ./mach bootstrap for Base Browser
by brizental (@brizental) 08 Sep '25
by brizental (@brizental) 08 Sep '25
08 Sep '25
brizental pushed to branch tor-browser-140.2.0esr-15.0-1 at The Tor Project / Applications / Tor Browser
Commits:
e3afce24 by Beatriz Rizental at 2025-09-08T18:43:45+02:00
fixup! BB 43564: Modify ./mach bootstrap for Base Browser
- - - - -
3 changed files:
- build/moz.configure/bootstrap.configure
- python/mozbuild/mozbuild/tbbutils.py
- python/mozbuild/mozbuild/test/test_tbbutils.py
Changes:
=====================================
build/moz.configure/bootstrap.configure
=====================================
@@ -211,7 +211,11 @@ def bootstrap_path(path, **kwargs):
return False
artifact_path = mozbuild.tbbutils.get_artifact_path(
- tor_browser_build_out, artifact, target, prefix=path_prefix
+ tor_browser_build_out,
+ artifact,
+ target,
+ prefix=path_prefix,
+ log=log.warning,
)
if not artifact_path:
log.info("no path found in tbb/out for %s", artifact)
=====================================
python/mozbuild/mozbuild/tbbutils.py
=====================================
@@ -58,7 +58,7 @@ def get_artifact_name(original_artifact_name, host):
return ARTIFACT_NAME_MAP.get(original_artifact_name)
-def get_artifact_path(url, artifact, target, prefix=""):
+def get_artifact_path(url, artifact, target, prefix="", log=lambda *args, **kwargs: {}):
if prefix:
path = prefix
else:
@@ -71,6 +71,7 @@ def get_artifact_path(url, artifact, target, prefix=""):
files = list_files_http(f"{url}/{path}?C=M;O=D")
if not files:
+ log(f"No files found in {url} for {artifact}.")
return None
def filter_files(files, keyword):
@@ -78,6 +79,10 @@ def get_artifact_path(url, artifact, target, prefix=""):
artifact_files = [file for file in files if file.startswith(artifact)]
+ if len(artifact_files) == 0:
+ log(f"No files found in {url} for {artifact}.")
+ return None
+
if len(artifact_files) == 1:
return f"{url}/{path}/{artifact_files[0]}"
=====================================
python/mozbuild/mozbuild/test/test_tbbutils.py
=====================================
@@ -48,6 +48,12 @@ class TestGetArtifactPath(unittest.TestCase):
result = get_artifact_path(self.url, self.artifact, self.target)
self.assertIsNone(result)
+ @patch("mozbuild.tbbutils.list_files_http")
+ def test_no_matching_files_returns_none(self, mock_list_files):
+ mock_list_files.return_value = ["somethingelse.zip", "yetanotherthing.zip"]
+ result = get_artifact_path(self.url, self.artifact, self.target)
+ self.assertIsNone(result)
+
@patch("mozbuild.tbbutils.list_files_http")
def test_single_artifact_match(self, mock_list_files):
mock_list_files.return_value = ["artifact-1.zip"]
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/e3afce2…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/e3afce2…
You're receiving this email because of your account on gitlab.torproject.org.
1
0

[Git][tpo/applications/mullvad-browser][mullvad-browser-140.2.0esr-15.0-1] fixup! MB 419: Mullvad Browser migration procedures.
by Pier Angelo Vendrame (@pierov) 08 Sep '25
by Pier Angelo Vendrame (@pierov) 08 Sep '25
08 Sep '25
Pier Angelo Vendrame pushed to branch mullvad-browser-140.2.0esr-15.0-1 at The Tor Project / Applications / Mullvad Browser
Commits:
a5709ed4 by Pier Angelo Vendrame at 2025-09-08T16:07:32+02:00
fixup! MB 419: Mullvad Browser migration procedures.
BB 43770: Follow upstream's BrowserGlue simplifications.
- - - - -
2 changed files:
- browser/components/BrowserGlue.sys.mjs
- browser/components/ProfileDataUpgrader.sys.mjs
Changes:
=====================================
browser/components/BrowserGlue.sys.mjs
=====================================
@@ -430,9 +430,7 @@ BrowserGlue.prototype = {
// handle any UI migration
this._migrateUI();
lazy.ProfileDataUpgrader.upgradeBB(this._isNewProfile);
-
- // Mullvad Browser-specific version of _migrateUI.
- this._migrateUIMB();
+ lazy.ProfileDataUpgrader.upgradeMB(this._isNewProfile);
if (!Services.prefs.prefHasUserValue(PREF_PDFJS_ISDEFAULT_CACHE_STATE)) {
lazy.PdfJs.checkIsDefault(this._isNewProfile);
@@ -1654,58 +1652,6 @@ BrowserGlue.prototype = {
}
},
- // Use this method for any MB migration that can be run just before showing
- // the UI.
- // Anything that critically needs to be migrated earlier should not use this.
- async _migrateUIMB() {
- // Version 1: Mullvad Browser 14.5a6: Clear home page update url preference
- // (mullvad-browser#411).
- // Version 2: Mullvad Browser 15.0a2: Remove legacy search addons
- // (tor-browser#43111).
- const MB_MIGRATION_VERSION = 2;
- const MIGRATION_PREF = "mullvadbrowser.migration.version";
-
- // If we decide to force updating users to pass through any version
- // following 14.5, we can remove this check, and check only whether
- // MIGRATION_PREF has a user value, like Mozilla does.
- if (this._isNewProfile) {
- // Do not migrate fresh profiles
- Services.prefs.setIntPref(MIGRATION_PREF, MB_MIGRATION_VERSION);
- return;
- } else if (this._isNewProfile === undefined) {
- // If this happens, check if upstream updated their function and do not
- // set this member anymore!
- console.error("_migrateUIMB: this._isNewProfile is undefined.");
- }
-
- const currentVersion = Services.prefs.getIntPref(MIGRATION_PREF, 0);
-
- if (currentVersion < 1) {
- Services.prefs.clearUserPref("mullvadbrowser.post_update.url");
- }
- const dropAddons = async list => {
- for (const id of list) {
- try {
- const engine = await lazy.AddonManager.getAddonByID(id);
- await engine?.uninstall();
- } catch {}
- }
- };
- if (currentVersion < 2) {
- await dropAddons([
- "brave(a)search.mozilla.org",
- "ddg(a)search.mozilla.org",
- "ddg-html(a)search.mozilla.org",
- "metager(a)search.mozilla.org",
- "mojeek(a)search.mozilla.org",
- "mullvad-leta(a)search.mozilla.org",
- "startpage(a)search.mozilla.org",
- ]);
- }
-
- Services.prefs.setIntPref(MIGRATION_PREF, MB_MIGRATION_VERSION);
- },
-
async _showUpgradeDialog() {
const data = await lazy.OnboardingMessageProvider.getUpgradeMessage();
const { gBrowser } = lazy.BrowserWindowTracker.getTopWindow();
=====================================
browser/components/ProfileDataUpgrader.sys.mjs
=====================================
@@ -974,4 +974,50 @@ export let ProfileDataUpgrader = {
}
Services.prefs.setIntPref(MIGRATION_PREF, MIGRATION_VERSION);
},
+
+ async upgradeMB(isNewProfile) {
+ // Version 1: Mullvad Browser 14.5a6: Clear home page update url preference
+ // (mullvad-browser#411).
+ // Version 2: Mullvad Browser 15.0a2: Remove legacy search addons
+ // (tor-browser#43111).
+ const MB_MIGRATION_VERSION = 2;
+ const MIGRATION_PREF = "mullvadbrowser.migration.version";
+
+ if (isNewProfile) {
+ // Do not migrate fresh profiles
+ Services.prefs.setIntPref(MIGRATION_PREF, MB_MIGRATION_VERSION);
+ return;
+ } else if (isNewProfile === undefined) {
+ // If this happens, check if upstream updated their function and do not
+ // set this member anymore!
+ console.error("upgradeTB: isNewProfile is undefined.");
+ }
+
+ const currentVersion = Services.prefs.getIntPref(MIGRATION_PREF, 0);
+
+ if (currentVersion < 1) {
+ Services.prefs.clearUserPref("mullvadbrowser.post_update.url");
+ }
+ const dropAddons = async list => {
+ for (const id of list) {
+ try {
+ const engine = await lazy.AddonManager.getAddonByID(id);
+ await engine?.uninstall();
+ } catch {}
+ }
+ };
+ if (currentVersion < 2) {
+ await dropAddons([
+ "brave(a)search.mozilla.org",
+ "ddg(a)search.mozilla.org",
+ "ddg-html(a)search.mozilla.org",
+ "metager(a)search.mozilla.org",
+ "mojeek(a)search.mozilla.org",
+ "mullvad-leta(a)search.mozilla.org",
+ "startpage(a)search.mozilla.org",
+ ]);
+ }
+
+ Services.prefs.setIntPref(MIGRATION_PREF, MB_MIGRATION_VERSION);
+ },
};
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/a57…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/a57…
You're receiving this email because of your account on gitlab.torproject.org.
1
0

[Git][tpo/applications/tor-browser][tor-browser-140.2.0esr-15.0-1] fixup! TB 43006: Disable RFP for Font Visibility on Android
by morgan (@morgan) 08 Sep '25
by morgan (@morgan) 08 Sep '25
08 Sep '25
morgan pushed to branch tor-browser-140.2.0esr-15.0-1 at The Tor Project / Applications / Tor Browser
Commits:
dc42afa4 by Pier Angelo Vendrame at 2025-09-08T13:51:04+00:00
fixup! TB 43006: Disable RFP for Font Visibility on Android
TB 43943: Refactor fontvis exclusion on Android.
Rather than updating Document, we can use
nsRFPService::HandleExeptionalRFPTargets.
- - - - -
2 changed files:
- dom/base/Document.cpp
- toolkit/components/resistfingerprinting/nsRFPService.cpp
Changes:
=====================================
dom/base/Document.cpp
=====================================
@@ -17308,12 +17308,6 @@ bool Document::RecomputeResistFingerprinting(bool aForceRefreshRTPCallerType) {
}
bool Document::ShouldResistFingerprinting(RFPTarget aTarget) const {
-#ifdef ANDROID
- if (aTarget == RFPTarget::FontVisibilityBaseSystem ||
- aTarget == RFPTarget::FontVisibilityLangPack) {
- return false;
- }
-#endif
return mShouldResistFingerprinting &&
nsRFPService::IsRFPEnabledFor(this->IsInPrivateBrowsing(), aTarget,
mOverriddenFingerprintingSettings);
=====================================
toolkit/components/resistfingerprinting/nsRFPService.cpp
=====================================
@@ -310,6 +310,13 @@ Maybe<bool> nsRFPService::HandleExeptionalRFPTargets(
}
#endif
+#ifdef ANDROID
+ if (aTarget == RFPTarget::FontVisibilityBaseSystem ||
+ aTarget == RFPTarget::FontVisibilityLangPack) {
+ return Some(false);
+ }
+#endif
+
return Nothing();
}
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/dc42afa…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/dc42afa…
You're receiving this email because of your account on gitlab.torproject.org.
1
0

[Git][tpo/applications/mullvad-browser][mullvad-browser-140.2.0esr-15.0-1] fixup! Firefox preference overrides.
by Pier Angelo Vendrame (@pierov) 08 Sep '25
by Pier Angelo Vendrame (@pierov) 08 Sep '25
08 Sep '25
Pier Angelo Vendrame pushed to branch mullvad-browser-140.2.0esr-15.0-1 at The Tor Project / Applications / Mullvad Browser
Commits:
c735c7ed by Pier Angelo Vendrame at 2025-09-08T15:51:22+02:00
fixup! Firefox preference overrides.
BB 43950: Disable HEVC.
HEVC support can be used for fingerprinting, as it's hardware-dependent
on some systems, or depends on distribution support/installed packages
for Linux.
- - - - -
1 changed file:
- browser/app/profile/001-base-profile.js
Changes:
=====================================
browser/app/profile/001-base-profile.js
=====================================
@@ -483,6 +483,9 @@ pref("gfx.offscreencanvas.enabled", false);
pref("dom.disable_window_move_resize", true);
// Set video VP9 to 0 for everyone (bug 22548)
pref("media.benchmark.vp9.threshold", 0);
+// tor-browser#43950: Disable HEVC, as it will reveal lacking hardware support,
+// or differences in installed codec for Linux systems.
+pref("media.hevc.enabled", false);
pref("privacy.resistFingerprinting.block_mozAddonManager", true); // Bug 26114
pref("dom.webmidi.enabled", false); // Bug 41398: Disable Web MIDI API
// tor-browser#42043: Stop reporting device IDs (and spoof their number without
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/c73…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/c73…
You're receiving this email because of your account on gitlab.torproject.org.
1
0

[Git][tpo/applications/tor-browser][base-browser-140.2.0esr-15.0-1] fixup! Firefox preference overrides.
by Pier Angelo Vendrame (@pierov) 08 Sep '25
by Pier Angelo Vendrame (@pierov) 08 Sep '25
08 Sep '25
Pier Angelo Vendrame pushed to branch base-browser-140.2.0esr-15.0-1 at The Tor Project / Applications / Tor Browser
Commits:
53201cbe by Pier Angelo Vendrame at 2025-09-08T15:49:55+02:00
fixup! Firefox preference overrides.
BB 43950: Disable HEVC.
HEVC support can be used for fingerprinting, as it's hardware-dependent
on some systems, or depends on distribution support/installed packages
for Linux.
- - - - -
1 changed file:
- browser/app/profile/001-base-profile.js
Changes:
=====================================
browser/app/profile/001-base-profile.js
=====================================
@@ -483,6 +483,9 @@ pref("gfx.offscreencanvas.enabled", false);
pref("dom.disable_window_move_resize", true);
// Set video VP9 to 0 for everyone (bug 22548)
pref("media.benchmark.vp9.threshold", 0);
+// tor-browser#43950: Disable HEVC, as it will reveal lacking hardware support,
+// or differences in installed codec for Linux systems.
+pref("media.hevc.enabled", false);
pref("privacy.resistFingerprinting.block_mozAddonManager", true); // Bug 26114
pref("dom.webmidi.enabled", false); // Bug 41398: Disable Web MIDI API
// tor-browser#42043: Stop reporting device IDs (and spoof their number without
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/53201cb…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/53201cb…
You're receiving this email because of your account on gitlab.torproject.org.
1
0