Bug 1482395: [mozrelease] Add support for generating update metadata; r=mtabara
authorTom Prince <mozilla@hocat.ca>
Tue, 27 Nov 2018 18:47:14 +0000
changeset 504781 b09a44bf41cb77963e1adbd15adfbd3996dcabb2
parent 504780 f78fcb8e46d46dc15b1eead4a817b8f3d1f981dc
child 504782 3bf6a4a7e135ef3df9ac432097fea323d7b86668
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmtabara
bugs1482395
milestone65.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 1482395: [mozrelease] Add support for generating update metadata; r=mtabara Differential Revision: https://phabricator.services.mozilla.com/D12707
python/mozrelease/mozrelease/balrog.py
python/mozrelease/mozrelease/util.py
python/mozrelease/test/data/Firefox-62.0.3.update.json
python/mozrelease/test/data/Firefox-62.0b11-update.json
python/mozrelease/test/data/Firefox-62.0b11.update.json
python/mozrelease/test/data/whatsnew-62.0.3.yml
python/mozrelease/test/data/whatsnew-release.yml
python/mozrelease/test/python.ini
python/mozrelease/test/test_balrog.py
taskcluster/ci/source-test/python.yml
new file mode 100644
--- /dev/null
+++ b/python/mozrelease/mozrelease/balrog.py
@@ -0,0 +1,66 @@
+# -*- coding: utf-8 -*-
+# 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/.
+
+from __future__ import absolute_import, print_function, unicode_literals
+
+
+def _generate_show_url(context, entry):
+    url = entry['url']
+    return {
+        "actions": "showURL",
+        "openURL": url.format(**context),
+    }
+
+
+def _generate_product_details(context, entry):
+    url = entry['url']
+    return {
+        'detailsURL': url.format(**context),
+        'type': 'minor',
+    }
+
+
+_FIELD_TYPES = {
+    'show-url': _generate_show_url,
+    'product-details': _generate_product_details,
+}
+
+
+def _generate_conditions(context, entry):
+    if 'release-types' in entry and context['release-type'] not in entry['release-types']:
+        return None
+    if 'blob-types' in entry and context['blob-type'] not in entry['blob-types']:
+        return None
+    if 'products' in entry and context['product'] not in entry['products']:
+        return None
+
+    conditions = {}
+    if 'locales' in entry:
+        conditions['locales'] = entry['locales']
+    if 'versions' in entry:
+        conditions['versions'] = [
+            version.format(**context)
+            for version in entry['versions']
+        ]
+    if 'update-channel' in entry:
+        conditions['channels'] = [
+            entry['update-channel'] + suffix
+            for suffix in ('', '-localtest', '-cdntest')
+        ]
+    return conditions
+
+
+def generate_update_properties(context, config):
+    result = []
+    for entry in config:
+        fields = _FIELD_TYPES[entry['type']](context, entry)
+        conditions = _generate_conditions(context, entry.get('conditions', {}))
+
+        if conditions is not None:
+            result.append({
+                'fields': fields,
+                'for': conditions,
+            })
+    return result
new file mode 100644
--- /dev/null
+++ b/python/mozrelease/mozrelease/util.py
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+# 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/.
+
+from __future__ import absolute_import, print_function, unicode_literals
+
+from yaml.loader import SafeLoader
+
+
+class UnicodeLoader(SafeLoader):
+    def construct_yaml_str(self, node):
+        return self.construct_scalar(node)
+
+
+UnicodeLoader.add_constructor(
+    'tag:yaml.org,2002:str',
+    UnicodeLoader.construct_yaml_str)
+
+
+def load(stream):
+    """
+    Parse the first YAML document in a stream
+    and produce the corresponding Python object.
+    """
+    loader = UnicodeLoader(stream)
+    try:
+        return loader.get_single_data()
+    finally:
+        loader.dispose()
new file mode 100644
--- /dev/null
+++ b/python/mozrelease/test/data/Firefox-62.0.3.update.json
@@ -0,0 +1,74 @@
+[
+    {
+        "fields": {
+            "detailsURL": "https://www.mozilla.org/%LOCALE%/firefox/62.0.3/releasenotes/",
+            "type": "minor"
+        },
+        "for": {}
+    },
+    {
+        "fields": {
+            "actions": "showURL",
+            "openURL": "https://www.mozilla.org/%LOCALE%/firefox/62.0.3/whatsnew/?oldversion=%OLD_VERSION%"
+        },
+        "for": {
+            "channels": [
+                "release",
+                "release-localtest",
+                "release-cdntest"
+            ],
+            "locales": [
+                "cak",
+                "cy",
+                "da",
+                "de",
+                "dsb",
+                "en-CA",
+                "en-US",
+                "es-AR",
+                "es-CL",
+                "es-ES",
+                "es-MX",
+                "et",
+                "fa",
+                "fi",
+                "fr",
+                "fy-NL",
+                "gn",
+                "gu-IN",
+                "hsb",
+                "hu",
+                "ia",
+                "id",
+                "it",
+                "ja",
+                "ja-JP-mac",
+                "ka",
+                "kab",
+                "ko",
+                "lij",
+                "lt",
+                "ms",
+                "nb-NO",
+                "nl",
+                "nn-NO",
+                "pl",
+                "pt-BR",
+                "pt-PT",
+                "sk",
+                "sl",
+                "sq",
+                "sr",
+                "sv-SE",
+                "tr",
+                "uk",
+                "vi",
+                "zh-CN",
+                "zh-TW"
+            ],
+            "versions": [
+                "<62.0"
+            ]
+        }
+    }
+]
new file mode 100644
--- /dev/null
+++ b/python/mozrelease/test/data/Firefox-62.0b11-update.json
@@ -0,0 +1,74 @@
+[
+    {
+        "fields": {
+            "detailsURL": "https://www.mozilla.org/%LOCALE%/firefox/62.0.3/releasenotes/",
+            "type": "minor"
+        },
+        "for": {}
+    },
+    {
+        "fields": {
+            "actions": "showURL",
+            "openURL": "https://www.mozilla.org/%LOCALE%/firefox/62.0.3/whatsnew/?oldversion=%OLD_VERSION%"
+        },
+        "for": {
+            "channels": [
+                "release",
+                "release-localtest",
+                "release-cdntest"
+            ],
+            "locales": [
+                "cak",
+                "cy",
+                "da",
+                "de",
+                "dsb",
+                "en-CA",
+                "en-US",
+                "es-AR",
+                "es-CL",
+                "es-ES",
+                "es-MX",
+                "et",
+                "fa",
+                "fi",
+                "fr",
+                "fy-NL",
+                "gn",
+                "gu-IN",
+                "hsb",
+                "hu",
+                "ia",
+                "id",
+                "it",
+                "ja",
+                "ja-JP-mac",
+                "ka",
+                "kab",
+                "ko",
+                "lij",
+                "lt",
+                "ms",
+                "nb-NO",
+                "nl",
+                "nn-NO",
+                "pl",
+                "pt-BR",
+                "pt-PT",
+                "sk",
+                "sl",
+                "sq",
+                "sr",
+                "sv-SE",
+                "tr",
+                "uk",
+                "vi",
+                "zh-CN",
+                "zh-TW"
+            ],
+            "versions": [
+                "<62.0"
+            ]
+        }
+    }
+]
new file mode 100644
--- /dev/null
+++ b/python/mozrelease/test/data/Firefox-62.0b11.update.json
@@ -0,0 +1,9 @@
+[
+    {
+        "fields": {
+            "detailsURL": "https://www.mozilla.org/%LOCALE%/firefox/62.0b11/releasenotes/",
+            "type": "minor"
+        },
+        "for": {}
+    }
+]
new file mode 100644
--- /dev/null
+++ b/python/mozrelease/test/data/whatsnew-62.0.3.yml
@@ -0,0 +1,65 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+---
+- type: product-details
+  url: "https://www.mozilla.org/%LOCALE%/{product}/{version}/releasenotes/"
+# %LOCALE% is automatically replaced by Balrog.
+- type: show-url
+  # yamllint disable-line rule:line-length
+  url: "https://www.mozilla.org/%LOCALE%/{product}/{version}/whatsnew/?oldversion=%OLD_VERSION%"
+  conditions:
+      release-types: [release]
+      products: [firefox]
+      update-channel: release
+      # e.g.: ["<61.0"]. {version.major_number} reflects the current version.
+      # This is done by taskgraph.
+      versions: ["<{version.major_number}.0"]
+      locales:
+          - cak
+          - cy
+          - da
+          - de
+          - dsb
+          - en-CA
+          - en-US
+          - es-AR
+          - es-CL
+          - es-ES
+          - es-MX
+          - et
+          - fa
+          - fi
+          - fr
+          - fy-NL
+          - gn
+          - gu-IN
+          - hsb
+          - hu
+          - ia
+          - id
+          - it
+          - ja
+          - ja-JP-mac
+          - ka
+          - kab
+          - ko
+          - lij
+          - lt
+          - ms
+          - nb-NO
+          - nl
+          - nn-NO
+          - pl
+          - pt-BR
+          - pt-PT
+          - sk
+          - sl
+          - sq
+          - sr
+          - sv-SE
+          - tr
+          - uk
+          - vi
+          - zh-CN
+          - zh-TW
new file mode 100644
--- /dev/null
+++ b/python/mozrelease/test/data/whatsnew-release.yml
@@ -0,0 +1,65 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+---
+- type: product-details
+  url: "https://www.mozilla.org/%LOCALE%/{product}/{version}/releasenotes/"
+# %LOCALE% is automatically replaced by Balrog.
+- type: show-url
+  # yamllint disable-line rule:line-length
+  url: "https://www.mozilla.org/%LOCALE%/{product}/{version}/whatsnew/?oldversion=%OLD_VERSION%"
+  conditions:
+      release-types: [release]
+      products: [firefox]
+      update-channel: release
+      # e.g.: ["<61.0"]. {version.major_number} reflects the current version.
+      # This is done by taskgraph.
+      versions: ["<{version.major_number}.0"]
+      locales:
+          - cak
+          - cy
+          - da
+          - de
+          - dsb
+          - en-CA
+          - en-US
+          - es-AR
+          - es-CL
+          - es-ES
+          - es-MX
+          - et
+          - fa
+          - fi
+          - fr
+          - fy-NL
+          - gn
+          - gu-IN
+          - hsb
+          - hu
+          - ia
+          - id
+          - it
+          - ja
+          - ja-JP-mac
+          - ka
+          - kab
+          - ko
+          - lij
+          - lt
+          - ms
+          - nb-NO
+          - nl
+          - nn-NO
+          - pl
+          - pt-BR
+          - pt-PT
+          - sk
+          - sl
+          - sq
+          - sr
+          - sv-SE
+          - tr
+          - uk
+          - vi
+          - zh-CN
+          - zh-TW
--- a/python/mozrelease/test/python.ini
+++ b/python/mozrelease/test/python.ini
@@ -1,6 +1,8 @@
 [DEFAULT]
 subsuite=mozrelease
-skip-if = python == 3
 
 [test_versions.py]
+skip-if = python == 3
+[test_balrog.py]
 [test_buglist_creator.py]
+skip-if = python == 3
new file mode 100644
--- /dev/null
+++ b/python/mozrelease/test/test_balrog.py
@@ -0,0 +1,43 @@
+# -*- coding: utf-8 -*-
+# 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/.
+
+from __future__ import absolute_import, print_function, unicode_literals
+
+import mozunit
+import pytest
+
+import json
+from mozrelease.util import load as yaml_load
+from pathlib2 import Path
+
+from mozrelease.balrog import generate_update_properties
+from mozilla_version.gecko import GeckoVersion
+
+DATA_PATH = Path(__file__).parent.joinpath('data')
+
+
+@pytest.mark.parametrize('context,config_file,output_file', [
+    ({
+        'release-type': 'release',
+        'product': 'firefox',
+        'version': GeckoVersion.parse('62.0.3'),
+    }, 'whatsnew-62.0.3.yml', 'Firefox-62.0.3.update.json'),
+    ({
+        'release-type': 'beta',
+        'product': 'firefox',
+        'version': GeckoVersion.parse('62.0b11'),
+    }, 'whatsnew-62.0.3.yml', 'Firefox-62.0b11.update.json'),
+])
+def test_update_properties(context, config_file, output_file):
+    with DATA_PATH.joinpath(config_file).open('r', encoding='utf-8') as f:
+        config = yaml_load(f)
+
+    update_line = generate_update_properties(context, config)
+
+    assert update_line == json.load(DATA_PATH.joinpath(output_file).open('r', encoding='utf-8'))
+
+
+if __name__ == '__main__':
+    mozunit.main()
--- a/taskcluster/ci/source-test/python.yml
+++ b/taskcluster/ci/source-test/python.yml
@@ -123,17 +123,17 @@ mozlint:
         subsuite: mozlint
     when:
         files-changed:
             - 'python/mozlint/**'
             - 'tools/lint/**'
 
 mozrelease:
     description: python/mozrelease unit tests
-    python-version: [2]
+    python-version: [2, 3]
     treeherder:
         symbol: release
     run:
         using: python-test
         subsuite: mozrelease
     when:
         files-changed:
             - 'python/mozrelease/**'