Bug 1535679 - switch Firefox nightlies to declarative artifacts. r=sfraser a=release
authorMihai Tabara <mtabara@mozilla.com>
Mon, 25 Mar 2019 13:48:54 +0000
changeset 525730 b057c733c95275308b2dde23f1c0fc1ec8e2d12a
parent 525729 5c56e7ff721af8c44e631224de885e0dc82cfaff
child 525731 bf53657616690068d1717caf542a60b61ab41eb7
push id2032
push userffxbld-merge
push dateMon, 13 May 2019 09:36:57 +0000
treeherdermozilla-release@455c1065dcbe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfraser, release
bugs1535679
milestone67.0
Bug 1535679 - switch Firefox nightlies to declarative artifacts. r=sfraser a=release Linter fixes. Differential Revision: https://phabricator.services.mozilla.com/D24214
taskcluster/ci/beetmover-repackage/kind.yml
taskcluster/taskgraph/manifests/fennec_candidates.yml
taskcluster/taskgraph/manifests/fennec_candidates_checksums.yml
taskcluster/taskgraph/manifests/fennec_geckoview.yml
taskcluster/taskgraph/manifests/fennec_nightly.yml
taskcluster/taskgraph/manifests/fennec_nightly_checksums.yml
taskcluster/taskgraph/manifests/firefox_nightly.yml
taskcluster/taskgraph/manifests/firefox_nightly_checksums.yml
taskcluster/taskgraph/manifests/release_checksums.yml
taskcluster/taskgraph/manifests/source_checksums.yml
taskcluster/taskgraph/manifests/source_files.yml
taskcluster/taskgraph/transforms/beetmover_repackage.py
taskcluster/taskgraph/transforms/mar_signing.py
taskcluster/taskgraph/util/partials.py
taskcluster/taskgraph/util/scriptworker.py
--- a/taskcluster/ci/beetmover-repackage/kind.yml
+++ b/taskcluster/ci/beetmover-repackage/kind.yml
@@ -44,8 +44,14 @@ only-for-build-platforms:
     - win32-devedition-nightly/opt
     - win64-devedition-nightly/opt
     - win64-aarch64-devedition-nightly/opt
     - linux64-asan-reporter-nightly/opt
     - win64-asan-reporter-nightly/opt
 
 job-template:
     shipping-phase: promote
+    attributes:
+        artifact_map:
+            by-project:
+                mozilla-release: taskcluster/taskgraph/manifests/firefox_candidates.yml
+                mozilla-beta: taskcluster/taskgraph/manifests/firefox_candidates.yml
+                default: taskcluster/taskgraph/manifests/firefox_nightly.yml
--- a/taskcluster/taskgraph/manifests/fennec_candidates.yml
+++ b/taskcluster/taskgraph/manifests/fennec_candidates.yml
@@ -16,25 +16,26 @@ platform_names:
       android-api-16-nightly: 'android-api-16'
       android-aarch64-nightly: 'android-aarch64'
   filename_platform:
     by-platform:
       android-x86-nightly: 'android-i386'
       android-x86_64-nightly: 'android-x86_64'
       android-api-16-nightly: 'android-arm'
       android-aarch64-nightly: 'android-aarch64'
+  stage_platform: ''
 
 # 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
   all_locales: false
-  description: "TODO"
+  description: "TO_BE_OVERRIDDEN"
   locale_prefix: '${locale}/'
   # anything between artifact prefix and filename within upstream task
   source_path_modifier:
     by-locale:
       default: '${locale}'
       multi: ''
   destinations:
     - ${version}-candidates/build${build_number}/${path_platform}
--- a/taskcluster/taskgraph/manifests/fennec_candidates_checksums.yml
+++ b/taskcluster/taskgraph/manifests/fennec_candidates_checksums.yml
@@ -13,25 +13,26 @@ platform_names:
       android-api-16-nightly: 'android-api-16'
       android-aarch64-nightly: 'android-aarch64'
   filename_platform:
     by-platform:
       android-x86-nightly: 'android-i386'
       android-x86_64-nightly: 'android-x86_64'
       android-api-16-nightly: 'android-arm'
       android-aarch64-nightly: 'android-aarch64'
+  stage_platform: ''
 
 # 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:
     - checksums-signing
   all_locales: true
-  description: "TODO"
+  description: "TO_BE_OVERRIDDEN"
   locale_prefix:
     by-locale:
       default: ''
       en-US: '${locale}/'
   source_path_modifier: ''
   destinations:
     - ${version}-candidates/build${build_number}/beetmover-checksums/${path_platform}
     - ${version}-candidates/build${build_number}/${path_platform}
--- a/taskcluster/taskgraph/manifests/fennec_geckoview.yml
+++ b/taskcluster/taskgraph/manifests/fennec_geckoview.yml
@@ -4,26 +4,27 @@ s3_bucket_paths:
 default_locales:  # Ignored for geckoview
   - en-US
 tasktype_map:  # Map task reference to task type.
   build: build
 base_artifact_prefix: ''
 platform_names:
   path_platform: ''
   filename_platform: ''
+  stage_platform: ''
 
 # 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}
-  description: ""
+  description: "TO_BE_OVERRIDDEN"
   destinations:  # locale_prefix is appended
     - org/mozilla/geckoview/${artifact_id}/${major_version}.${minor_version}.${build_date}
 
 # Configuration for individual files. Extends 'default', above.
 upstream_mapping:
   target.maven.zip:
     from:
       - build
--- a/taskcluster/taskgraph/manifests/fennec_nightly.yml
+++ b/taskcluster/taskgraph/manifests/fennec_nightly.yml
@@ -16,44 +16,45 @@ platform_names:
       android-api-16-nightly: 'android-api-16'
       android-aarch64-nightly: 'android-aarch64'
   filename_platform:
     by-platform:
       android-x86-nightly: 'android-i386'
       android-x86_64-nightly: 'android-x86_64'
       android-api-16-nightly: 'android-arm'
       android-aarch64-nightly: 'android-aarch64'
+  stage_platform: ''
 
 # 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
   all_locales: false
-  description: "TODO"
+  description: "TO_BE_OVERRIDDEN"
   locale_prefix:
     by-locale:
       default: ''
       en-US: '${locale}/'
   source_path_modifier:  # Anything between artifact prefix and filename
     by-locale:
       default: '${locale}'
       multi: ''
   destinations:  # locale_prefix is appended
     by-locale:
       multi:
-        - latest-${branch}-${path_platform}
         - ${year}/${month}/${upload_date}-${branch}-${path_platform}
-      en-US:
         - latest-${branch}-${path_platform}
+      en-US:
         - ${year}/${month}/${upload_date}-${branch}-${path_platform}
+        - latest-${branch}-${path_platform}
       default:
+        - ${year}/${month}/${upload_date}-${branch}-${path_platform}-l10n
         - latest-${branch}-${path_platform}-l10n
-        - ${year}/${month}/${upload_date}-${branch}-${path_platform}-l10n
 
 # Configuration for individual files. Extends 'default', above.
 mapping:
   buildhub.json:
     <<: *default
     all_locales: true
     description: "Build related information to be consumed by Buildhub service"
     locale_prefix: ''
--- a/taskcluster/taskgraph/manifests/fennec_nightly_checksums.yml
+++ b/taskcluster/taskgraph/manifests/fennec_nightly_checksums.yml
@@ -13,41 +13,42 @@ platform_names:
       android-api-16-nightly: 'android-api-16'
       android-aarch64-nightly: 'android-aarch64'
   filename_platform:
     by-platform:
       android-x86-nightly: 'android-i386'
       android-x86_64-nightly: 'android-x86_64'
       android-api-16-nightly: 'android-arm'
       android-aarch64-nightly: 'android-aarch64'
+  stage_platform: ''
 
 # 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:
     - checksums-signing
   all_locales: true
-  description: "TODO"
+  description: "TO_BE_OVERRIDDEN"
   locale_prefix:
     by-locale:
       default: ''
       en-US: '${locale}/'
   source_path_modifier: ''
   destinations:  # locale_prefix is appended
     by-locale:
       multi:
-        - latest-${branch}-${path_platform}
         - ${year}/${month}/${upload_date}-${branch}-${path_platform}
-      en-US:
         - latest-${branch}-${path_platform}
+      en-US:
         - ${year}/${month}/${upload_date}-${branch}-${path_platform}
+        - latest-${branch}-${path_platform}
       default:
+        - ${year}/${month}/${upload_date}-${branch}-${path_platform}-l10n
         - latest-${branch}-${path_platform}-l10n
-        - ${year}/${month}/${upload_date}-${branch}-${path_platform}-l10n
 
 # Configuration for individual files. Extends 'default', above.
 mapping:
   target.checksums:
     <<: *default
     description: "Checksums file containing size, hash, sha algorithm and filename"
     pretty_name: fennec-${version}.${locale}.${filename_platform}.checksums
     checksums_path: fennec-${version}.${locale}.${filename_platform}.checksums
new file mode 100644
--- /dev/null
+++ b/taskcluster/taskgraph/manifests/firefox_nightly.yml
@@ -0,0 +1,438 @@
+# This file contains exhaustive information about all the release artifacs that
+# are needed within a type of release.
+#
+# Structure
+# --------
+# `s3_bucket_paths`       -- prefix to be used per product to correctly access our S3 buckets
+# `default_locales`       -- list of locales to be used when composing upstream artifacts or the list of
+#                      destinations. If given an empty locale, it uses these locales instead.
+# `tasktype_map`          -- mapping between task reference and task type, particularly usefule when
+#                      composing the upstreamArtifacts for scriptworker.
+# `platform_names`        -- various platform mappings used in reckoning artifacts or other paths
+# `default`               -- a default entry, which the mappings extend and override in such a way that
+#                      final path full-destinations will be a concatenation of the following:
+#                      `s3_bucket_paths`, `destinations`, `locale_prefix`, `pretty_name`
+# `from`                  -- specifies the dependency(ies) from which to expect the particular artifact
+# `all_locales`           -- boolean argument to specify whether that particular artifact is to be expected
+#                      for all locales or just the default one
+# `description`           -- brief summary of what that artifact is
+# `locale_prefix`         -- prefix to be used in the final destination paths, whether that's for default locale or not
+# `source_path_modifier`  -- any parent dir that might be used in between artifact prefix and filename at source location
+#                            for example `public/build` vs `public/build/ach/`.
+# `destinations`          -- final list of directories where to push the artifacts in S3
+# `pretty_name`           -- the final name the artifact will have at destination
+# `checksums_path`        -- the name to identify one artifact within the checksums file
+# `not_for_platforms`     -- filtering option to avoid associating an artifact with a specific platform
+# `only_for_platforms`    -- filtering option to exclusively include the association of an artifact for a specific platform
+# `partials_only`         -- filtering option to avoid associating an artifact unless this flag is present
+# `update_balrog_manifest`-- flag needed downstream in beetmover jobs to reckon the balrog manifest
+# `from_buildid`          -- flag needed downstream in beetmover jobs to reckon the balrog manifest
+
+---
+s3_bucket_paths:
+  - pub/firefox/nightly
+default_locales:
+  - en-US
+tasktype_map:
+  build: build
+  signing: signing
+  mar-signing: signing
+  partials-signing: signing
+  repackage: repackage
+  repackage-signing: repackage
+  repackage-signing-msi: repackage
+platform_names:
+  path_platform: ''
+  filename_platform:
+    by-platform:
+      linux-nightly: 'linux-i686'
+      linux64-nightly: 'linux-x86_64'
+      linux64-asan-reporter-nightly: 'linux-x86_64-asan-reporter'
+      macosx64-nightly: 'mac'
+      win32-nightly: 'win32'
+      win64-nightly: 'win64'
+      win64-aarch64-nightly: 'win64-aarch64'
+      win64-asan-reporter-nightly: 'win64-asan-reporter'
+  stage_platform:
+    by-platform:
+      linux-nightly: 'linux'
+      linux64-asan-reporter-nightly: 'linux64-asan-reporter'
+      linux64-nightly: 'linux64'
+      macosx64-nightly: 'macosx64'
+      win32-nightly: 'win32'
+      win64-nightly: 'win64'
+      win64-aarch64-nightly: 'win64-aarch64'
+      win64-asan-reporter-nightly: 'win64-asan-reporter'
+
+default: &default
+  from:
+    - build
+  all_locales: false
+  description: "TO_BE_OVERRIDDEN"
+  locale_prefix: ''
+  source_path_modifier:
+    by-locale:
+      default: '${locale}'
+      en-US: ''
+  destinations:
+    by-locale:
+      en-US:
+        - ${year}/${month}/${upload_date}-${branch}
+        - latest-${branch}
+      default:
+        - ${year}/${month}/${upload_date}-${branch}-l10n
+        - latest-${branch}-l10n
+
+mapping:
+  buildhub.json:
+    <<: *default
+    description: "Build related information to be consumed by Buildhub service"
+    pretty_name: firefox-${version}.${locale}.${filename_platform}.buildhub.json
+    checksums_path: firefox-${version}.${locale}.${filename_platform}.buildhub.json
+    destinations:
+      by-locale:
+        en-US:
+          - ${year}/${month}/${upload_date}-${branch}
+          - latest-${branch}
+          - latest-${branch}-l10n
+        default:
+          - ${year}/${month}/${upload_date}-${branch}-l10n
+          - latest-${branch}-l10n
+  target.common.tests.tar.gz:
+    <<: *default
+    description: "Mixture of reftests, mochitests, UI and others, commonly bundled together in a test suite"
+    pretty_name: firefox-${version}.${locale}.${filename_platform}.common.tests.tar.gz
+    checksums_path: firefox-${version}.${locale}.${filename_platform}.common.tests.tar.gz
+  target.cppunittest.tests.tar.gz:
+    <<: *default
+    description: "C++ unittests related in-tree test infrastructure"
+    pretty_name: firefox-${version}.${locale}.${filename_platform}.cppunittest.tests.tar.gz
+    checksums_path: firefox-${version}.${locale}.${filename_platform}.cppunittest.tests.tar.gz
+  target.crashreporter-symbols.zip:
+    <<: *default
+    description: "Crashreporter symbols to be consumed by Socorro"
+    pretty_name: firefox-${version}.${locale}.${filename_platform}.crashreporter-symbols.zip
+    checksums_path: firefox-${version}.${locale}.${filename_platform}.crashreporter-symbols.zip
+    not_for_platforms:
+      - linux64-asan-reporter-nightly
+      - win64-asan-reporter-nightly
+  target.json:
+    <<: *default
+    description: "Various compile and moz_app flags baked together in a json file"
+    pretty_name: firefox-${version}.${locale}.${filename_platform}.json
+    checksums_path: firefox-${version}.${locale}.${filename_platform}.json
+  target.mochitest.tests.tar.gz:
+    <<: *default
+    description: "Results for running the mochitest testing framework via Javascript function calls"
+    pretty_name: firefox-${version}.${locale}.${filename_platform}.mochitest.tests.tar.gz
+    checksums_path: firefox-${version}.${locale}.${filename_platform}.mochitest.tests.tar.gz
+  target.mozinfo.json:
+    <<: *default
+    description: "Various compile and moz_app flags baked together in a json file"
+    pretty_name: firefox-${version}.${locale}.${filename_platform}.mozinfo.json
+    checksums_path: firefox-${version}.${locale}.${filename_platform}.mozinfo.json
+  target.reftest.tests.tar.gz:
+    <<: *default
+    description: "Results for running the reftest testing framework via display of two Web pages comparison"
+    pretty_name: firefox-${version}.${locale}.${filename_platform}.reftest.tests.tar.gz
+    checksums_path: firefox-${version}.${locale}.${filename_platform}.reftest.tests.tar.gz
+  target.talos.tests.tar.gz:
+    <<: *default
+    description: "Results for running the talos testing framework to measure performance"
+    pretty_name: firefox-${version}.${locale}.${filename_platform}.talos.tests.tar.gz
+    checksums_path: firefox-${version}.${locale}.${filename_platform}.talos.tests.tar.gz
+  target.awsy.tests.tar.gz:
+    <<: *default
+    description: "Results for running the awsy testing framework to track memory usage"
+    pretty_name: firefox-${version}.${locale}.${filename_platform}.awsy.tests.tar.gz
+    checksums_path: firefox-${version}.${locale}.${filename_platform}.awsy.tests.tar.gz
+  target.test_packages.json:
+    <<: *default
+    description: "File containing metadata about all other files and testing harnesses specifics"
+    pretty_name: firefox-${version}.${locale}.${filename_platform}.test_packages.json
+    checksums_path: firefox-${version}.${locale}.${filename_platform}.test_packages.json
+  target.txt:
+    <<: *default
+    description: "File containing buildid and revision"
+    pretty_name: firefox-${version}.${locale}.${filename_platform}.txt
+    checksums_path: firefox-${version}.${locale}.${filename_platform}.txt
+  target.web-platform.tests.tar.gz:
+    <<: *default
+    description: "Results for running the webplatform testing framework to cover standard Web platform features"
+    pretty_name: firefox-${version}.${locale}.${filename_platform}.web-platform.tests.tar.gz
+    checksums_path: firefox-${version}.${locale}.${filename_platform}.web-platform.tests.tar.gz
+  target.xpcshell.tests.tar.gz:
+    <<: *default
+    description: "Results for running the xpcshell testing framework to enable XPConnect console application"
+    pretty_name: firefox-${version}.${locale}.${filename_platform}.xpcshell.tests.tar.gz
+    checksums_path: firefox-${version}.${locale}.${filename_platform}.xpcshell.tests.tar.gz
+  target_info.txt:
+    <<: *default
+    description: "File containing the buildID"
+    pretty_name: firefox-${version}.${locale}.${filename_platform}_info.txt
+    checksums_path: firefox-${version}.${locale}.${filename_platform}_info.txt
+  mozharness.zip:
+    <<: *default
+    description: "File containing the mozharness set of scripts and configuration used by various automation tools"
+    pretty_name: mozharness.zip
+    checksums_path: mozharness.zip
+  target.jsshell.zip:
+    <<: *default
+    description: "Set of shells to allow test snippets of Javascript code without needing to reload the page"
+    pretty_name: jsshell-${filename_platform}.zip
+    checksums_path: jsshell-${filename_platform}.zip
+    not_for_platforms:
+      - linux64-asan-reporter-nightly
+      - win64-asan-reporter-nightly
+  target.langpack.xpi:
+    <<: *default
+    all_locales: true
+    description: "Localized repack that grabs a packaged en-US Firefox and repackages it as locale-specific Firefox"
+    from:
+      - build
+    only_for_platforms:
+      - linux-nightly
+      - linux64-nightly
+      - macosx64-nightly
+      - win64-nightly
+      - win32-nightly
+      - win64-nightly
+      - win64-aarch64-nightly
+      - win64-asan-reporter-nightly
+      - linux64-asan-reporter-nightly
+    pretty_name: firefox-${version}.${locale}.langpack.xpi
+    checksums_path: firefox-${version}.${locale}.langpack.xpi
+    destinations:
+      by-locale:
+        en-US:
+          - ${year}/${month}/${upload_date}-${branch}
+          - latest-${branch}
+        default:
+          - ${year}/${month}/${upload_date}-${branch}-l10n/${filename_platform}/xpi
+          - latest-${branch}-l10n/${filename_platform}/xpi
+  mar:
+    <<: *default
+    description: "Alongside `mbsdiff`, a tool used to generate partials"
+    source_path_modifier: 'host/bin'
+    pretty_name: mar
+    checksums_path: mar
+    not_for_platforms:
+      - win32-nightly
+      - win64-nightly
+      - win64-aarch64-nightly
+      - win64-asan-reporter-nightly
+    destinations:
+      - ${year}/${month}/${upload_date}-${branch}/mar-tools/${stage_platform}
+      - latest-${branch}/mar-tools/${stage_platform}
+  mbsdiff:
+    <<: *default
+    description: "Alongside `mar`, a tool used to generate partials"
+    source_path_modifier: 'host/bin'
+    pretty_name: mbsdiff
+    checksums_path: mbsdiff
+    not_for_platforms:
+      - win32-nightly
+      - win64-nightly
+      - win64-aarch64-nightly
+      - win64-asan-reporter-nightly
+    destinations:
+      - ${year}/${month}/${upload_date}-${branch}/mar-tools/${stage_platform}
+      - latest-${branch}/mar-tools/${stage_platform}
+  mar.exe:
+    <<: *default
+    description: "Alongside `mbsdiff.exe`, a tool used to generate partials for Windows platforms"
+    source_path_modifier: 'host/bin'
+    pretty_name: mar.exe
+    checksums_path: mar.exe
+    only_for_platforms:
+      - win32-nightly
+      - win64-nightly
+      - win64-aarch64-nightly
+      - win64-asan-reporter-nightly
+    destinations:
+      - ${year}/${month}/${upload_date}-${branch}/mar-tools/${stage_platform}
+      - latest-${branch}/mar-tools/${stage_platform}
+  mbsdiff.exe:
+    <<: *default
+    description: "Alongside `mar.exe`, a tool used to generate partials for Windows platforms"
+    source_path_modifier: 'host/bin'
+    pretty_name: mbsdiff.exe
+    checksums_path: mbsdiff.exe
+    only_for_platforms:
+      - win32-nightly
+      - win64-nightly
+      - win64-aarch64-nightly
+      - win64-asan-reporter-nightly
+    destinations:
+      - ${year}/${month}/${upload_date}-${branch}/mar-tools/${stage_platform}
+      - latest-${branch}/mar-tools/${stage_platform}
+  target.tar.bz2:
+    <<: *default
+    description: "Main installer for Linux platforms"
+    all_locales: true
+    from:
+      - signing
+    only_for_platforms:
+      - linux-nightly
+      - linux64-nightly
+      - linux64-asan-reporter-nightly
+    pretty_name: firefox-${version}.${locale}.${filename_platform}.tar.bz2
+    checksums_path: firefox-${version}.${locale}.${filename_platform}.tar.bz2
+    destinations:
+      by-locale:
+        en-US:
+          - ${year}/${month}/${upload_date}-${branch}
+          - latest-${branch}
+          - latest-${branch}-l10n
+        default:
+          - ${year}/${month}/${upload_date}-${branch}-l10n
+          - latest-${branch}-l10n
+  target.tar.bz2.asc:
+    <<: *default
+    description: "Detached signature for the checksums file"
+    all_locales: true
+    from:
+      - signing
+    only_for_platforms:
+      - linux-nightly
+      - linux64-nightly
+      - linux64-asan-reporter-nightly
+    pretty_name: firefox-${version}.${locale}.${filename_platform}.tar.bz2.asc
+    checksums_path: firefox-${version}.${locale}.${filename_platform}.tar.bz2.asc
+    destinations:
+      by-locale:
+        en-US:
+          - ${year}/${month}/${upload_date}-${branch}
+          - latest-${branch}
+          - latest-${branch}-l10n
+        default:
+          - ${year}/${month}/${upload_date}-${branch}-l10n
+          - latest-${branch}-l10n
+  target.dmg:
+    <<: *default
+    description: "Main package installer for Mac OS X platforms"
+    all_locales: true
+    from:
+      - repackage
+    only_for_platforms:
+      - macosx64-nightly
+    pretty_name: firefox-${version}.${locale}.${filename_platform}.dmg
+    checksums_path: firefox-${version}.${locale}.${filename_platform}.dmg
+    destinations:
+      by-locale:
+        en-US:
+          - ${year}/${month}/${upload_date}-${branch}
+          - latest-${branch}
+          - latest-${branch}-l10n
+        default:
+          - ${year}/${month}/${upload_date}-${branch}-l10n
+          - latest-${branch}-l10n
+  target.zip:
+    <<: *default
+    description: "Main package installer for Windows platforms"
+    all_locales: true
+    from:
+      - signing
+    only_for_platforms:
+      - win64-nightly
+      - win32-nightly
+      - win64-aarch64-nightly
+      - win64-asan-reporter-nightly
+    pretty_name: firefox-${version}.${locale}.${filename_platform}.zip
+    checksums_path: firefox-${version}.${locale}.${filename_platform}.zip
+  target.installer.exe:
+    <<: *default
+    description: "Main installer for Windows platforms"
+    all_locales: true
+    from:
+      - repackage-signing
+    only_for_platforms:
+      - win64-nightly
+      - win32-nightly
+      - win64-aarch64-nightly
+      - win64-asan-reporter-nightly
+    pretty_name: firefox-${version}.${locale}.${filename_platform}.installer.exe
+    checksums_path: firefox-${version}.${locale}.${filename_platform}.installer.exe
+    destinations:
+      by-locale:
+        en-US:
+          - ${year}/${month}/${upload_date}-${branch}
+          - latest-${branch}
+          - latest-${branch}-l10n
+        default:
+          - ${year}/${month}/${upload_date}-${branch}-l10n
+          - latest-${branch}-l10n
+  target.stub-installer.exe:
+    <<: *default
+    description: "Stub installer for Win32 platforms"
+    all_locales: true
+    from:
+      - repackage-signing
+    only_for_platforms:
+      - win32-nightly
+    pretty_name: Firefox Installer.${locale}.exe
+    checksums_path: Firefox Installer.${locale}.exe
+    destinations:
+      by-locale:
+        en-US:
+          - ${year}/${month}/${upload_date}-${branch}
+          - latest-${branch}
+          - latest-${branch}-l10n
+        default:
+          - ${year}/${month}/${upload_date}-${branch}-l10n
+          - latest-${branch}-l10n
+  target.installer.msi:
+    <<: *default
+    description: "Windows installer for MSI platform"
+    all_locales: true
+    from:
+      - repackage-signing-msi
+    only_for_platforms:
+      - win64-nightly
+      - win32-nightly
+    pretty_name: firefox-${version}.${locale}.${filename_platform}.installer.msi
+    checksums_path: firefox-${version}.${locale}.${filename_platform}.installer.msi
+    destinations:
+      by-locale:
+        en-US:
+          - ${year}/${month}/${upload_date}-${branch}
+          - latest-${branch}
+          - latest-${branch}-l10n
+        default:
+          - ${year}/${month}/${upload_date}-${branch}-l10n
+          - latest-${branch}-l10n
+  target.complete.mar:
+    <<: *default
+    description: "The main installer we ship our mobile products baked within"
+    all_locales: true
+    from:
+      - mar-signing
+    pretty_name: firefox-${version}.${locale}.${filename_platform}.complete.mar
+    checksums_path: firefox-${version}.${locale}.${filename_platform}.complete.mar
+    update_balrog_manifest: true
+    destinations:
+      by-locale:
+        en-US:
+          - ${year}/${month}/${upload_date}-${branch}
+          - latest-${branch}
+          - latest-${branch}-l10n
+        default:
+          - ${year}/${month}/${upload_date}-${branch}-l10n
+          - latest-${branch}-l10n
+  ${partial}:
+    <<: *default
+    description: "Partials MAR files to serve as updates"
+    all_locales: true
+    from:
+      - partials-signing
+    partials_only: true
+    pretty_name: firefox-${branch}-${version}-${filename_platform}-${locale}-${from_buildid}-${buildid}.partial.mar
+    checksums_path: firefox-${branch}-${version}-${filename_platform}-${locale}-${from_buildid}-${buildid}.partial.mar
+    update_balrog_manifest: true
+    from_buildid: ${from_buildid}
+    destinations:
+      by-locale:
+        en-US:
+          - partials/${year}/${month}/${upload_date}-${branch}
+        default:
+          - partials/${year}/${month}/${upload_date}-${branch}-l10n
--- a/taskcluster/taskgraph/manifests/firefox_nightly_checksums.yml
+++ b/taskcluster/taskgraph/manifests/firefox_nightly_checksums.yml
@@ -8,41 +8,45 @@ s3_bucket_paths:
 default_locales:  # if given an empty locale, use these locales
   - en-US
 tasktype_map:  # Map task reference to task type.
   checksums-signing: signing
 platform_names:
   path_platform: ''
   filename_platform:
     by-platform:
-      linux-.*: 'linux-i686'
-      linux64.*: 'linux-x86_64'
-      macosx64.*: 'mac'
-      win32.*: 'win32'
-      win64.*: 'win64'
+      linux-nightly: 'linux-i686'
+      linux64-nightly: 'linux-x86_64'
+      linux64-asan-reporter-nightly: 'linux-x86_64-asan-reporter'
+      macosx64-nightly: 'mac'
+      win32-nightly: 'win32'
+      win64-nightly: 'win64'
+      win64-aarch64-nightly: 'win64-aarch64'
+      win64-asan-reporter-nightly: 'win64-asan-reporter'
+  stage_platform: ''
 
 # 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:
     - checksums-signing
   all_locales: true
-  description: "TODO"
+  description: "TO_BE_OVERRIDDEN"
   locale_prefix: ''
   source_path_modifier: ''
   destinations:  # locale_prefix is appended
     by-locale:
       en-US:
+        - ${year}/${month}/${upload_date}-${branch}
         - latest-${branch}
         - latest-${branch}-l10n
-        - ${year}/${month}/${upload_date}-${branch}-${path_platform}
       default:
+        - ${year}/${month}/${upload_date}-${branch}-l10n
         - latest-${branch}-l10n
-        - ${year}/${month}/${upload_date}-${branch}-l10n
 
 # Configuration for individual files. Extends 'default', above.
 mapping:
   target.checksums:
     <<: *default
     description: "Checksums file containing size, hash, sha algorithm and filename"
     pretty_name: firefox-${version}.${locale}.${filename_platform}.checksums
     checksums_path: firefox-${version}.${locale}.${filename_platform}.checksums
--- a/taskcluster/taskgraph/manifests/release_checksums.yml
+++ b/taskcluster/taskgraph/manifests/release_checksums.yml
@@ -10,25 +10,26 @@ s3_bucket_paths:
 default_locales:  # if given an empty locale, use these locales
   - en-US
 tasktype_map:  # Map task reference to task type.
   release-generate-checksums: build
   release-generate-checksums-signing: signing
 platform_names:
   path_platform: ''
   filename_platform: ''
+  stage_platform: ''
 
 # 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:
     - release-generate-checksums-signing
   all_locales: true
-  description: "TODO"
+  description: "TO_BE_OVERRIDDEN"
   locale_prefix: ''
   source_path_modifier: ''
   destinations:  # locale_prefix is appended
     - ${version}-candidates/build${build_number}
 
 # Configuration for individual files. Extends 'default', above.
 mapping:
   SHA256SUMMARY:
--- a/taskcluster/taskgraph/manifests/source_checksums.yml
+++ b/taskcluster/taskgraph/manifests/source_checksums.yml
@@ -9,25 +9,26 @@ s3_bucket_paths:
       - pub/firefox/candidates
 default_locales:  # if given an empty locale, use these locales
   - en-US
 tasktype_map:  # Map task reference to task type.
   release-source-checksums-signing: signing
 platform_names:
   path_platform: ''
   filename_platform: ''
+  stage_platform: ''
 
 # 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:
     - release-source-checksums-signing
   all_locales: false
-  description: "TODO"
+  description: "TO_BE_OVERRIDDEN"
   locale_prefix: ''
   source_path_modifier: ''
   destinations:  # locale_prefix is appended
     - ${version}-candidates/build${build_number}/beetmover-checksums/source
 
 # Configuration for individual files. Extends 'default', above.
 mapping:
   target-source.checksums:
--- a/taskcluster/taskgraph/manifests/source_files.yml
+++ b/taskcluster/taskgraph/manifests/source_files.yml
@@ -9,25 +9,26 @@ s3_bucket_paths:
       - pub/firefox/candidates
 default_locales:  # if given an empty locale, use these locales
   - en-US
 tasktype_map:  # Map task reference to task type.
   release-source-signing: signing
 platform_names:
   path_platform: ''
   filename_platform: ''
+  stage_platform: ''
 
 # 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:
     - release-source-signing
   all_locales: false
-  description: "TODO"
+  description: "TO_BE_OVERRIDDEN"
   locale_prefix: ''
   source_path_modifier: ''
   destinations:  # locale_prefix is appended
     - ${version}-candidates/build${build_number}/source
 
 # Configuration for individual files. Extends 'default', above.
 mapping:
   source.tar.xz:
--- a/taskcluster/taskgraph/transforms/beetmover_repackage.py
+++ b/taskcluster/taskgraph/transforms/beetmover_repackage.py
@@ -7,21 +7,25 @@ Transform the beetmover task into an act
 
 from __future__ import absolute_import, print_function, unicode_literals
 
 from taskgraph.loader.multi_dep import schema
 from taskgraph.transforms.base import TransformSequence
 from taskgraph.transforms.beetmover import craft_release_properties
 from taskgraph.util.attributes import copy_attributes_from_dependent_job
 from taskgraph.util.partials import (get_balrog_platform_name,
-                                     get_partials_artifacts,
-                                     get_partials_artifact_map)
-from taskgraph.util.scriptworker import (get_beetmover_bucket_scope,
+                                     get_partials_artifacts_from_params,
+                                     get_partials_info_from_params)
+from taskgraph.util.scriptworker import (generate_beetmover_artifact_map,
+                                         generate_beetmover_upstream_artifacts,
+                                         generate_beetmover_partials_artifact_map,
+                                         get_beetmover_bucket_scope,
                                          get_beetmover_action_scope,
-                                         get_worker_type_for_scope)
+                                         get_worker_type_for_scope,
+                                         should_use_artifact_map)
 from taskgraph.util.taskcluster import get_artifact_prefix
 from taskgraph.util.treeherder import replace_group
 from taskgraph.transforms.task import task_description_schema
 from voluptuous import Required, Optional
 
 import logging
 import re
 
@@ -348,73 +352,85 @@ least 2 regular expressions. First match
 
 
 @transforms.add
 def make_task_worker(config, jobs):
     for job in jobs:
         locale = job["attributes"].get("locale")
         platform = job["attributes"]["build_platform"]
 
-        upstream_artifacts = generate_upstream_artifacts(
-            config, job, job['dependencies'], platform, locale,
-            project=config.params['project']
-        )
+        if should_use_artifact_map(platform, config.params['project']):
+            upstream_artifacts = generate_beetmover_upstream_artifacts(
+                config, job, platform, locale)
+        else:
+            upstream_artifacts = generate_upstream_artifacts(
+                config, job, job['dependencies'], platform, locale,
+                project=config.params['project']
+            )
 
         worker = {
             'implementation': 'beetmover',
             'release-properties': craft_release_properties(config, job),
             'upstream-artifacts': upstream_artifacts,
         }
+
+        if should_use_artifact_map(platform, config.params['project']):
+            worker['artifact-map'] = generate_beetmover_artifact_map(
+                config, job, platform=platform, locale=locale)
+
         if locale:
             worker["locale"] = locale
         job["worker"] = worker
 
         yield job
 
 
 @transforms.add
 def make_partials_artifacts(config, jobs):
     for job in jobs:
         locale = job["attributes"].get("locale")
         if not locale:
             locale = 'en-US'
 
-        # Remove when proved reliable
-        # job['treeherder']['tier'] = 3
-
         platform = job["attributes"]["build_platform"]
 
         if 'partials-signing' not in job['dependencies']:
             yield job
             continue
 
         balrog_platform = get_balrog_platform_name(platform)
-        artifacts = get_partials_artifacts(config.params.get('release_history'),
-                                           balrog_platform, locale)
+        artifacts = get_partials_artifacts_from_params(config.params.get('release_history'),
+                                                       balrog_platform, locale)
 
         upstream_artifacts = generate_partials_upstream_artifacts(
             job, artifacts, balrog_platform, locale
         )
 
         job['worker']['upstream-artifacts'].extend(upstream_artifacts)
 
         extra = list()
 
-        artifact_map = get_partials_artifact_map(
+        partials_info = get_partials_info_from_params(
             config.params.get('release_history'), balrog_platform, locale)
-        for artifact in artifact_map:
+
+        if should_use_artifact_map(platform, config.params['project']):
+            job['worker']['artifact-map'].extend(
+                generate_beetmover_partials_artifact_map(
+                    config, job, partials_info, platform=platform, locale=locale))
+
+        for artifact in partials_info:
             artifact_extra = {
                 'locale': locale,
                 'artifact_name': artifact,
-                'buildid': artifact_map[artifact]['buildid'],
+                'buildid': partials_info[artifact]['buildid'],
                 'platform': balrog_platform,
             }
             for rel_attr in ('previousBuildNumber', 'previousVersion'):
-                if artifact_map[artifact].get(rel_attr):
-                    artifact_extra[rel_attr] = artifact_map[artifact][rel_attr]
+                if partials_info[artifact].get(rel_attr):
+                    artifact_extra[rel_attr] = partials_info[artifact][rel_attr]
             extra.append(artifact_extra)
 
         job.setdefault('extra', {})
         job['extra']['partials'] = extra
 
         yield job
 
 
--- a/taskcluster/taskgraph/transforms/mar_signing.py
+++ b/taskcluster/taskgraph/transforms/mar_signing.py
@@ -10,17 +10,17 @@ import os
 
 from taskgraph.transforms.base import TransformSequence
 from taskgraph.util.attributes import copy_attributes_from_dependent_job, sorted_unique_list
 from taskgraph.util.scriptworker import (
     add_scope_prefix,
     get_signing_cert_scope_per_platform,
     get_worker_type_for_scope,
 )
-from taskgraph.util.partials import get_balrog_platform_name, get_partials_artifacts
+from taskgraph.util.partials import get_balrog_platform_name, get_partials_artifacts_from_params
 from taskgraph.util.taskcluster import get_artifact_prefix
 from taskgraph.util.treeherder import join_symbol
 
 import logging
 logger = logging.getLogger(__name__)
 
 SIGNING_FORMATS = {
     'mar-signing-autograph-stage': {
@@ -37,17 +37,17 @@ transforms = TransformSequence()
 
 def generate_partials_artifacts(job, release_history, platform, locale=None):
     artifact_prefix = get_artifact_prefix(job)
     if locale:
         artifact_prefix = '{}/{}'.format(artifact_prefix, locale)
     else:
         locale = 'en-US'
 
-    artifacts = get_partials_artifacts(release_history, platform, locale)
+    artifacts = get_partials_artifacts_from_params(release_history, platform, locale)
 
     upstream_artifacts = [{
         "taskId": {"task-reference": '<partials>'},
         "taskType": 'partials',
         "paths": [
             "{}/{}".format(artifact_prefix, path)
             for path, version in artifacts
             # TODO Use mozilla-version to avoid comparing strings. Otherwise Firefox 100 will be
--- a/taskcluster/taskgraph/util/partials.py
+++ b/taskcluster/taskgraph/util/partials.py
@@ -92,25 +92,25 @@ def _sanitize_platform(platform):
 
 def get_builds(release_history, platform, locale):
     """Examine cached balrog release history and return the list of
     builds we need to generate diffs from"""
     platform = _sanitize_platform(platform)
     return release_history.get(platform, {}).get(locale, {})
 
 
-def get_partials_artifacts(release_history, platform, locale):
+def get_partials_artifacts_from_params(release_history, platform, locale):
     platform = _sanitize_platform(platform)
     return [
         (artifact, details.get('previousVersion', None))
         for artifact, details in release_history.get(platform, {}).get(locale, {}).items()
     ]
 
 
-def get_partials_artifact_map(release_history, platform, locale):
+def get_partials_info_from_params(release_history, platform, locale):
     platform = _sanitize_platform(platform)
 
     artifact_map = {}
     for k in release_history.get(platform, {}).get(locale, {}):
         details = release_history[platform][locale][k]
         attributes = ('buildid',
                       'previousBuildNumber',
                       'previousVersion')
--- a/taskcluster/taskgraph/util/scriptworker.py
+++ b/taskcluster/taskgraph/util/scriptworker.py
@@ -436,17 +436,24 @@ def generate_beetmover_upstream_artifact
     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']:
                 continue
-
+            if ('only_for_platforms' in map_config['mapping'][filename] and
+                platform not in map_config['mapping'][filename]['only_for_platforms']):
+                continue
+            if ('not_for_platforms' in map_config['mapping'][filename] and
+                platform in map_config['mapping'][filename]['not_for_platforms']):
+                continue
+            if 'partials_only' in map_config['mapping'][filename]:
+                continue
             # The next time we look at this file it might be a different locale.
             file_config = deepcopy(map_config['mapping'][filename])
             resolve_keyed_by(file_config, "source_path_modifier",
                              'source path modifier', locale=locale)
             paths.append(os.path.join(
                 base_artifact_prefix,
                 jsone.render(file_config['source_path_modifier'], {'locale': locale}),
                 filename,
@@ -561,16 +568,26 @@ def generate_beetmover_artifact_map(conf
         for filename in map_config['mapping']:
             # Relevancy checks
             if dep not in map_config['mapping'][filename]['from']:
                 # We don't get this file from this dependency.
                 continue
             if locale != 'en-US' and not map_config['mapping'][filename]['all_locales']:
                 # This locale either doesn't produce or shouldn't upload this file.
                 continue
+            if ('only_for_platforms' in map_config['mapping'][filename] and
+                platform not in map_config['mapping'][filename]['only_for_platforms']):
+                # This platform either doesn't produce or shouldn't upload this file.
+                continue
+            if ('not_for_platforms' in map_config['mapping'][filename] and
+                platform in map_config['mapping'][filename]['not_for_platforms']):
+                # This platform either doesn't produce or shouldn't upload this file.
+                continue
+            if 'partials_only' in map_config['mapping'][filename]:
+                continue
 
             # deepcopy because the next time we look at this file the locale will differ.
             file_config = deepcopy(map_config['mapping'][filename])
 
             for field in [
                 'destinations',
                 'locale_prefix',
                 'source_path_modifier',
@@ -588,32 +605,31 @@ def generate_beetmover_artifact_map(conf
                     dest_path=dest_path,
                     locale_prefix=file_config['locale_prefix'],
                     filename=file_config.get('pretty_name', filename),
                 )
                 for dest_path, bucket_path
                 in itertools.product(file_config['destinations'], map_config['s3_bucket_paths'])
             ]
             # Creating map entries
-
             # Key must be artifact path, to avoid trampling duplicates, such
             # as public/build/target.apk and public/build/en-US/target.apk
             key = os.path.join(
                 base_artifact_prefix,
                 file_config['source_path_modifier'],
                 filename,
             )
 
             paths[key] = {
                 'destinations': destinations,
             }
             if file_config.get('checksums_path'):
                 paths[key]['checksums_path'] = file_config['checksums_path']
 
-            # Optional flags.
+            # optional flag: balrog manifest
             if file_config.get('update_balrog_manifest'):
                 paths[key]['update_balrog_manifest'] = True
                 if file_config.get('balrog_format'):
                     paths[key]['balrog_format'] = file_config['balrog_format']
 
         if not paths:
             # No files for this dependency/locale combination.
             continue
@@ -628,37 +644,193 @@ def generate_beetmover_artifact_map(conf
 
         kwargs.update({
             'locale': locale,
             'version': config.params['version'],
             'branch': config.params['project'],
             'build_number': config.params['build_number'],
             'filename_platform': platforms['filename_platform'],
             'path_platform': platforms['path_platform'],
+            'stage_platform': platforms['stage_platform'],
             'year': upload_date.year,
             'month': upload_date.strftime("%m"),  # zero-pad the month
             'upload_date': upload_date.strftime("%Y-%m-%d-%H-%M-%S")
         })
         paths = jsone.render(paths, kwargs)
         artifacts.append({
             'taskId': {'task-reference': "<{}>".format(dep)},
             'locale': locale,
             'paths': paths,
         })
 
     return artifacts
 
 
+# generate_beetmover_partials_artifact_map {{{1
+def generate_beetmover_partials_artifact_map(config, job, partials_info, **kwargs):
+    """Generate the beetmover partials artifact map.
+
+    Currently only applies to beetmover tasks.
+
+    Args:
+        config (): Current taskgraph configuration.
+        job (dict): The current job being generated
+        partials_info (dict): Current partials and information about them in a dict
+    Common kwargs:
+        platform (str): The current build platform
+        locale (str): The current locale being beetmoved.
+
+    Returns:
+        list: A list of dictionaries containing source->destination
+            maps for beetmover.
+    """
+    platform = kwargs.get('platform', '')
+    resolve_keyed_by(
+        job, 'attributes.artifact_map',
+        'artifact map',
+        project=config.params['project'],
+        platform=platform
+    )
+    map_config = load_yaml(job['attributes']['artifact_map'])
+    base_artifact_prefix = map_config.get('base_artifact_prefix', get_artifact_prefix(job))
+
+    artifacts = list()
+    dependencies = job['dependencies'].keys()
+
+    if kwargs.get('locale'):
+        locales = [kwargs['locale']]
+    else:
+        locales = map_config['default_locales']
+
+    resolve_keyed_by(map_config, 's3_bucket_paths', 's3_bucket_paths', platform=platform)
+
+    platforms = deepcopy(map_config['platform_names'])
+    if platform:
+        for key in platforms.keys():
+            resolve_keyed_by(platforms, key, key, platform=platform)
+    upload_date = datetime.fromtimestamp(config.params['build_date'])
+
+    for locale, dep in itertools.product(locales, dependencies):
+        paths = dict()
+        for filename in map_config['mapping']:
+            # Relevancy checks
+            if dep not in map_config['mapping'][filename]['from']:
+                # We don't get this file from this dependency.
+                continue
+            if locale != 'en-US' and not map_config['mapping'][filename]['all_locales']:
+                # This locale either doesn't produce or shouldn't upload this file.
+                continue
+            if 'partials_only' not in map_config['mapping'][filename]:
+                continue
+            # deepcopy because the next time we look at this file the locale will differ.
+            file_config = deepcopy(map_config['mapping'][filename])
+
+            for field in [
+                'destinations',
+                'locale_prefix',
+                'source_path_modifier',
+                'update_balrog_manifest',
+                'from_buildid',
+                'pretty_name',
+                'checksums_path'
+            ]:
+                resolve_keyed_by(file_config, field, field, locale=locale, platform=platform)
+
+            # This format string should ideally be in the configuration file,
+            # but this would mean keeping variable names in sync between code + config.
+            destinations = [
+                "{s3_bucket_path}/{dest_path}/{locale_prefix}{filename}".format(
+                    s3_bucket_path=bucket_path,
+                    dest_path=dest_path,
+                    locale_prefix=file_config['locale_prefix'],
+                    filename=file_config.get('pretty_name', filename),
+                )
+                for dest_path, bucket_path
+                in itertools.product(file_config['destinations'], map_config['s3_bucket_paths'])
+            ]
+            # Creating map entries
+            # Key must be artifact path, to avoid trampling duplicates, such
+            # as public/build/target.apk and public/build/en-US/target.apk
+            key = os.path.join(
+                base_artifact_prefix,
+                file_config['source_path_modifier'],
+                filename,
+            )
+            partials_paths = {}
+            for pname, info in partials_info.items():
+                partials_paths[key] = {
+                    'destinations': destinations,
+                }
+                if file_config.get('checksums_path'):
+                    partials_paths[key]['checksums_path'] = file_config['checksums_path']
+
+                # optional flag: balrog manifest
+                if file_config.get('update_balrog_manifest'):
+                    partials_paths[key]['update_balrog_manifest'] = True
+                    if file_config.get('balrog_format'):
+                        partials_paths[key]['balrog_format'] = file_config['balrog_format']
+                # optional flag: from_buildid
+                if file_config.get('from_buildid'):
+                    partials_paths[key]['from_buildid'] = file_config['from_buildid']
+
+                # render buildid
+                kwargs.update({
+                    'partial': pname,
+                    'from_buildid': info['buildid'],
+                    'buildid': str(config.params['moz_build_date']),
+                    'locale': locale,
+                    'version': config.params['version'],
+                    'branch': config.params['project'],
+                    'build_number': config.params['build_number'],
+                    'filename_platform': platforms['filename_platform'],
+                    'path_platform': platforms['path_platform'],
+                    'stage_platform': platforms['stage_platform'],
+                    'year': upload_date.year,
+                    'month': upload_date.strftime("%m"),  # zero-pad the month
+                    'upload_date': upload_date.strftime("%Y-%m-%d-%H-%M-%S")
+                })
+                paths.update(jsone.render(partials_paths, kwargs))
+
+        if not paths:
+            continue
+
+        artifacts.append({
+            'taskId': {'task-reference': "<{}>".format(dep)},
+            'locale': locale,
+            'paths': paths,
+        })
+
+    return artifacts
+
+
 # should_use_artifact_map {{{
 def should_use_artifact_map(platform, project):
     """Return True if this task uses the beetmover artifact map.
 
     This function exists solely for the beetmover artifact map
     migration.
     """
-    platforms = ['android', 'fennec']
     # FIXME: once we're ready to switch fully to declarative artifacts on other
-    # branches, we can expand this
+    # branches, we can expand this; for now, Fennec is rolled-out to all
+    # release branches, while Firefox only to mozilla-central
+    platforms = [
+        'android',
+        'fennec'
+    ]
     projects = ['mozilla-central', 'mozilla-beta', 'mozilla-release']
-
     if any([pl in platform for pl in platforms]) and any([pj in project for pj in projects]):
         return True
+
+    platforms = [
+        'linux-nightly',
+        'linux64-nightly',
+        'macosx64-nightly',
+        'win32-nightly',
+        'win64-nightly',
+        'win64-aarch64-nightly',
+        'win64-asan-reporter-nightly',
+        'linux64-asan-reporter-nightly',
+    ]
+    projects = ['mozilla-central']
+    if any([pl in platform for pl in platforms]) and any([pj in project for pj in projects]):
+        return True
+
     return False