Bug 1557269 - part 2: GPG-sign geckoview artifacts r=mtabara
☠☠ backed out by d2b5726bfce4 ☠ ☠
authorJohan Lorenzo <jlorenzo@mozilla.com>
Mon, 01 Jul 2019 14:01:26 +0000
changeset 543632 e3d495f69dfbacd48088c5136eac8dfb3272d218
parent 543631 b469d332f316fc19f615a296ae4723330f382529
child 543633 9249f90cd640668512d9f32642ec29aefd9ce56f
push id2131
push userffxbld-merge
push dateMon, 26 Aug 2019 18:30:20 +0000
treeherdermozilla-release@b19ffb3ca153 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmtabara
bugs1557269
milestone69.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1557269 - part 2: GPG-sign geckoview artifacts r=mtabara Differential Revision: https://phabricator.services.mozilla.com/D34866
taskcluster/ci/beetmover-geckoview/kind.yml
taskcluster/ci/build/android.yml
taskcluster/taskgraph/manifests/fennec_geckoview.yml
taskcluster/taskgraph/transforms/beetmover_geckoview.py
taskcluster/taskgraph/transforms/build_signing.py
taskcluster/taskgraph/transforms/nightly_l10n_signing.py
taskcluster/taskgraph/transforms/partner_signing.py
taskcluster/taskgraph/transforms/signing.py
taskcluster/taskgraph/util/attributes.py
taskcluster/taskgraph/util/declarative_artifacts.py
taskcluster/taskgraph/util/scriptworker.py
taskcluster/taskgraph/util/signed_artifacts.py
--- a/taskcluster/ci/beetmover-geckoview/kind.yml
+++ b/taskcluster/ci/beetmover-geckoview/kind.yml
@@ -5,17 +5,17 @@
 loader: taskgraph.loader.single_dep:loader
 
 transforms:
     - taskgraph.transforms.name_sanity:transforms
     - taskgraph.transforms.beetmover_geckoview:transforms
     - taskgraph.transforms.task:transforms
 
 kind-dependencies:
-    - build  # geckoview builds aren't signed
+    - build-signing
 
 only-for-attributes:
     - nightly
 
 not-for-build-platforms:
     - linux-nightly/opt
     - linux-shippable/opt
     - linux64-nightly/opt
@@ -35,17 +35,16 @@ not-for-build-platforms:
     - win64-devedition-nightly/opt
     - win64-aarch64-devedition-nightly/opt
     - linux64-asan-reporter-nightly/opt
     - win64-asan-reporter-nightly/opt
 
 job-template:
     attributes:
         artifact_map: taskcluster/taskgraph/manifests/fennec_geckoview.yml
-        artifact_prefix: public/build/maven
     run-on-projects: ['mozilla-central', 'mozilla-release']
     run-on-hg-branches:
         by-project:
             mozilla-release:
                 - '^GECKOVIEW_\d+_RELBRANCH$'
             default:
                 - '.*'
     shipping-phase:
--- a/taskcluster/ci/build/android.yml
+++ b/taskcluster/ci/build/android.yml
@@ -1,13 +1,15 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # 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/.
 ---
 job-defaults:
+    attributes:
+        artifact_map: taskcluster/taskgraph/manifests/fennec_geckoview.yml
     index:
         product: mobile
     worker:
         docker-image: {in-tree: android-build}
         max-run-time: 7200
         env:
             GRADLE_USER_HOME: "/builds/worker/workspace/build/src/mobile/android/gradle/dotgradle-offline"
         artifacts:
--- a/taskcluster/taskgraph/manifests/fennec_geckoview.yml
+++ b/taskcluster/taskgraph/manifests/fennec_geckoview.yml
@@ -3,71 +3,101 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 ---
 s3_bucket_paths:
     - maven2
 default_locales:  # Ignored for geckoview
     - en-US
 tasktype_map:  # Map task reference to task type.
     build: build
-base_artifact_prefix: public/build/maven/
+    build-signing: signing
 
 # A default entry, which the mappings below extend and override.
 # Final 'destinations' will be the product of:
 # s3_bucket_paths + destinations + locale_prefix + pretty_name
 default: &default
-    from:
-        - build
     locale_prefix: ''
-    source_path_modifier: org/mozilla/geckoview/${artifact_id}/${major_version}.${minor_version}.${build_date}
+    source_path_modifier: maven/org/mozilla/geckoview/${artifact_id}/${major_version}.${minor_version}.${build_date}
     description: "TO_BE_OVERRIDDEN"
     destinations:  # locale_prefix is appended
         - org/mozilla/geckoview/${artifact_id}/${major_version}.${minor_version}.${build_date}
 
 mapping:
-    ${artifact_id}-${major_version}.${minor_version}.${build_date}.pom.sha1:
-        <<: *default
-        pretty_name: ${artifact_id}-${major_version}.${minor_version}.${build_date}.pom.sha1
-        checksums_path: ${artifact_id}-${major_version}.${minor_version}.${build_date}.pom.sha1
-    ${artifact_id}-${major_version}.${minor_version}.${build_date}-javadoc.jar.md5:
+    ${artifact_id}-${major_version}.${minor_version}.${build_date}.aar:
         <<: *default
-        pretty_name: ${artifact_id}-${major_version}.${minor_version}.${build_date}-javadoc.jar.md5
-        checksums_path: ${artifact_id}-${major_version}.${minor_version}.${build_date}-javadoc.jar.md5
-    ${artifact_id}-${major_version}.${minor_version}.${build_date}.aar.sha1:
+        from: ['build']
+        pretty_name: ${artifact_id}-${major_version}.${minor_version}.${build_date}.aar
+        checksums_path: ${artifact_id}-${major_version}.${minor_version}.${build_date}.aar
+    ${artifact_id}-${major_version}.${minor_version}.${build_date}.aar.asc:
         <<: *default
-        pretty_name: ${artifact_id}-${major_version}.${minor_version}.${build_date}.aar.sha1
-        checksums_path: ${artifact_id}-${major_version}.${minor_version}.${build_date}.aar.sha1
+        from: ['build-signing']
+        pretty_name: ${artifact_id}-${major_version}.${minor_version}.${build_date}.aar.asc
+        checksums_path: ${artifact_id}-${major_version}.${minor_version}.${build_date}.aar.asc
     ${artifact_id}-${major_version}.${minor_version}.${build_date}.aar.md5:
         <<: *default
+        from: ['build']
         pretty_name: ${artifact_id}-${major_version}.${minor_version}.${build_date}.aar.md5
         checksums_path: ${artifact_id}-${major_version}.${minor_version}.${build_date}.aar.md5
-    ${artifact_id}-${major_version}.${minor_version}.${build_date}-sources.jar.sha1:
+    ${artifact_id}-${major_version}.${minor_version}.${build_date}.aar.sha1:
+        <<: *default
+        from: ['build']
+        pretty_name: ${artifact_id}-${major_version}.${minor_version}.${build_date}.aar.sha1
+        checksums_path: ${artifact_id}-${major_version}.${minor_version}.${build_date}.aar.sha1
+    ${artifact_id}-${major_version}.${minor_version}.${build_date}.pom:
         <<: *default
-        pretty_name: ${artifact_id}-${major_version}.${minor_version}.${build_date}-sources.jar.sha1
-        checksums_path: ${artifact_id}-${major_version}.${minor_version}.${build_date}-sources.jar.sha1
-    ${artifact_id}-${major_version}.${minor_version}.${build_date}-javadoc.jar:
+        from: ['build']
+        pretty_name: ${artifact_id}-${major_version}.${minor_version}.${build_date}.pom
+        checksums_path: ${artifact_id}-${major_version}.${minor_version}.${build_date}.pom
+    ${artifact_id}-${major_version}.${minor_version}.${build_date}.pom.asc:
         <<: *default
-        pretty_name: ${artifact_id}-${major_version}.${minor_version}.${build_date}-javadoc.jar
-        checksums_path: ${artifact_id}-${major_version}.${minor_version}.${build_date}-javadoc.jar
+        from: ['build-signing']
+        pretty_name: ${artifact_id}-${major_version}.${minor_version}.${build_date}.pom.asc
+        checksums_path: ${artifact_id}-${major_version}.${minor_version}.${build_date}.pom.asc
     ${artifact_id}-${major_version}.${minor_version}.${build_date}.pom.md5:
         <<: *default
+        from: ['build']
         pretty_name: ${artifact_id}-${major_version}.${minor_version}.${build_date}.pom.md5
         checksums_path: ${artifact_id}-${major_version}.${minor_version}.${build_date}.pom.md5
-    ${artifact_id}-${major_version}.${minor_version}.${build_date}.pom:
+    ${artifact_id}-${major_version}.${minor_version}.${build_date}.pom.sha1:
         <<: *default
-        pretty_name: ${artifact_id}-${major_version}.${minor_version}.${build_date}.pom
-        checksums_path: ${artifact_id}-${major_version}.${minor_version}.${build_date}.pom
-    ${artifact_id}-${major_version}.${minor_version}.${build_date}.aar:
+        from: ['build']
+        pretty_name: ${artifact_id}-${major_version}.${minor_version}.${build_date}.pom.sha1
+        checksums_path: ${artifact_id}-${major_version}.${minor_version}.${build_date}.pom.sha1
+    ${artifact_id}-${major_version}.${minor_version}.${build_date}-javadoc.jar:
         <<: *default
-        pretty_name: ${artifact_id}-${major_version}.${minor_version}.${build_date}.aar
-        checksums_path: ${artifact_id}-${major_version}.${minor_version}.${build_date}.aar
-    ${artifact_id}-${major_version}.${minor_version}.${build_date}-sources.jar.md5:
+        from: ['build']
+        pretty_name: ${artifact_id}-${major_version}.${minor_version}.${build_date}-javadoc.jar
+        checksums_path: ${artifact_id}-${major_version}.${minor_version}.${build_date}-javadoc.jar
+    ${artifact_id}-${major_version}.${minor_version}.${build_date}-javadoc.jar.asc:
         <<: *default
-        pretty_name: ${artifact_id}-${major_version}.${minor_version}.${build_date}-sources.jar.md5
-        checksums_path: ${artifact_id}-${major_version}.${minor_version}.${build_date}-sources.jar.md5
+        from: ['build-signing']
+        pretty_name: ${artifact_id}-${major_version}.${minor_version}.${build_date}-javadoc.jar.asc
+        checksums_path: ${artifact_id}-${major_version}.${minor_version}.${build_date}-javadoc.jar.asc
+    ${artifact_id}-${major_version}.${minor_version}.${build_date}-javadoc.jar.md5:
+        <<: *default
+        from: ['build']
+        pretty_name: ${artifact_id}-${major_version}.${minor_version}.${build_date}-javadoc.jar.md5
+        checksums_path: ${artifact_id}-${major_version}.${minor_version}.${build_date}-javadoc.jar.md5
     ${artifact_id}-${major_version}.${minor_version}.${build_date}-javadoc.jar.sha1:
         <<: *default
+        from: ['build']
         pretty_name: ${artifact_id}-${major_version}.${minor_version}.${build_date}-javadoc.jar.sha1
         checksums_path: ${artifact_id}-${major_version}.${minor_version}.${build_date}-javadoc.jar.sha1
     ${artifact_id}-${major_version}.${minor_version}.${build_date}-sources.jar:
         <<: *default
+        from: ['build']
         pretty_name: ${artifact_id}-${major_version}.${minor_version}.${build_date}-sources.jar
         checksums_path: ${artifact_id}-${major_version}.${minor_version}.${build_date}-sources.jar
+    ${artifact_id}-${major_version}.${minor_version}.${build_date}-sources.jar.asc:
+        <<: *default
+        from: ['build-signing']
+        pretty_name: ${artifact_id}-${major_version}.${minor_version}.${build_date}-sources.jar.asc
+        checksums_path: ${artifact_id}-${major_version}.${minor_version}.${build_date}-sources.jar.asc
+    ${artifact_id}-${major_version}.${minor_version}.${build_date}-sources.jar.md5:
+        <<: *default
+        from: ['build']
+        pretty_name: ${artifact_id}-${major_version}.${minor_version}.${build_date}-sources.jar.md5
+        checksums_path: ${artifact_id}-${major_version}.${minor_version}.${build_date}-sources.jar.md5
+    ${artifact_id}-${major_version}.${minor_version}.${build_date}-sources.jar.sha1:
+        <<: *default
+        from: ['build']
+        pretty_name: ${artifact_id}-${major_version}.${minor_version}.${build_date}-sources.jar.sha1
+        checksums_path: ${artifact_id}-${major_version}.${minor_version}.${build_date}-sources.jar.sha1
--- a/taskcluster/taskgraph/transforms/beetmover_geckoview.py
+++ b/taskcluster/taskgraph/transforms/beetmover_geckoview.py
@@ -2,47 +2,35 @@
 # 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/.
 """
 Transform the beetmover task into an actual task description.
 """
 
 from __future__ import absolute_import, print_function, unicode_literals
 
-import re
+from copy import deepcopy
 
 from taskgraph.loader.single_dep import schema
 from taskgraph.transforms.base import TransformSequence
 from taskgraph.transforms.beetmover import \
     craft_release_properties as beetmover_craft_release_properties
 from taskgraph.util.attributes import copy_attributes_from_dependent_job
+from taskgraph.util.declarative_artifacts import (
+    get_geckoview_template_vars,
+    get_geckoview_upstream_artifacts,
+    get_geckoview_artifact_id,
+)
 from taskgraph.util.schema import resolve_keyed_by, optionally_keyed_by
 from taskgraph.util.scriptworker import (generate_beetmover_artifact_map,
-                                         generate_beetmover_upstream_artifacts,
                                          get_worker_type_for_scope)
 from taskgraph.transforms.task import task_description_schema
 from voluptuous import Required, Optional
 
 
-_ARTIFACT_ID_PER_PLATFORM = {
-    'android-aarch64': 'geckoview{update_channel}-arm64-v8a',
-    'android-api-16': 'geckoview{update_channel}-armeabi-v7a',
-    'android-x86': 'geckoview{update_channel}-x86',
-    'android-x86_64': 'geckoview{update_channel}-x86_64',
-    'android-geckoview-fat-aar': 'geckoview{update_channel}',
-}
-
-_MOZ_UPDATE_CHANNEL_PER_BRANCH = {
-    'mozilla-release': '',
-    'mozilla-beta': '-beta',
-    'mozilla-central': '-nightly',
-    'try': '-nightly-try',
-    'maple': '-nightly-maple',
-}
-
 beetmover_description_schema = schema.extend({
     Required('depname', default='build'): basestring,
     Optional('label'): basestring,
     Optional('treeherder'): task_description_schema['treeherder'],
 
     Required('run-on-projects'): task_description_schema['run-on-projects'],
     Required('run-on-hg-branches'): task_description_schema['run-on-hg-branches'],
 
@@ -92,17 +80,18 @@ def make_task_description(config, jobs):
         description = (
             "Beetmover submission for geckoview"
             "{build_platform}/{build_type}'".format(
                 build_platform=attributes.get('build_platform'),
                 build_type=attributes.get('build_type')
             )
         )
 
-        dependencies = {dep_job.kind: dep_job.label}
+        dependencies = deepcopy(dep_job.dependencies)
+        dependencies[dep_job.kind] = dep_job.label
 
         attributes = copy_attributes_from_dependent_job(dep_job)
         attributes.update(job.get('attributes', {}))
 
         if job.get('locale'):
             attributes['locale'] = job['locale']
 
         attributes['run_on_hg_branches'] = job['run-on-hg-branches']
@@ -120,59 +109,40 @@ def make_task_description(config, jobs):
         }
 
         yield task
 
 
 @transforms.add
 def make_task_worker(config, jobs):
     for job in jobs:
-        valid_beetmover_job = len(job['dependencies']) == 1 and 'build' in job['dependencies']
+        valid_beetmover_job = set(job['dependencies'].keys()) == {'build', 'build-signing'}
         if not valid_beetmover_job:
             raise NotImplementedError(
-                'Beetmover-geckoview must have a single dependency. Got: {}'.format(
+                'Beetmover-geckoview must have 2 dependencies: build and build-signing. '
+                'Got: {}'.format(
                     job['dependencies']
                 )
             )
 
-        worker = {
+        job['worker'] = {
+            'artifact-map': generate_beetmover_artifact_map(
+                config,
+                job,
+                **get_geckoview_template_vars(config, job['attributes']['build_platform'])
+            ),
             'implementation': 'beetmover-maven',
             'release-properties': craft_release_properties(config, job),
-        }
-
-        version_groups = re.match(r'(\d+).(\d+).*', config.params['version'])
-        if version_groups:
-            major_version, minor_version = version_groups.groups()
-
-        template_vars = {
-            'artifact_id': worker['release-properties']['artifact-id'],
-            'build_date': config.params['moz_build_date'],
-            'major_version': major_version,
-            'minor_version': minor_version,
+            'upstream-artifacts': get_geckoview_upstream_artifacts(config, job),
         }
-        worker['artifact-map'] = generate_beetmover_artifact_map(
-            config, job, **template_vars
-        )
-        upstream_artifacts = generate_beetmover_upstream_artifacts(
-            config, job, platform='', **template_vars
-        )
-        worker['upstream-artifacts'] = [{
-            key: value for key, value in upstream_artifact.items()
-            if key != 'locale'
-        } for upstream_artifact in upstream_artifacts]
-
-        job["worker"] = worker
 
         yield job
 
 
 def craft_release_properties(config, job):
-    props = beetmover_craft_release_properties(config, job)
+    release_properties = beetmover_craft_release_properties(config, job)
 
-    platform = props['platform']
-    update_channel = _MOZ_UPDATE_CHANNEL_PER_BRANCH.get(
-        props['branch'], '-UNKNOWN_MOZ_UPDATE_CHANNEL'
+    release_properties['artifact-id'] = get_geckoview_artifact_id(
+        job['attributes']['build_platform'], release_properties['branch']
     )
-    artifact_id = _ARTIFACT_ID_PER_PLATFORM[platform].format(update_channel=update_channel)
-    props['artifact-id'] = artifact_id
-    props['app-name'] = 'geckoview'     # this beetmover job is not about pushing Fennec
+    release_properties['app-name'] = 'geckoview'
 
-    return props
+    return release_properties
--- a/taskcluster/taskgraph/transforms/build_signing.py
+++ b/taskcluster/taskgraph/transforms/build_signing.py
@@ -3,16 +3,17 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 """
 Transform the signing task into an actual task description.
 """
 
 from __future__ import absolute_import, print_function, unicode_literals
 
 from taskgraph.transforms.base import TransformSequence
+from taskgraph.util.attributes import copy_attributes_from_dependent_job
 from taskgraph.util.signed_artifacts import generate_specifications_of_artifacts_to_sign
 from taskgraph.util.taskcluster import get_artifact_path
 
 
 transforms = TransformSequence()
 
 
 @transforms.add
@@ -45,18 +46,21 @@ def add_signed_routes(config, jobs):
 
 
 @transforms.add
 def define_upstream_artifacts(config, jobs):
     for job in jobs:
         dep_job = job['primary-dependency']
         build_platform = dep_job.attributes.get('build_platform')
 
+        job['attributes'] = copy_attributes_from_dependent_job(dep_job)
+
         artifacts_specifications = generate_specifications_of_artifacts_to_sign(
-            dep_job,
+            config,
+            job,
             keep_locale_template=False,
             kind=config.kind,
         )
 
         if 'android' in build_platform:
             # We're in the job that creates both multilocale and en-US APKs
             artifacts_specifications[0]['artifacts'].append(
                 get_artifact_path(dep_job, 'en-US/target.apk')
--- a/taskcluster/taskgraph/transforms/nightly_l10n_signing.py
+++ b/taskcluster/taskgraph/transforms/nightly_l10n_signing.py
@@ -3,16 +3,17 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 """
 Transform the signing task into an actual task description.
 """
 
 from __future__ import absolute_import, print_function, unicode_literals
 
 from taskgraph.transforms.base import TransformSequence
+from taskgraph.util.attributes import copy_attributes_from_dependent_job
 from taskgraph.util.signed_artifacts import generate_specifications_of_artifacts_to_sign
 from taskgraph.util.treeherder import join_symbol
 
 transforms = TransformSequence()
 
 
 @transforms.add
 def make_signing_description(config, jobs):
@@ -32,18 +33,21 @@ def make_signing_description(config, job
         yield job
 
 
 @transforms.add
 def define_upstream_artifacts(config, jobs):
     for job in jobs:
         dep_job = job['primary-dependency']
 
+        job['attributes'] = copy_attributes_from_dependent_job(dep_job)
+
         locale_specifications = generate_specifications_of_artifacts_to_sign(
-            dep_job,
+            config,
+            job,
             keep_locale_template=True,
         )
 
         upstream_artifacts = []
         for spec in locale_specifications:
             upstream_artifacts.append({
                 'taskId': {'task-reference': '<unsigned-repack>'},
                 'taskType': 'l10n',
--- a/taskcluster/taskgraph/transforms/partner_signing.py
+++ b/taskcluster/taskgraph/transforms/partner_signing.py
@@ -21,16 +21,17 @@ def define_upstream_artifacts(config, jo
     partner_configs = get_partner_config_by_kind(config, config.kind)
     if not partner_configs:
         return
 
     for job in jobs:
         dep_job = job['primary-dependency']
         repack_id = job['extra']['repack_id']
         artifacts_specifications = generate_specifications_of_artifacts_to_sign(
+            config,
             dep_job,
             keep_locale_template=True,
             kind=config.kind,
         )
         job['upstream-artifacts'] = [{
             'taskId': {'task-reference': '<{}>'.format(job['depname'])},
             'taskType': 'build',
             'paths': [
--- a/taskcluster/taskgraph/transforms/signing.py
+++ b/taskcluster/taskgraph/transforms/signing.py
@@ -37,16 +37,19 @@ signing_description_schema = schema.exte
 
         # Signing formats to use on each of the paths
         Required('formats'): [basestring],
     }],
 
     # depname is used in taskref's to identify the taskID of the unsigned things
     Required('depname'): basestring,
 
+    # attributes for this task
+    Optional('attributes'): {basestring: object},
+
     # unique label to describe this signing task, defaults to {dep.label}-signing
     Optional('label'): basestring,
 
     # treeherder is allowed here to override any defaults we use for signing.  See
     # taskcluster/taskgraph/transforms/task.py for the schema details, and the
     # below transforms for defaults of various values.
     Optional('treeherder'): task_description_schema['treeherder'],
 
@@ -132,17 +135,18 @@ def make_task_description(config, jobs):
             "Initial Signing for locale '{locale}' for build '"
             "{build_platform}/{build_type}'".format(
                 locale=attributes.get('locale', 'en-US'),
                 build_platform=build_platform,
                 build_type=attributes.get('build_type')
             )
         )
 
-        attributes = copy_attributes_from_dependent_job(dep_job)
+        attributes = job['attributes'] if job.get('attributes') else \
+            copy_attributes_from_dependent_job(dep_job)
         attributes['signed'] = True
 
         if dep_job.attributes.get('chunk_locales'):
             # Used for l10n attribute passthrough
             attributes['chunk_locales'] = dep_job.attributes.get('chunk_locales')
 
         signing_cert_scope = get_signing_cert_scope_per_platform(
             build_platform, is_nightly, config
--- a/taskcluster/taskgraph/util/attributes.py
+++ b/taskcluster/taskgraph/util/attributes.py
@@ -30,16 +30,17 @@ RELEASE_PROJECTS = {
 RELEASE_PROMOTION_PROJECTS = {
     'jamun',
     'maple',
     'try',
     'try-comm-central',
 } | RELEASE_PROJECTS
 
 _OPTIONAL_ATTRIBUTES = (
+    'artifact_map',
     'artifact_prefix',
     'l10n_chunk',
     'locale',
     'nightly',
     'required_signoffs',
     'signed',
     'shipping_phase',
     'shipping_product',
new file mode 100644
--- /dev/null
+++ b/taskcluster/taskgraph/util/declarative_artifacts.py
@@ -0,0 +1,51 @@
+from __future__ import absolute_import, unicode_literals
+
+import re
+
+from taskgraph.util.scriptworker import generate_beetmover_upstream_artifacts
+
+
+_ARTIFACT_ID_PER_PLATFORM = {
+    'android-aarch64-nightly': 'geckoview{update_channel}-arm64-v8a',
+    'android-api-16-nightly': 'geckoview{update_channel}-armeabi-v7a',
+    'android-x86-nightly': 'geckoview{update_channel}-x86',
+    'android-x86_64-nightly': 'geckoview{update_channel}-x86_64',
+    'android-geckoview-fat-aar-nightly': 'geckoview{update_channel}',
+}
+
+_MOZ_UPDATE_CHANNEL_PER_PROJECT = {
+    'mozilla-release': '',
+    'mozilla-beta': '-beta',
+    'mozilla-central': '-nightly',
+    'try': '-nightly-try',
+    'maple': '-nightly-maple',
+}
+
+
+def get_geckoview_upstream_artifacts(config, job):
+    upstream_artifacts = generate_beetmover_upstream_artifacts(
+        config, job, platform='',
+        **get_geckoview_template_vars(config, job['attributes']['build_platform'])
+    )
+    return [{
+        key: value for key, value in upstream_artifact.items()
+        if key != 'locale'
+    } for upstream_artifact in upstream_artifacts]
+
+
+def get_geckoview_template_vars(config, platform):
+    version_groups = re.match(r'(\d+).(\d+).*', config.params['version'])
+    if version_groups:
+        major_version, minor_version = version_groups.groups()
+
+    return {
+        'artifact_id': get_geckoview_artifact_id(platform, config.params['project']),
+        'build_date': config.params['moz_build_date'],
+        'major_version': major_version,
+        'minor_version': minor_version,
+    }
+
+
+def get_geckoview_artifact_id(platform, project):
+    update_channel = _MOZ_UPDATE_CHANNEL_PER_PROJECT.get(project, '-UNKNOWN_MOZ_UPDATE_CHANNEL')
+    return _ARTIFACT_ID_PER_PLATFORM[platform].format(update_channel=update_channel)
--- a/taskcluster/taskgraph/util/scriptworker.py
+++ b/taskcluster/taskgraph/util/scriptworker.py
@@ -440,17 +440,22 @@ def generate_beetmover_upstream_artifact
     if not locale:
         locales = map_config['default_locales']
     elif isinstance(locale, list):
         locales = locale
     else:
         locales = [locale]
 
     if not dependencies:
-        dependencies = job['dependencies'].keys()
+        if job.get('dependencies'):
+            dependencies = job['dependencies'].keys()
+        elif job.get('primary-dependency'):
+            dependencies = [job['primary-dependency'].kind]
+        else:
+            raise Exception('Unsupported type of dependency. Got job: {}'.format(job))
 
     for locale, dep in itertools.product(locales, dependencies):
         paths = list()
 
         for filename in map_config['mapping']:
             if dep not in map_config['mapping'][filename]['from']:
                 continue
             if locale != 'en-US' and not map_config['mapping'][filename]['all_locales']:
@@ -471,20 +476,24 @@ def generate_beetmover_upstream_artifact
             kwargs['locale'] = locale
 
             paths.append(os.path.join(
                 base_artifact_prefix,
                 jsone.render(file_config['source_path_modifier'], kwargs),
                 jsone.render(filename, kwargs),
             ))
 
-        if getattr(job['dependencies'][dep], 'release_artifacts', None):
+        if (
+            job.get('dependencies') and
+            getattr(job['dependencies'][dep], 'release_artifacts', None)
+        ):
             paths = [
                 path for path in paths
-                if path in job['dependencies'][dep].release_artifacts]
+                if path in job['dependencies'][dep].release_artifacts
+            ]
 
         if not paths:
             continue
 
         upstream_artifacts.append({
             "taskId": {
                 "task-reference": "<{}>".format(dep)
             },
--- a/taskcluster/taskgraph/util/signed_artifacts.py
+++ b/taskcluster/taskgraph/util/signed_artifacts.py
@@ -2,73 +2,77 @@
 # 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/.
 """
 Defines artifacts to sign before repackage.
 """
 
 from __future__ import absolute_import, print_function, unicode_literals
 from taskgraph.util.taskcluster import get_artifact_path
+from taskgraph.util.declarative_artifacts import get_geckoview_upstream_artifacts
 
 
 def is_partner_kind(kind):
     if kind and kind.startswith(('release-partner', 'release-eme-free')):
         return True
 
 
 def generate_specifications_of_artifacts_to_sign(
-    task, keep_locale_template=True, kind=None
+    config, job, keep_locale_template=True, kind=None
 ):
-    build_platform = task.attributes.get('build_platform')
-    use_stub = task.attributes.get('stub-installer')
+    build_platform = job['attributes'].get('build_platform')
+    use_stub = job['attributes'].get('stub-installer')
     if kind == 'release-source-signing':
         artifacts_specifications = [{
             'artifacts': [
-                get_artifact_path(task, 'source.tar.xz')
+                get_artifact_path(job, 'source.tar.xz')
             ],
             'formats': ['autograph_gpg'],
         }]
     elif 'android' in build_platform:
         artifacts_specifications = [{
             'artifacts': [
-                get_artifact_path(task, '{locale}/target.apk'),
+                get_artifact_path(job, '{locale}/target.apk'),
             ],
             'formats': ['autograph_apk_fennec_sha1'],
+        }, {
+            'artifacts': get_geckoview_artifacts_to_sign(config, job),
+            'formats': ['autograph_gpg'],
         }]
     # XXX: Mars aren't signed here (on any platform) because internals will be
     # signed at after this stage of the release
     elif 'macosx' in build_platform:
         if is_partner_kind(kind):
             extension = 'tar.gz'
         else:
             extension = 'dmg'
         artifacts_specifications = [{
-            'artifacts': [get_artifact_path(task, '{{locale}}/target.{}'.format(extension))],
+            'artifacts': [get_artifact_path(job, '{{locale}}/target.{}'.format(extension))],
             'formats': ['macapp', 'autograph_widevine', 'autograph_omnija'],
         }]
     elif 'win' in build_platform:
         artifacts_specifications = [{
             'artifacts': [
-                get_artifact_path(task, '{locale}/setup.exe'),
+                get_artifact_path(job, '{locale}/setup.exe'),
             ],
             'formats': ['sha2signcode'],
         }, {
             'artifacts': [
-                get_artifact_path(task, '{locale}/target.zip'),
+                get_artifact_path(job, '{locale}/target.zip'),
             ],
             'formats': ['sha2signcode', 'autograph_widevine', 'autograph_omnija'],
         }]
 
         if use_stub:
             artifacts_specifications[0]['artifacts'] += [
-                get_artifact_path(task, '{locale}/setup-stub.exe')
+                get_artifact_path(job, '{locale}/setup-stub.exe')
             ]
     elif 'linux' in build_platform:
         artifacts_specifications = [{
-            'artifacts': [get_artifact_path(task, '{locale}/target.tar.bz2')],
+            'artifacts': [get_artifact_path(job, '{locale}/target.tar.bz2')],
             'formats': ['autograph_gpg', 'autograph_widevine', 'autograph_omnija'],
         }]
     else:
         raise Exception("Platform not implemented for signing")
 
     if not keep_locale_template:
         artifacts_specifications = _strip_locale_template(artifacts_specifications)
 
@@ -112,8 +116,18 @@ def get_signed_artifacts(input, formats,
         if behavior and behavior != "mac_sign":
             artifacts.add(input.replace('.dmg', '.pkg'))
     else:
         artifacts.add(input)
     if 'autograph_gpg' in formats:
         artifacts.add('{}.asc'.format(input))
 
     return artifacts
+
+
+def get_geckoview_artifacts_to_sign(config, job):
+    upstream_artifacts = get_geckoview_upstream_artifacts(config, job)
+    return [
+        path
+        for upstream_artifact in upstream_artifacts
+        for path in upstream_artifact['paths']
+        if not path.endswith('.md5') and not path.endswith('.sha1')
+    ]