Skip to content

Commit 7c974ee

Browse files
author
Alexandre Lissy
committed
Bug 1763188 - Add Snap support using TC builds
1 parent e09d1f9 commit 7c974ee

File tree

11 files changed

+515
-22
lines changed

11 files changed

+515
-22
lines changed

mozregression/bisector.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,51 @@ def handle_merge(self):
351351
return result
352352

353353

354+
"""
355+
We are just using this to make it clear we have no merge to take care of
356+
We are running an Integration because builds are triggered from cron jobs
357+
on mozilla-central for all Snap package branches
358+
"""
359+
360+
361+
class SnapHandler(IntegrationHandler):
362+
snap_repo = None
363+
_build_infos = {}
364+
snap_rev = {}
365+
366+
def __init__(self, **kwargs):
367+
super(IntegrationHandler, self).__init__(**kwargs)
368+
369+
def record_build_infos(self, build_infos):
370+
self._build_infos["_changeset"] = build_infos._changeset
371+
self._build_infos["_repo_url"] = build_infos._repo_url
372+
self.snap_repo = build_infos._repo_url
373+
374+
def update_build_infos(self, build_infos):
375+
# _build_infos here holds the mozilla-central ones,
376+
# build_infos should be the snap-specific one
377+
self.snap_rev[self._build_infos["_changeset"]] = build_infos.changeset
378+
self.snap_repo = build_infos._repo_url
379+
380+
def get_pushlog_url(self):
381+
# somehow, self.found_repo from this class would not reflect
382+
first_rev, last_rev = self.get_range()
383+
if first_rev == last_rev:
384+
return "%s/pushloghtml?changeset=%s" % (self.snap_repo, first_rev)
385+
return "%s/pushloghtml?fromchange=%s&tochange=%s" % (
386+
self.snap_repo,
387+
first_rev,
388+
last_rev,
389+
)
390+
391+
def revert_build_infos(self, build_infos):
392+
build_infos._changeset = self._build_infos["_changeset"]
393+
build_infos._repo_url = self._build_infos["_repo_url"]
394+
395+
def handle_merge(self):
396+
return None
397+
398+
354399
class IndexPromise(object):
355400
"""
356401
A promise to get a build index.
@@ -503,11 +548,29 @@ def start_dl(r):
503548
return self.build_range.index(bdata)
504549

505550
def evaluate(self, build_infos):
551+
# we force getting data from app info for snap since we are building everything
552+
# out of mozilla-central
553+
if type(self.handler) is SnapHandler:
554+
self.handler.record_build_infos(build_infos)
555+
build_infos._force_update = True
506556
verdict = self.test_runner.evaluate(build_infos, allow_back=bool(self.history))
507557
# old builds do not have metadata about the repo. But once
508558
# the build is installed, we may have it
509559
if self.handler.found_repo is None:
510560
self.handler.found_repo = build_infos.repo_url
561+
if type(self.handler) is SnapHandler:
562+
# Some Snap nightly builds are missing SourceRepository/SourceStamp
563+
# So since we dont have a better source of information, let's get back
564+
# what we had
565+
if build_infos.repo_url is None:
566+
LOG.warning(
567+
"Bisection on a Snap package missing SourceRepository/SourceStamp,"
568+
" falling back to mozilla-central revs."
569+
)
570+
build_infos._force_update = False
571+
self.handler.revert_build_infos(build_infos)
572+
else:
573+
self.handler.update_build_infos(build_infos)
511574
return verdict
512575

513576
def ensure_good_and_bad(self):

mozregression/branches.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,12 @@ def create_branches():
7878
):
7979
for alias in aliases:
8080
branches.set_alias(alias, name)
81+
82+
branches.set_branch("snap-nightly", "mozilla-central")
83+
branches.set_branch("snap-beta", "mozilla-central")
84+
branches.set_branch("snap-stable", "mozilla-central")
85+
branches.set_branch("snap-esr", "mozilla-central")
86+
8187
return branches
8288

8389

mozregression/build_info.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ def __init__(
3636
task_id=None,
3737
):
3838
self._fetch_config = fetch_config
39+
self._force_update = False # will be set True by SnapHandler
3940
self._build_type = build_type
4041
self._build_url = build_url
4142
self._build_date = build_date
@@ -136,9 +137,9 @@ def update_from_app_info(self, app_info):
136137
137138
This helps to build the pushlog url for old nightlies.
138139
"""
139-
if self._changeset is None:
140+
if self._changeset is None or self._force_update is True:
140141
self._changeset = app_info.get("application_changeset")
141-
if self._repo_url is None:
142+
if self._repo_url is None or self._force_update is True:
142143
self._repo_url = app_info.get("application_repository")
143144

144145
def persist_filename_for(self, data, regex=True):

mozregression/cli.py

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,21 @@ def create_parser(defaults):
417417
help="Helps to write the configuration file.",
418418
)
419419

420+
parser.add_argument(
421+
"--allow-sudo",
422+
action="store_true",
423+
help=(
424+
"[Snap] Allow the use of sudo for Snap install/remove operations (otherwise,"
425+
" you will be prompted on each)"
426+
),
427+
)
428+
429+
parser.add_argument(
430+
"--disable-snap-connect",
431+
action="store_true",
432+
help="[Snap] Do not automatically perform 'snap connect'",
433+
)
434+
420435
parser.add_argument("--debug", "-d", action="store_true", help="Show the debug output.")
421436

422437
return parser
@@ -579,14 +594,19 @@ def validate(self):
579594
"x86",
580595
"x86_64",
581596
],
597+
"firefox-snap": [
598+
"aarch64", # will be morphed into arm64
599+
"arm", # will be morphed into armf
600+
"x86_64", # will be morphed into amd64
601+
],
582602
}
583603

584604
user_defined_bits = options.bits is not None
585605
options.bits = parse_bits(options.bits or mozinfo.bits)
586606

587607
if options.arch is not None:
588-
if options.app not in ("gve", "fenix", "focus"):
589-
self.logger.warning("--arch ignored for non Android apps.")
608+
if options.app not in ("gve", "fenix", "focus", "firefox-snap"):
609+
self.logger.warning("--arch ignored for non Android apps or Snap package.")
590610
options.arch = None
591611
elif options.arch not in arch_options[options.app]:
592612
raise MozRegressionError(
@@ -598,6 +618,29 @@ def validate(self):
598618
f"`--arch` required for specified app ({options.app}). "
599619
f"Please specify one of {', '.join(arch_options[options.app])}."
600620
)
621+
elif options.app == "firefox-snap" and options.allow_sudo is False:
622+
self.logger.warning(
623+
"Bisection on Snap package without --allow-sudo, you will be prompted for"
624+
" credential on each 'snap' command."
625+
)
626+
elif options.allow_sudo is True and options.app != "firefox-snap":
627+
raise MozRegressionError(
628+
f"--allow-sudo specified for app ({options.app}), but only valid for "
629+
f"firefox-snap. Please verify your config."
630+
)
631+
elif options.disable_snap_connect is True and options.app != "firefox-snap":
632+
raise MozRegressionError(
633+
f"--disable-snap-conncet specified for app ({options.app}), but only valid for "
634+
f"firefox-snap. Please verify your config."
635+
)
636+
637+
if options.app == "firefox-snap" and (
638+
options.repo is None or not options.repo.startswith("snap-")
639+
):
640+
raise MozRegressionError(
641+
f"--repo not specified for app ({options.app}), or not starting with snap-. "
642+
f"Please use correct repo for bisecting Snap package."
643+
)
601644

602645
fetch_config = create_config(
603646
options.app, mozinfo.os, options.bits, mozinfo.processor, options.arch

mozregression/fetch_configs.py

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -753,3 +753,99 @@ def build_regex(self):
753753
part = "mac"
754754
psuffix = "-asan" if "asan" in self.build_type else ""
755755
return r"jsshell-%s%s\.zip$" % (part, psuffix)
756+
757+
758+
TIMESTAMP_SNAP_UPSTREAM_BUILD = to_utc_timestamp(datetime.datetime(2023, 7, 26, 9, 39, 21))
759+
TIMESTAMP_SNAP_INDEX_RENAME = to_utc_timestamp(datetime.datetime(2023, 11, 17, 21, 46, 39))
760+
# This needs to be updated when we land cross-compilation on treeherder
761+
TIMESTAMP_SNAP_CROSS_COMPILATION = to_utc_timestamp(datetime.datetime(3023, 11, 21, 15, 15, 00))
762+
763+
764+
class FirefoxSnapNightlyConfigMixin(NightlyConfigMixin):
765+
def _get_nightly_repo(self, date):
766+
return "mozilla-central"
767+
768+
769+
class FirefoxSnapIntegrationConfigMixin(IntegrationConfigMixin):
770+
def _idx_key(self, date):
771+
branch_name = ""
772+
773+
if self.integration_branch == "snap-nightly":
774+
branch_name = "nightly"
775+
elif self.integration_branch == "snap-beta":
776+
branch_name = "beta"
777+
elif self.integration_branch == "snap-stable":
778+
branch_name = "stable"
779+
elif self.integration_branch == "snap-esr":
780+
branch_name = "esr"
781+
else:
782+
raise errors.MozRegressionError(
783+
"No such branch available, valid are nightly/beta/stable/esr"
784+
" (prefix with snap- for --repo)"
785+
)
786+
787+
if date < TIMESTAMP_SNAP_UPSTREAM_BUILD:
788+
raise errors.MozRegressionError("No build before this date")
789+
elif date >= TIMESTAMP_SNAP_UPSTREAM_BUILD and date < TIMESTAMP_SNAP_INDEX_RENAME:
790+
index_base = ""
791+
elif date >= TIMESTAMP_SNAP_INDEX_RENAME:
792+
index_base = "{}-".format(self.arch)
793+
794+
if self.arch != "amd64" and date < TIMESTAMP_SNAP_CROSS_COMPILATION:
795+
raise errors.MozRegressionError(f"No support for build other than amd64 ({self.arch})")
796+
797+
return "{}{}".format(index_base, branch_name)
798+
799+
def tk_routes(self, push):
800+
for build_type in self.build_types:
801+
name = "gecko.v2.mozilla-central.revision.{}.firefox.{}{}".format(
802+
push.changeset,
803+
self._idx_key(push.timestamp),
804+
"-{}".format(build_type)
805+
if build_type != "opt" and build_type != "shippable"
806+
else "",
807+
)
808+
yield name
809+
self._inc_used_build()
810+
return
811+
812+
813+
class SnapCommonConfig(CommonConfig):
814+
def should_use_archive(self):
815+
"""
816+
We only want to use TaskCluster builds
817+
"""
818+
return False
819+
820+
def build_regex(self):
821+
return r"(firefox_.*)\.snap"
822+
823+
824+
@REGISTRY.register("firefox-snap")
825+
class FirefoxSnapConfig(
826+
SnapCommonConfig, FirefoxSnapIntegrationConfigMixin, FirefoxSnapNightlyConfigMixin
827+
):
828+
BUILD_TYPES = ("shippable", "opt", "debug")
829+
BUILD_TYPE_FALLBACKS = {
830+
"shippable": ("opt",),
831+
"opt": ("shippable",),
832+
}
833+
834+
def __init__(self, os, bits, processor, arch):
835+
super(FirefoxSnapConfig, self).__init__(os, bits, processor, arch)
836+
self.set_build_type("shippable")
837+
838+
def available_archs(self):
839+
return [
840+
"aarch64",
841+
"arm",
842+
"x86_64",
843+
]
844+
845+
def set_arch(self, arch):
846+
mapping = {
847+
"aarch64": "arm64",
848+
"arm": "armhf",
849+
"x86_64": "amd64",
850+
}
851+
self.arch = mapping.get(arch, "amd64")

0 commit comments

Comments
 (0)