Bug 1548864 - part 10: Use release-type attributes r=Callek a=release
authorTom Prince <mozilla@hocat.ca>
Mon, 20 May 2019 16:38:09 +0200
changeset 533356 9196b576f69a07fb670394ce81f3e1f0b5965b9d
parent 533355 ec804fef742ef89cce39b2443812523f017bdeeb
child 533357 c6efa45fbc6946d76841fdf4c9605e45171e6b3b
push id11299
push userjlorenzo@mozilla.com
push dateFri, 24 May 2019 04:06:52 +0000
treeherdermozilla-beta@1f2cf02d4beb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersCallek, release
bugs1548864
milestone68.0
Bug 1548864 - part 10: Use release-type attributes r=Callek a=release Differential Revision: https://phabricator.services.mozilla.com/D32315
taskcluster/ci/build/android.yml
taskcluster/ci/google-play-strings/kind.yml
taskcluster/ci/push-apk-checks/kind.yml
taskcluster/ci/push-apk/kind.yml
taskcluster/ci/release-bouncer-aliases/kind.yml
taskcluster/ci/release-bouncer-sub/kind.yml
taskcluster/ci/release-generate-checksums/kind.yml
taskcluster/ci/release-mark-as-shipped/kind.yml
taskcluster/ci/release-notify-promote/kind.yml
taskcluster/ci/release-notify-ship/kind.yml
taskcluster/ci/release-notify-started/kind.yml
taskcluster/ci/release-source/kind.yml
taskcluster/docs/attributes.rst
taskcluster/taskgraph/loader/push_apk.py
taskcluster/taskgraph/manifests/source_checksums.yml
taskcluster/taskgraph/manifests/source_files.yml
taskcluster/taskgraph/target_tasks.py
taskcluster/taskgraph/transforms/per_platform_dummy.py
taskcluster/taskgraph/transforms/release_deps.py
taskcluster/taskgraph/transforms/upload_generated_sources.py
taskcluster/taskgraph/transforms/upload_symbols.py
taskcluster/taskgraph/util/attributes.py
--- a/taskcluster/ci/build/android.yml
+++ b/taskcluster/ci/build/android.yml
@@ -160,16 +160,17 @@ android-x86-fuzzing/debug:
     toolchains:
         - linux64-sccache
 
 android-x86-nightly/opt:
     description: "Android 4.2 x86 Nightly"
     attributes:
         enable-full-crashsymbols: true
         nightly: true
+        release-type: nightly
     shipping-phase: build
     shipping-product: fennec
     index:
         job-name: android-x86-opt
         type: android-nightly
     treeherder:
         platform: android-4-2-x86/opt
         symbol: N
@@ -185,16 +186,17 @@ android-x86-nightly/opt:
         custom-build-variant-cfg: x86
         update-channel: nightly
 
 android-x86-beta/opt:
     description: "Android 4.2 x86 Beta"
     attributes:
         nightly: true
         enable-full-crashsymbols: true
+        release-type: beta
     shipping-phase: build
     shipping-product: fennec
     index:
         job-name: android-x86-beta-opt
         type: android-nightly
     treeherder:
         platform: android-4-2-x86-beta/opt
         symbol: N
@@ -274,16 +276,17 @@ android-api-16-without-google-play-servi
         - linux64-sccache
 
 android-api-16-nightly/opt:
     description: "Android 4.0 api-16+ Nightly"
     use-pgo: android-api-16/pgo
     attributes:
         enable-full-crashsymbols: true
         nightly: true
+        release-type: nightly
     shipping-phase: build
     shipping-product: fennec
     index:
         job-name: android-api-16-opt
         type: android-nightly-with-multi-l10n
     treeherder:
         platform: android-4-0-armv7-api16/opt
         symbol: N
@@ -300,16 +303,17 @@ android-api-16-nightly/opt:
         update-channel: nightly
 
 android-api-16-beta/opt:
     description: "Android 4.0 api-16+ Beta"
     use-pgo: android-api-16/pgo
     attributes:
         nightly: true
         enable-full-crashsymbols: true
+        release-type: beta
     shipping-phase: build
     shipping-product: fennec
     index:
         job-name: android-api-16-beta-opt
         type: android-nightly-with-multi-l10n
     treeherder:
         platform: android-4-0-armv7-api16-beta/opt
         symbol: N
@@ -412,16 +416,17 @@ android-aarch64-beta/debug:
         - linux64-sccache
 
 android-aarch64-nightly/opt:
     description: "Android 5.0 AArch64 Nightly"
     use-pgo: android-api-16/pgo
     attributes:
         enable-full-crashsymbols: true
         nightly: true
+        release-type: nightly
     shipping-phase: build
     shipping-product: fennec
     index:
         job-name: android-aarch64-opt
         type: android-nightly
     treeherder:
         platform: android-5-0-aarch64/opt
         symbol: N
@@ -438,16 +443,17 @@ android-aarch64-nightly/opt:
         update-channel: nightly
 
 android-aarch64-beta/opt:
     description: "Android 5.0 AArch64 Beta"
     use-pgo: android-api-16-beta/pgo
     attributes:
         nightly: true
         enable-full-crashsymbols: true
+        release-type: beta
     shipping-phase: build
     shipping-product: fennec
     index:
         job-name: android-aarch64-beta-opt
         type: android-nightly
     treeherder:
         platform: android-5-0-aarch64-beta/opt
         symbol: N
@@ -487,16 +493,17 @@ android-x86_64/opt:
     toolchains:
         - linux64-sccache
 
 android-x86_64-nightly/opt:
     description: "Android 5.0 x86-64 Nightly"
     attributes:
         enable-full-crashsymbols: true
         nightly: true
+        release-type: nightly
     shipping-phase: build
     shipping-product: fennec
     index:
         job-name: android-x86_64-opt
         type: android-nightly
     treeherder:
         platform: android-5-0-x86_64/opt
         symbol: N
@@ -512,16 +519,17 @@ android-x86_64-nightly/opt:
         custom-build-variant-cfg: x86_64
         update-channel: nightly
 
 android-x86_64-beta/opt:
     description: "Android 5.0 x86-64 Beta"
     attributes:
         nightly: true
         enable-full-crashsymbols: true
+        release-type: beta
     shipping-phase: build
     shipping-product: fennec
     index:
         job-name: android-x86_64-beta-opt
         type: android-nightly
     treeherder:
         platform: android-5-0-x86_64-beta/opt
         symbol: N
--- a/taskcluster/ci/google-play-strings/kind.yml
+++ b/taskcluster/ci/google-play-strings/kind.yml
@@ -41,22 +41,22 @@ job-defaults:
         platform: Android/opt
         tier: 2
         kind: other
     run-on-projects: ['try', 'mozilla-central', 'mozilla-beta', 'mozilla-release']
 
 jobs:
     google-play-strings-nightly:
         attributes:
-            build_platform: android-nightly
+            release-type: nightly
         worker:
             env:
                 PACKAGE_NAME: org.mozilla.fennec_aurora
         treeherder:
             symbol: pub(gps-n)
     google-play-strings-beta:
         attributes:
-            build_platform: android-beta
+            release-type: beta
         worker:
             env:
                 PACKAGE_NAME: org.mozilla.firefox_beta
         treeherder:
             symbol: pub(gps-b)
--- a/taskcluster/ci/push-apk-checks/kind.yml
+++ b/taskcluster/ci/push-apk-checks/kind.yml
@@ -28,20 +28,20 @@ job-defaults:
         tier: 1
         kind: test
     run-on-projects: ['try', 'mozilla-central', 'mozilla-beta', 'mozilla-release']
 
 jobs:
     push-apk-checks-nightly/opt:
         description: Verify Nightly APKs are sane before uploading them onto Google Play Store
         attributes:
-            build_platform: android-nightly
+            release-type: nightly
         package-name: org.mozilla.fennec_aurora
         treeherder:
             symbol: pub(gpc-n)
 
     push-apk-checks-beta/opt:
         description: Verify Beta APKs are sane before uploading them onto Google Play Store
         attributes:
-            build_platform: android-beta
+            release-type: beta
         package-name: org.mozilla.firefox_beta
         treeherder:
             symbol: pub(gpc-b)
--- a/taskcluster/ci/push-apk/kind.yml
+++ b/taskcluster/ci/push-apk/kind.yml
@@ -36,25 +36,25 @@ job-defaults:
         platform: Android/opt
         tier: 2
         kind: other
     run-on-projects: ['try', 'mozilla-central', 'mozilla-beta', 'mozilla-release']
 
 jobs:
     push-apk-nightly/opt:
         attributes:
-            build_platform: android-nightly
+            release-type: nightly
         worker:
             # XXX Temporarily ship Nightly to the alpha track while we ensure it's
             # correctly built of mozilla-beta
             # See also https://github.com/mozilla-releng/pushapkscript#aurora-beta-release-vs-alpha-beta-production
             google-play-track: alpha
         treeherder:
             symbol: pub(gp-n)
 
     push-apk-beta/opt:
         attributes:
-            build_platform: android-beta
+            release-type: beta
         worker:
             google-play-track: rollout
             rollout-percentage: 10
         treeherder:
             symbol: pub(gp-b)
--- a/taskcluster/ci/release-bouncer-aliases/kind.yml
+++ b/taskcluster/ci/release-bouncer-aliases/kind.yml
@@ -41,31 +41,24 @@ jobs:
             firefox-devedition-latest-ssl: installer-ssl
             firefox-devedition-latest: installer
             firefox-devedition-stub: stub-installer
             firefox-devedition-msi-latest-ssl: msi
         shipping-product: devedition
         treeherder:
             platform: devedition-release/opt
 
-    fennec:
+    fennec-beta:
         bouncer-products-per-alias:
-            by-project:
-                mozilla-beta:
-                    fennec-beta-latest: apk
-                mozilla-release:
-                    fennec-latest: apk
-                birch:
-                    fennec-latest: apk
-                maple:
-                    fennec-beta-latest: apk
-                default: {}
+            fennec-beta-latest: apk
         shipping-product: fennec
         treeherder:
             platform: fennec-release/opt
+        attributes:
+            release-type: beta
 
     firefox:
         bouncer-products-per-alias:
             by-project:
                 mozilla-beta:
                     firefox-beta-latest-ssl: installer-ssl
                     firefox-beta-latest: installer
                     firefox-beta-stub: stub-installer
--- a/taskcluster/ci/release-bouncer-sub/kind.yml
+++ b/taskcluster/ci/release-bouncer-sub/kind.yml
@@ -36,23 +36,25 @@ job-defaults:
 jobs:
     devedition:
         bouncer-platforms: ['linux', 'linux64', 'osx', 'win', 'win64', 'win64-aarch64']
         bouncer-products: ['complete-mar', 'installer', 'installer-ssl', 'partial-mar', 'stub-installer', 'msi']
         shipping-product: devedition
         treeherder:
             platform: devedition-release/opt
 
-    fennec:
+    fennec-beta:
         bouncer-platforms: ['android', 'android-x86']
         bouncer-products: ['apk']
         shipping-product: fennec
         locales-file: mobile/locales/l10n-changesets.json
         treeherder:
             platform: fennec-release/opt
+        attributes:
+            release-type: beta
 
     firefox:
         bouncer-platforms: ['linux', 'linux64', 'osx', 'win', 'win64', 'win64-aarch64']
         bouncer-products:
             by-project:
                 default: ['complete-mar', 'installer', 'installer-ssl', 'partial-mar', 'stub-installer', 'msi']
                 # No stub installer in esr60
                 mozilla-esr60: ['complete-mar', 'complete-mar-bz2', 'installer', 'installer-ssl', 'partial-mar']
--- a/taskcluster/ci/release-generate-checksums/kind.yml
+++ b/taskcluster/ci/release-generate-checksums/kind.yml
@@ -63,21 +63,22 @@ jobs:
                         stage_product: "firefox"
                         bucket_name: "net-mozaws-prod-delivery-firefox"
                     staging:
                         stage_product: "firefox"
                         bucket_name: "net-mozaws-stage-delivery-firefox"
         treeherder:
             platform: firefox-release/opt
 
-    fennec:
+    fennec-beta:
         shipping-product: fennec
         attributes:
             build_platform: fennec-release
             build_type: opt
+            release-type: beta
         run:
             extra-config:
                 by-release-level:
                     production:
                         stage_product: "mobile"
                         bucket_name: "net-mozaws-prod-delivery-archive"
                     staging:
                         stage_product: "mobile"
--- a/taskcluster/ci/release-mark-as-shipped/kind.yml
+++ b/taskcluster/ci/release-mark-as-shipped/kind.yml
@@ -30,19 +30,21 @@ job-defaults:
                 - project:releng:ship-it:action:mark-as-shipped
             staging:
                 - project:releng:ship-it:server:staging
                 - project:releng:ship-it:action:mark-as-shipped
     run-on-projects: []
     shipping-phase: ship
 
 jobs:
-    fennec:
-        name: release-fennec_mark_as_shipped
+    fennec-beta:
+        name: release-fennec-beta_mark_as_shipped
         shipping-product: fennec
+        attributes:
+            release-type: beta
 
     firefox:
         name: release-firefox_mark_as_shipped
         shipping-product: firefox
 
     devedition:
         name: release-devedition_mark_as_shipped
         shipping-product: devedition
--- a/taskcluster/ci/release-notify-promote/kind.yml
+++ b/taskcluster/ci/release-notify-promote/kind.yml
@@ -34,14 +34,16 @@ job-defaults:
         message: "{task[shipping-product]} {release_config[version]} build{release_config[build_number]}/{config[params][project]} is in the candidates directory"
         emails:
             by-project:
                 mozilla-(beta|release|esr.*): ["release-signoff@mozilla.org"]
                 try: ["{config[params][owner]}"]
                 default: []
 
 jobs:
-    fennec:
+    fennec-beta:
         shipping-product: fennec
+        attributes:
+            release-type: beta
     firefox:
         shipping-product: firefox
     devedition:
         shipping-product: devedition
--- a/taskcluster/ci/release-notify-ship/kind.yml
+++ b/taskcluster/ci/release-notify-ship/kind.yml
@@ -34,21 +34,23 @@ job-defaults:
     notifications:
         emails:
             by-project:
                 mozilla-(beta|release|esr.*): ["release-signoff@mozilla.org"]
                 try: ["{config[params][owner]}"]
                 default: []
 
 jobs:
-    fennec:
+    fennec-beta:
         shipping-product: fennec
         notifications:
             subject: "{task[shipping-product]} {release_config[version]} build{release_config[build_number]}/{config[params][project]} has shipped!"
             message: "{task[shipping-product]} {release_config[version]} build{release_config[build_number]}/{config[params][project]} has shipped!"
+        attributes:
+            release-type: beta
     firefox:
         shipping-product: firefox
         notifications:
             subject: "{task[shipping-product]} {release_config[version]} build{release_config[build_number]}/{config[params][project]} updates are ready for signoff in Balrog!"
             message: "{task[shipping-product]} {release_config[version]} build{release_config[build_number]}/{config[params][project]} updates are ready for signoff in Balrog!"
     devedition:
         shipping-product: devedition
         notifications:
--- a/taskcluster/ci/release-notify-started/kind.yml
+++ b/taskcluster/ci/release-notify-started/kind.yml
@@ -21,14 +21,16 @@ job-defaults:
         max-run-time: 600
     emails:
         by-project:
             mozilla-(beta|release|esr.*): ["release-signoff@mozilla.org"]
             try: ["{config[params][owner]}"]
             default: []
 
 jobs:
-    fennec:
+    fennec-beta:
         shipping-product: fennec
+        attributes:
+            release-type: beta
     firefox:
         shipping-product: firefox
     devedition:
         shipping-product: devedition
--- a/taskcluster/ci/release-source/kind.yml
+++ b/taskcluster/ci/release-source/kind.yml
@@ -15,16 +15,18 @@ transforms:
     - taskgraph.transforms.job:transforms
     - taskgraph.transforms.task:transforms
 
 
 job-defaults:
     shipping-phase: promote
     treeherder:
         symbol: Src
+    attributes:
+        shippable: true
     worker-type: b-linux
     worker:
         max-run-time: 3600
         env:
             TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/linux64/releng.manifest"
             PKG_SRCPACK_BASENAME: source
     run:
         using: mozharness
@@ -43,19 +45,21 @@ job-defaults:
 
 jobs:
     firefox-source/opt:
         description: "Firefox source builder"
         treeherder:
             platform: firefox-release/opt
         shipping-product: firefox
 
-    fennec-source/opt:
+    fennec-beta-source/opt:
         description: "Fennec source builder"
         treeherder:
             platform: fennec-release/opt
         shipping-product: fennec
+        attributes:
+            release-type: beta
 
     devedition-source/opt:
         description: "Devedition source builder"
         treeherder:
             platform: devedition-release/opt
         shipping-product: devedition
--- a/taskcluster/docs/attributes.rst
+++ b/taskcluster/docs/attributes.rst
@@ -300,8 +300,12 @@ code-review
 If a task set this boolean attribute to `true`, it will be processed by the code
 review bot, the task will ran for every new Phabricator diff.
 Any supported and detected issue will be automatically reported on the
 Phabricator revision.
 
 retrigger
 =========
 Whether the task can be retriggered, or if it needs to be re-run.
+
+release-type
+============
+Because we now ship Fennec Nightly off mozilla-beta, `release-type` defines whether the task is a Nightly or a Beta build.
--- a/taskcluster/taskgraph/loader/push_apk.py
+++ b/taskcluster/taskgraph/loader/push_apk.py
@@ -28,37 +28,25 @@ def loader(kind, path, config, params, l
 
 def get_dependent_loaded_tasks(config, params, loaded_tasks, job):
     nightly_tasks = (
         task for task in loaded_tasks if task.attributes.get('nightly')
     )
     tasks_with_matching_kind = (
         task for task in nightly_tasks if task.kind in config.get('kind-dependencies')
     )
-    android_tasks = (
+    tasks = (
         task for task in tasks_with_matching_kind
-        if task.attributes.get('build_platform', '').startswith('android')
+        if task.attributes.get('shipping_product') == 'fennec'
+        and task.attributes.get('release-type') == job['attributes']['release-type']
     )
 
-    if job['attributes']['build_platform'].endswith('-beta'):
-        tasks_with_right_release_type = (
-            task for task in android_tasks
-            if task.attributes.get('build_platform', '').endswith('-beta')
-        )
-    elif job['attributes']['build_platform'].endswith('-nightly'):
-        tasks_with_right_release_type = (
-            task for task in android_tasks
-            if task.attributes.get('build_platform', '').endswith('-nightly')
-        )
-    else:
-        return []
-
     # XXX Bug 1368484: Aarch64 is not planned to ride the trains regularly. It stayed on central
     # for a couple of cycles, and is planned to stay on mozilla-beta until 68.
     if params['project'] in ('mozilla-central', 'mozilla-beta', 'try'):
-        shipping_tasks = list(tasks_with_right_release_type)
+        shipping_tasks = list(tasks)
     else:
         shipping_tasks = [
-            task for task in tasks_with_right_release_type
+            task for task in tasks
             if 'aarch64' not in task.attributes.get('build_platform', '')
         ]
 
     return shipping_tasks
--- a/taskcluster/taskgraph/manifests/source_checksums.yml
+++ b/taskcluster/taskgraph/manifests/source_checksums.yml
@@ -1,15 +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/.
 ---
 s3_bucket_paths:
     by-platform:
-        fennec-source:
+        fennec-.*:
             - pub/mobile/candidates
         devedition-source:
             - pub/devedition/candidates
         firefox-source:
             - pub/firefox/candidates
 default_locales:  # if given an empty locale, use these locales
     - en-US
 tasktype_map:  # Map task reference to task type.
@@ -32,27 +32,27 @@ default: &default
 mapping:
     target-source.checksums:
         <<: *default
         description: "Checksums file for the source zip files"
         pretty_name:
             by-platform:
                 firefox-source: firefox-${version}.checksums.beet
                 devedition-source: firefox-${version}.checksums.beet
-                fennec-source: fennec-${version}.checksums.beet
+                fennec-.*: fennec-${version}.checksums.beet
         checksums_path:
             by-platform:
                 firefox-source: firefox-${version}.checksums.beet
                 devedition-source: firefox-${version}.checksums.beet
-                fennec-source: fennec-${version}.checksums.beet
+                fennec-.*: fennec-${version}.checksums.beet
     target-source.checksums.asc:
         <<: *default
         description: "Detached signature for the checksums file"
         pretty_name:
             by-platform:
                 firefox-source: firefox-${version}.checksums.asc
                 devedition-source: firefox-${version}.checksums.asc
-                fennec-source: fennec-${version}.checksums.asc
+                fennec-.*: fennec-${version}.checksums.asc
         checksums_path:
             by-platform:
                 firefox-source: firefox-${version}.checksums.asc
                 devedition-source: firefox-${version}.checksums.asc
-                fennec-source: fennec-${version}.checksums.asc
+                fennec-.*: fennec-${version}.checksums.asc
--- a/taskcluster/taskgraph/manifests/source_files.yml
+++ b/taskcluster/taskgraph/manifests/source_files.yml
@@ -1,15 +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/.
 ---
 s3_bucket_paths:
     by-platform:
-        fennec-source:
+        fennec-.*:
             - pub/mobile/candidates
         devedition-source:
             - pub/devedition/candidates
         firefox-source:
             - pub/firefox/candidates
 default_locales:  # if given an empty locale, use these locales
     - en-US
 tasktype_map:  # Map task reference to task type.
@@ -32,27 +32,27 @@ default: &default
 mapping:
     source.tar.xz:
         <<: *default
         description: "Source file with the in-tree code archived"
         pretty_name:
             by-platform:
                 firefox-source: firefox-${version}.source.tar.xz
                 devedition-source: firefox-${version}.source.tar.xz
-                fennec-source: fennec-${version}.source.tar.xz
+                fennec-.*: fennec-${version}.source.tar.xz
         checksums_path:
             by-platform:
                 firefox-source: source/firefox-${version}.source.tar.xz
                 devedition-source: source/firefox-${version}.source.tar.xz
-                fennec-source: source/fennec-${version}.source.tar.xz
+                fennec-.*: source/fennec-${version}.source.tar.xz
     source.tar.xz.asc:
         <<: *default
         description: "Detached signature for the source file"
         pretty_name:
             by-platform:
                 firefox-source: firefox-${version}.source.tar.xz.asc
                 devedition-source: firefox-${version}.source.tar.xz.asc
-                fennec-source: fennec-${version}.source.tar.xz.asc
+                fennec-.*: fennec-${version}.source.tar.xz.asc
         checksums_path:
             by-platform:
                 firefox-source: source/firefox-${version}.source.tar.xz.asc
                 devedition-source: source/firefox-${version}.source.tar.xz.asc
-                fennec-source: source/fennec-${version}.source.tar.xz.asc
+                fennec-.*: source/fennec-${version}.source.tar.xz.asc
--- a/taskcluster/taskgraph/target_tasks.py
+++ b/taskcluster/taskgraph/target_tasks.py
@@ -383,17 +383,17 @@ def target_tasks_promote_fennec(full_tas
     def filter(task):
         attr = task.attributes.get
         # Don't ship single locale fennec anymore - Bug 1408083
         if attr("locale") or attr("chunk_locales"):
             return False
 
         if task.attributes.get('shipping_product') == 'fennec' and \
                 task.attributes.get('shipping_phase') == 'promote' and \
-                '-nightly' not in task.label:
+                task.attributes.get('release-type') != 'nightly':
             return True
         return False
 
     return [l for l, t in full_task_graph.tasks.iteritems() if filter(full_task_graph[l])]
 
 
 @_target_task('ship_fennec')
 def target_tasks_ship_fennec(full_task_graph, parameters, graph_config):
@@ -404,20 +404,18 @@ def target_tasks_ship_fennec(full_task_g
         full_task_graph, parameters, graph_config,
     )
 
     def filter(task):
         # Include candidates build tasks; these will be optimized out
         if task.label in filtered_for_candidates:
             return True
         if task.attributes.get('shipping_product') != 'fennec' or \
-                task.attributes.get('shipping_phase') not in ('ship', 'push'):
-            return False
-
-        if task.attributes.get('build_platform', '').endswith('-nightly'):
+                task.attributes.get('shipping_phase') not in ('ship', 'push') or \
+                task.attributes.get('release-type') == 'nightly':
             return False
 
         # secondary-notify-ship is only for RC
         if task.kind in (
             'release-secondary-notify-ship',
         ):
             return is_rc
 
@@ -455,28 +453,23 @@ def target_tasks_nightly_fennec(full_tas
         if task.label in (
             'beetmover-geckoview-android-aarch64-nightly/opt',
             'beetmover-geckoview-android-api-16-nightly/opt',
             'beetmover-geckoview-android-x86-nightly/opt',
             'beetmover-geckoview-android-x86_64-nightly/opt',
         ):
             return False
 
-        platform = task.attributes.get('build_platform')
         if not filter_for_project(task, parameters):
             return False
-        if platform in ('android-aarch64-nightly',
-                        'android-api-16-nightly',
-                        'android-nightly',
-                        'android-x86-nightly',
-                        'android-x86_64-nightly',
-                        ):
-            if not task.attributes.get('nightly', False):
-                return False
-            return filter_for_project(task, parameters)
+        if task.attributes.get('shipping_product') == 'fennec':
+            if task.attributes.get('release-type') == 'nightly':
+                if not task.attributes.get('nightly', False):
+                    return False
+                return True
 
     return [l for l, t in full_task_graph.tasks.iteritems() if filter(t)]
 
 
 def make_desktop_nightly_filter(platforms):
     """Returns a filter that gets all nightly tasks on the given platform."""
     def filter(task, parameters):
         return all([
--- a/taskcluster/taskgraph/transforms/per_platform_dummy.py
+++ b/taskcluster/taskgraph/transforms/per_platform_dummy.py
@@ -17,15 +17,16 @@ transforms = TransformSequence()
 def one_task_per_product_and_platform(config, jobs):
     unique_products_and_platforms = set()
     for job in jobs:
         dep_task = job["primary-dependency"]
         if 'primary-dependency' in job:
             del job['primary-dependency']
         product = dep_task.attributes.get("shipping_product")
         platform = dep_task.attributes.get("build_platform")
-        if (product, platform) not in unique_products_and_platforms:
+        release_type = dep_task.attributes.get("release-type")
+        if (product, platform, release_type) not in unique_products_and_platforms:
             attributes = copy_attributes_from_dependent_job(dep_task)
             attributes.update(job.get('attributes', {}))
             job['attributes'] = attributes
-            job["name"] = "{}-{}".format(product, platform)
+            job["name"] = "-".join(filter(None, (product, platform, release_type)))
             yield job
-            unique_products_and_platforms.add((product, platform))
+            unique_products_and_platforms.add((product, platform, release_type))
--- a/taskcluster/taskgraph/transforms/release_deps.py
+++ b/taskcluster/taskgraph/transforms/release_deps.py
@@ -19,24 +19,16 @@ def add_dependencies(config, jobs):
     for job in jobs:
         dependencies = {}
         # Add any kind_dependencies_tasks with matching product as dependencies
         product = job.get('shipping-product')
         phase = job.get('shipping-phase')
         if product is None:
             continue
 
-        release_type = config.params['release_type']
-        build_platform = job.get('attributes', {}).get('build_platform', '')
-        if product == 'fennec' and (
-            (release_type == 'beta' and '-nightly' in build_platform) or
-            (release_type == 'nightly' and '-beta' in build_platform)
-        ):
-            continue
-
         required_signoffs = set(job.setdefault('attributes', {}).get('required_signoffs', []))
         for dep_task in config.kind_dependencies_tasks:
             # Weed out unwanted tasks.
             # XXX we have run-on-projects which specifies the on-push behavior;
             # we need another attribute that specifies release promotion,
             # possibly which action(s) each task belongs in.
             if product == 'fennec':
                 # Don't ship single locale fennec anymore - Bug 1408083
@@ -47,16 +39,21 @@ def add_dependencies(config, jobs):
                 if attr('build_platform', '').endswith('-nightly'):
                     continue
 
             # We can only depend on tasks in the current or previous phases
             dep_phase = dep_task.attributes.get('shipping_phase')
             if dep_phase and PHASES.index(dep_phase) > PHASES.index(phase):
                 continue
 
+            if dep_task.attributes.get("release-type") and \
+               job.get("attributes", {}).get("release-type"):
+                if dep_task.attributes["release-type"] != job["attributes"]["release-type"]:
+                    continue
+
             if dep_task.attributes.get("build_platform") and \
                job.get("attributes", {}).get("build_platform"):
                 if dep_task.attributes["build_platform"] != job["attributes"]["build_platform"]:
                     continue
             # Add matching product tasks to deps
             if dep_task.task.get('shipping-product') == product or \
                     dep_task.attributes.get('shipping_product') == product:
                 dependencies[dep_task.label] = dep_task.label
--- a/taskcluster/taskgraph/transforms/upload_generated_sources.py
+++ b/taskcluster/taskgraph/transforms/upload_generated_sources.py
@@ -4,40 +4,39 @@
 """
 Transform the upload-generated-files task description template,
 taskcluster/ci/upload-generated-sources/kind.yml, 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.taskcluster import get_artifact_url
 
 
 transforms = TransformSequence()
 
 
 @transforms.add
 def add_task_info(config, jobs):
     for job in jobs:
-        dep_task = job['primary-dependency']
-        del job['primary-dependency']
+        dep_task = job.pop('primary-dependency')
 
         # Add a dependency on the build task.
         job['dependencies'] = {'build': dep_task.label}
         # Label the job to match the build task it's uploading from.
         job['label'] = dep_task.label.replace("build-", "upload-generated-sources-")
         # Copy over some bits of metdata from the build task.
         dep_th = dep_task.task['extra']['treeherder']
-        job.setdefault('attributes', {})
-        job['attributes']['build_platform'] = dep_task.attributes.get('build_platform')
-        if dep_task.attributes.get('nightly'):
-            job['attributes']['nightly'] = True
-        if dep_task.attributes.get('shippable'):
-            job['attributes']['shippable'] = True
+
+        attributes = copy_attributes_from_dependent_job(dep_task)
+        attributes.update(job.get('attributes', {}))
+        job['attributes'] = attributes
+
         plat = '{}/{}'.format(dep_th['machine']['platform'], dep_task.attributes.get('build_type'))
         job['treeherder']['platform'] = plat
         job['treeherder']['tier'] = dep_th['tier']
         if dep_th['symbol'] != "N":
             job['treeherder']['symbol'] = "Ugs{}".format(dep_th['symbol'])
         # Add an environment variable pointing at the artifact from the build.
         artifact_url = get_artifact_url('<build>',
                                         'public/build/target.generated-files.tar.gz')
--- a/taskcluster/taskgraph/transforms/upload_symbols.py
+++ b/taskcluster/taskgraph/transforms/upload_symbols.py
@@ -4,17 +4,17 @@
 """
 Transform the upload-symbols task description template,
 taskcluster/ci/upload-symbols/job-template.yml 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 RELEASE_PROJECTS
+from taskgraph.util.attributes import RELEASE_PROJECTS, copy_attributes_from_dependent_job
 from taskgraph.util.treeherder import join_symbol
 
 import logging
 logger = logging.getLogger(__name__)
 
 transforms = TransformSequence()
 
 
@@ -49,25 +49,21 @@ def fill_template(config, tasks):
             continue
 
         task['dependencies'] = {'build': dep.label}
         task['worker']['env']['GECKO_HEAD_REPOSITORY'] = config.params['head_repository']
         task['worker']['env']['GECKO_HEAD_REV'] = config.params['head_rev']
         task['worker']['env']['SYMBOL_SECRET'] = task['worker']['env']['SYMBOL_SECRET'].format(
             level=config.params['level'])
 
-        build_platform = dep.attributes.get('build_platform')
-        build_type = dep.attributes.get('build_type')
-        attributes = task.setdefault('attributes', {})
-        attributes['build_platform'] = build_platform
-        attributes['build_type'] = build_type
-        if dep.attributes.get('nightly'):
-            attributes['nightly'] = True
-        if dep.attributes.get('shippable'):
-            attributes['shippable'] = True
+        attributes = copy_attributes_from_dependent_job(dep)
+        attributes.update(task.get('attributes', {}))
+        task['attributes'] = attributes
+
+        build_type = attributes.get('build_type')
 
         treeherder = task.get('treeherder', {})
         th = dep.task.get('extra')['treeherder']
         th_platform = dep.task['extra'].get('treeherder-platform',
                                             "{}/{}".format(th['machine']['platform'], build_type))
         th_symbol = th.get('symbol')
         th_groupsymbol = th.get('groupSymbol', '?')
         treeherder.setdefault('platform', th_platform)
--- a/taskcluster/taskgraph/util/attributes.py
+++ b/taskcluster/taskgraph/util/attributes.py
@@ -41,16 +41,17 @@ RELEASE_PROMOTION_PROJECTS = {
     'nightly',
     'required_signoffs',
     'signed',
     'shipping_phase',
     'shipping_product',
     'stub-installer',
     'update-channel',
     'shippable',
+    'release-type',
 )
 
 
 def attrmatch(attributes, **kwargs):
     """Determine whether the given set of task attributes matches.  The
     conditions are given as keyword arguments, where each keyword names an
     attribute.  The keyword value can be a literal, a set, or a callable.  A
     literal must match the attribute exactly.  Given a set, the attribute value