diff --git a/.taskcluster.yml b/.taskcluster.yml index 45697f693..d633736d0 100644 --- a/.taskcluster.yml +++ b/.taskcluster.yml @@ -98,13 +98,14 @@ tasks: - -cx # The rest of the command must be defined below env: - TASK_ID: ${decision_task_id} - TASKS_PRIORITY: ${tasks_priority} - SCHEDULER_ID: ${scheduler_id} - MOBILE_HEAD_REPOSITORY: ${repository} + BUILD_DATE: ${now} MOBILE_HEAD_BRANCH: ${head_branch} + MOBILE_HEAD_REPOSITORY: ${repository} MOBILE_HEAD_REV: ${head_rev} MOBILE_TRIGGERED_BY: ${user} + SCHEDULER_ID: ${scheduler_id} + TASK_ID: ${decision_task_id} + TASKS_PRIORITY: ${tasks_priority} features: taskclusterProxy: true extra: @@ -190,8 +191,7 @@ tasks: --output /opt/fenix/app/build/outputs/apk \ --apk armGreenfield/release/app-arm-greenfield-release-unsigned.apk \ --apk x86Greenfield/release/app-x86-greenfield-release-unsigned.apk \ - --apk aarch64Greenfield/release/app-aarch64-greenfield-release-unsigned.apk \ - --date ${now} + --apk aarch64Greenfield/release/app-aarch64-greenfield-release-unsigned.apk artifacts: public/task-graph.json: type: file diff --git a/automation/taskcluster/decision_task.py b/automation/taskcluster/decision_task.py index b51923a73..734b93aac 100644 --- a/automation/taskcluster/decision_task.py +++ b/automation/taskcluster/decision_task.py @@ -30,13 +30,14 @@ SKIP_TASKS_TRIGGER = '[ci skip]' BUILDER = TaskBuilder( task_id=os.environ.get('TASK_ID'), - repo_url=os.environ.get('MOBILE_HEAD_REPOSITORY'), + repo_url=REPO_URL, branch=os.environ.get('MOBILE_HEAD_BRANCH'), commit=COMMIT, owner="fenix-eng-notifications@mozilla.com", source='{}/raw/{}/.taskcluster.yml'.format(REPO_URL, COMMIT), scheduler_id=os.environ.get('SCHEDULER_ID', 'taskcluster-github'), tasks_priority=os.environ.get('TASKS_PRIORITY'), + date_string=os.environ.get('BUILD_DATE'), ) @@ -73,7 +74,7 @@ def pr_or_push(): return (build_tasks, other_tasks) -def nightly(apks, track, commit, date_string): +def nightly(apks, track, commit): is_staging = track == 'staging-nightly' build_tasks = {} @@ -88,7 +89,6 @@ def nightly(apks, track, commit, date_string): signing_tasks[signing_task_id] = BUILDER.craft_signing_task( build_task_id, apks=artifacts, - date_string=date_string, is_staging=is_staging, ) @@ -127,7 +127,6 @@ if __name__ == "__main__": release_parser.add_argument( '--output', metavar="path", action="store", help="Path to the build output", required=True ) - release_parser.add_argument('--date', action="store", help="ISO8601 timestamp for build") result = parser.parse_args() @@ -137,10 +136,7 @@ if __name__ == "__main__": ordered_groups_of_tasks = pr_or_push() elif command == 'release': apks = ["{}/{}".format(result.output, apk) for apk in result.apks] - # nightly(apks, result.track, result.commit, result.date) - ordered_groups_of_tasks = nightly( - apks, result.track, result.commit, result.date - ) + ordered_groups_of_tasks = nightly(apks, result.track, result.commit) else: raise Exception('Unsupported command "{}"'.format(command)) diff --git a/automation/taskcluster/lib/tasks.py b/automation/taskcluster/lib/tasks.py index fa0801c64..46231d650 100644 --- a/automation/taskcluster/lib/tasks.py +++ b/automation/taskcluster/lib/tasks.py @@ -10,12 +10,15 @@ import json import os import taskcluster +from lib.util import convert_camel_case_into_kebab_case + DEFAULT_EXPIRES_IN = '1 year' +_OFFICIAL_REPO_URL = 'https://github.com/mozilla-mobile/fenix' class TaskBuilder(object): def __init__( - self, task_id, repo_url, branch, commit, owner, source, scheduler_id, + self, task_id, repo_url, branch, commit, owner, source, scheduler_id, date_string, tasks_priority='lowest' ): self.task_id = task_id @@ -26,6 +29,7 @@ class TaskBuilder(object): self.source = source self.scheduler_id = scheduler_id self.tasks_priority = tasks_priority + self.date = arrow.get(date_string) def craft_assemble_release_task(self, apks, is_staging=False): artifacts = { @@ -95,6 +99,7 @@ class TaskBuilder(object): description='Building and testing variant {}'.format(variant), gradle_task='assemble{}'.format(variant.capitalize()), artifacts=_craft_artifacts_from_variant(variant), + routes=self._craft_branch_routes(variant), treeherder={ 'groupSymbol': _craft_treeherder_group_symbol_from_variant(variant), 'jobKind': 'build', @@ -122,6 +127,32 @@ class TaskBuilder(object): }, ) + def _craft_branch_routes(self, variant): + routes = [] + + if self.repo_url == _OFFICIAL_REPO_URL and self.branch == 'master': + architecture, build_type, product = \ + _get_architecture_and_build_type_and_product_from_variant(variant) + product = convert_camel_case_into_kebab_case(product) + postfix = convert_camel_case_into_kebab_case('{}-{}'.format(architecture, build_type)) + + routes = [ + 'index.project.mobile.fenix.branch.{}.revision.{}.{}.{}'.format( + self.branch, self.commit, product, postfix + ), + 'index.project.mobile.fenix.branch.{}.latest.{}.{}'.format( + self.branch, product, postfix + ), + 'index.project.mobile.fenix.branch.{}.pushdate.{}.{}.{}.revision.{}.{}.{}'.format( + self.branch, self.date.year, self.date.month, self.date.day, self.commit, + product, postfix + ), + 'index.project.mobile.fenix.branch.{}.pushdate.{}.{}.{}.latest.{}.{}'.format( + self.branch. self.date.year, self.date.month, self.date.day, product, postfix + ), + ] + return routes + def craft_detekt_task(self): return self._craft_clean_gradle_task( name='detekt', @@ -169,13 +200,14 @@ class TaskBuilder(object): ) def _craft_clean_gradle_task( - self, name, description, gradle_task, artifacts=None, treeherder=None + self, name, description, gradle_task, artifacts=None, routes=None, treeherder=None ): return self._craft_build_ish_task( name=name, description=description, command='./gradlew --no-daemon clean {}'.format(gradle_task), artifacts=artifacts, + routes=routes, treeherder=treeherder, ) @@ -288,9 +320,8 @@ class TaskBuilder(object): } def craft_signing_task( - self, build_task_id, apks, date_string, is_staging=True, + self, build_task_id, apks, is_staging=True, ): - date = arrow.get(date_string) signing_format = 'autograph_apk' payload = { "upstreamArtifacts": [{ @@ -304,10 +335,10 @@ class TaskBuilder(object): index_release = 'staging-signed-nightly' if is_staging else 'signed-nightly' routes = [ "index.project.mobile.fenix.{}.nightly.{}.{}.{}.latest".format( - index_release, date.year, date.month, date.day + index_release, self.date.year, self.date.month, self.date.day ), "index.project.mobile.fenix.{}.nightly.{}.{}.{}.revision.{}".format( - index_release, date.year, date.month, date.day, self.commit + index_release, self.date.year, self.date.month, self.date.day, self.commit ), "index.project.mobile.fenix.{}.nightly.latest".format(index_release), ] @@ -376,7 +407,9 @@ class TaskBuilder(object): def _craft_treeherder_platform_from_variant(variant): - architecture, build_type, _ = _get_architecture_and_build_type_and_product_from_variant(variant) + architecture, build_type, _ = _get_architecture_and_build_type_and_product_from_variant( + variant + ) return 'android-{}-{}'.format(architecture, build_type) diff --git a/automation/taskcluster/lib/util.py b/automation/taskcluster/lib/util.py index 7ef50c02f..38c46e4fb 100644 --- a/automation/taskcluster/lib/util.py +++ b/automation/taskcluster/lib/util.py @@ -1,4 +1,11 @@ import json +import re + + +def convert_camel_case_into_kebab_case(string): + # Inspired from https://stackoverflow.com/questions/1175208/elegant-python-function-to-convert-camelcase-to-snake-case # noqa: E501 + first_pass = re.sub('(.)([A-Z][a-z]+)', r'\1-\2', string) + return re.sub('([a-z0-9])([A-Z])', r'\1-\2', first_pass).lower() def populate_chain_of_trust_required_but_unused_files():