def generate_update_line(config, jobs): """Resolve fields that can be keyed by platform, etc.""" release_config = get_release_config(config) for job in jobs: config_file = job.pop('whats-new-config') update_config = load_yaml(config_file) product = job['shipping-product'] # XXX On ESR68, even though they get filtered, we're building balrog tasks with the new # Fennec numbers. This solution is not ideal, but works at the moment. version = FennecVersion.parse(release_config['appVersion']) if product == 'devedition': product = 'firefox' job['worker']['update-line'] = {} for blob_type, suffix in [('wnp', ''), ('no-wnp', '-No-WNP')]: context = { 'release-type': config.params['release_type'], 'product': product, 'version': version, 'blob-type': blob_type, 'build-id': config.params['moz_build_date'], } job['worker']['update-line'][suffix] = generate_update_properties( context, update_config) yield job
def check_versions_are_successive(current_version, payload_version, product): """Function to check if the provided version in the payload and the existing one in bouncer are successive as valid versions.""" def _successive_sanity(current_identifier, candidate_identifier): if current_identifier == candidate_identifier: err_msg = ( "Identifiers for {} and {} can't be equal at this point " "in the code".format(payload_version, current_version)) raise ScriptWorkerTaskException(err_msg) elif current_identifier > candidate_identifier: err_msg = ("In-tree version {} can't be less than current bouncer " "counterpart".format(payload_version, current_version)) raise ScriptWorkerTaskException(err_msg) elif (candidate_identifier - current_identifier) > 1: err_msg = ( "In-tree version {} can't be greater than current bouncer " "by more than 1 digit".format(payload_version, current_version)) raise ScriptWorkerTaskException(err_msg) # XXX: for Firefox central nightlies we need to handle the major number # while for Fennec nightlies on ESR we need to handle minor_number if product == "firefox": current_bouncer_version = FirefoxVersion.parse(current_version) candidate_version = FirefoxVersion.parse(payload_version) _successive_sanity(current_bouncer_version.major_number, candidate_version.major_number) elif product == "fennec": # XXX: this will fail for the next ESR cut, on 75, since that will be a # major_number bump, but also a minor_number. But cutting ESR releases # can vary over time (could be 7 releases or 8 like ESR8, etc); # It's unrecommended to hardcode those variable window times here # in order to ensure the check; So for now we leave this code smell here. # Real fix is to centralize this operation and implement it in mozilla-version directly current_bouncer_version = FennecVersion.parse(current_version) candidate_version = FennecVersion.parse(payload_version) _successive_sanity(current_bouncer_version.minor_number, candidate_version.minor_number) else: err_msg = "Unknown product {} in the payload".format(product) raise ScriptWorkerTaskException(err_msg) log.info("Versions are successive. All good")
def test_fennec_version_supports_released_edge_cases(version_string): assert str(FennecVersion.parse(version_string)) == version_string for Class in (FirefoxVersion, DeveditionVersion, ThunderbirdVersion): if Class == FirefoxVersion and version_string in ('33.1', '33.1build1', '33.1build2'): # These edge cases also exist in Firefox continue with pytest.raises(PatternNotMatchedError): Class.parse(version_string)
def _check_version_matches_package_name(version, package_name): sanitized_version = FennecVersion.parse(version) if ( (package_name == 'org.mozilla.firefox' and sanitized_version.is_release) or # Due to project Dawn, Nightly is now using the Aurora package name. See bug 1357351. (package_name == 'org.mozilla.fennec_aurora' and sanitized_version.is_nightly) or ( # XXX Betas aren't following the regular XX.0bY format. Instead they follow XX.0 # (which looks like release). Therefore, we can't use sanitized_version.is_beta package_name == 'org.mozilla.firefox_beta' and sanitized_version.is_release and sanitized_version.minor_number == 0 # We ensure the patch_number is undefined. Calling sanitized_version.patch_number # directly raises an (expected) AttributeError and getattr(sanitized_version, 'patch_number', None) is None ) ): logger.info('Firefox version "{}" matches package name "{}"'.format(version, package_name)) else: raise BadApk('Wrong version number "{}" for package name "{}"'.format(version, package_name))
"filename": "config/milestone.txt", "version_bump": "major" }, FirefoxVersion.parse("75.0"), "76.0"), # bump_esr ({ "filename": "browser/config/version.txt", "version_bump": "minor" }, FirefoxVersion.parse("68.1.0"), "68.2.0"), ({ "filename": "browser/config/version_display.txt", "version_bump": "minor" }, FirefoxVersion.parse("68.1.0esr"), "68.2.0esr"), ({ "filename": "mobile/android/config/version-files/beta/version.txt", "version_bump": "minor" }, FennecVersion.parse("68.1"), "68.2"), ({ "filename": "mobile/android/config/version-files/beta/version_display.txt", "version_bump": "minor" }, FennecVersion.parse("68.1b9"), "68.2b1"), ({ "filename": "mobile/android/config/version-files/nightly/version.txt", "version_bump": "minor" }, FennecVersion.parse("68.1a1"), "68.2a1"), ({ "filename": "mobile/android/config/version-files/release/version.txt", "version_bump": "minor" }, FennecVersion.parse("68.6.1"), "68.7.0"),
@pytest.mark.parametrize( "product, version, expectation, result", ( ("devedition", "56.0b1", does_not_raise(), DeveditionVersion(56, 0, beta_number=1)), (Product.DEVEDITION, "56.0b1", does_not_raise(), DeveditionVersion(56, 0, beta_number=1)), ("pinebuild", "56.0b1", does_not_raise(), FirefoxVersion(56, 0, beta_number=1)), (Product.PINEBUILD, "56.0b1", does_not_raise(), FirefoxVersion(56, 0, beta_number=1)), ("fenix", "84.0.0-beta.2", does_not_raise(), FenixVersion(84, 0, 0, beta_number=2)), (Product.FENIX, "84.0.0", does_not_raise(), FenixVersion(84, 0, 0)), ("fennec", "68.2b3", does_not_raise(), FennecVersion(68, 2, beta_number=3)), (Product.FENNEC, "68.2b3", does_not_raise(), FennecVersion(68, 2, beta_number=3)), ("firefox", "45.0", does_not_raise(), FirefoxVersion(45, 0)), (Product.FIREFOX, "45.0", does_not_raise(), FirefoxVersion(45, 0)), ("thunderbird", "60.8.0", does_not_raise(), ThunderbirdVersion( 60, 8, 0)), (Product.THUNDERBIRD, "60.8.0", does_not_raise(), ThunderbirdVersion(60, 8, 0)), ("non-existing-product", "68.0", pytest.raises(ValueError), None), # fennec_release used to be a valid value when we moved Fennec to ESR68 # https://github.com/mozilla/release-services/pull/2265 # Let's be explicitly failing about it. ("fennec_release", "68.1.1", pytest.raises(ValueError), None), (Product.FOCUS_ANDROID, "95.0.1", does_not_raise(), MobileVersion(95, 0, 1)),
def test_fennec_version_bumps_raises(version_string, field): version = FennecVersion.parse(version_string) with pytest.raises(ValueError): version.bump(field)
def test_fennec_version_bumps_edge_cases(version_string, field, expected): version = FennecVersion.parse(version_string) assert str(version.bump(field)) == expected
def test_fennec_version_ends_at_68(version_string, expectation): with expectation: FennecVersion.parse(version_string)
from mozilla_version.gecko import DeveditionVersion, FennecVersion, FirefoxVersion, ThunderbirdVersion from shipit_api.admin.api import get_signoff_emails from shipit_api.admin.release import bump_version, is_eme_free_enabled, is_partner_enabled, is_rc, parse_version from shipit_api.common.models import XPISignoff from shipit_api.common.product import Product @pytest.mark.parametrize( "product, version, expectation, result", ( ("devedition", "56.0b1", does_not_raise(), DeveditionVersion(56, 0, beta_number=1)), (Product.DEVEDITION, "56.0b1", does_not_raise(), DeveditionVersion(56, 0, beta_number=1)), ("fenix", "84.0.0-beta.2", does_not_raise(), FenixVersion(84, 0, 0, beta_number=2)), (Product.FENIX, "84.0.0", does_not_raise(), FenixVersion(84, 0, 0)), ("fennec", "68.2b3", does_not_raise(), FennecVersion(68, 2, beta_number=3)), (Product.FENNEC, "68.2b3", does_not_raise(), FennecVersion(68, 2, beta_number=3)), ("firefox", "45.0", does_not_raise(), FirefoxVersion(45, 0)), (Product.FIREFOX, "45.0", does_not_raise(), FirefoxVersion(45, 0)), ("thunderbird", "60.8.0", does_not_raise(), ThunderbirdVersion(60, 8, 0)), (Product.THUNDERBIRD, "60.8.0", does_not_raise(), ThunderbirdVersion(60, 8, 0)), ("non-existing-product", "68.0", pytest.raises(ValueError), None), # fennec_release used to be a valid value when we moved Fennec to ESR68 # https://github.com/mozilla/release-services/pull/2265 # Let's be explicitly failing about it. ("fennec_release", "68.1.1", pytest.raises(ValueError), None), ), ) def test_parse_version(product, version, expectation, result): with expectation: assert parse_version(product, version) == result
from mozilla_version.gecko import ThunderbirdVersion from shipit_api.release import Product from shipit_api.release import bump_version from shipit_api.release import is_eme_free_enabled from shipit_api.release import is_partner_enabled from shipit_api.release import is_rc from shipit_api.release import parse_version @pytest.mark.parametrize('product, version, expectation, result', ( ('devedition', '56.0b1', does_not_raise(), DeveditionVersion(56, 0, beta_number=1)), (Product.DEVEDITION, '56.0b1', does_not_raise(), DeveditionVersion(56, 0, beta_number=1)), ('fennec', '68.2b3', does_not_raise(), FennecVersion(68, 2, beta_number=3)), (Product.FENNEC, '68.2b3', does_not_raise(), FennecVersion(68, 2, beta_number=3)), ('firefox', '45.0', does_not_raise(), FirefoxVersion(45, 0)), (Product.FIREFOX, '45.0', does_not_raise(), FirefoxVersion(45, 0)), ('thunderbird', '60.8.0', does_not_raise(), ThunderbirdVersion(60, 8, 0)), (Product.THUNDERBIRD, '60.8.0', does_not_raise(), ThunderbirdVersion(60, 8, 0)), ('non-existing-product', '68.0', pytest.raises(ValueError), None), )) def test_parse_version(product, version, expectation, result): with expectation: assert parse_version(product, version) == result @pytest.mark.parametrize('product, version, partial_updates, result', (
def is_firefox_version_nightly(firefox_version): version = FennecVersion.parse(firefox_version) if not (version.is_nightly or version.is_beta or version.is_release): raise ValueError('Unsupported version: {}'.format(firefox_version)) return version.is_nightly
@pytest.mark.asyncio @pytest.mark.parametrize( "version_config,current_version, expected", ( # central-to-beta ({"filename": "config/milestone.txt", "new_suffix": ""}, FirefoxVersion.parse("75.0a1"), "75.0"), ({"filename": "browser/config/version_display.txt", "new_suffix": "b1"}, FirefoxVersion.parse("75.0a1"), "75.0b1"), # beta-to-release ({"filename": "browser/config/version_display.txt", "new_suffix": ""}, FirefoxVersion.parse("75.0b9"), "75.0"), # bump_central ({"filename": "config/milestone.txt", "version_bump": "major"}, FirefoxVersion.parse("75.0a1"), "76.0a1"), ({"filename": "config/milestone.txt", "version_bump": "major"}, FirefoxVersion.parse("75.0"), "76.0"), # bump_esr ({"filename": "browser/config/version.txt", "version_bump": "minor"}, FirefoxVersion.parse("68.1.0"), "68.2.0"), ({"filename": "browser/config/version_display.txt", "version_bump": "minor"}, FirefoxVersion.parse("68.1.0esr"), "68.2.0esr"), ({"filename": "mobile/android/config/version-files/beta/version.txt", "version_bump": "minor"}, FennecVersion.parse("68.1"), "68.2"), ({"filename": "mobile/android/config/version-files/beta/version_display.txt", "version_bump": "minor"}, FennecVersion.parse("68.1b9"), "68.2b1"), ({"filename": "mobile/android/config/version-files/nightly/version.txt", "version_bump": "minor"}, FennecVersion.parse("68.1a1"), "68.2a1"), ({"filename": "mobile/android/config/version-files/release/version.txt", "version_bump": "minor"}, FennecVersion.parse("68.6.1"), "68.7.0"), ), ) async def test_create_new_version(config, mocker, version_config, current_version, expected): def mocked_get_version(path, repo_path): return current_version mocker.patch.object(merges, "get_version", new=mocked_get_version) result = merges.create_new_version(version_config, repo_path="") # Dummy repo_path, ignored. assert result == expected