def run(self, productName, version, build_number, rule_ids, backgroundRate=None): name = get_release_blob_name(productName, version, build_number, self.suffix) for rule_id in rule_ids: data = {"mapping": name} if backgroundRate: data["backgroundRate"] = backgroundRate Rule(api_root=self.api_root, auth0_secrets=self.auth0_secrets, rule_id=rule_id).update_rule(**data)
def run(self, productName, version, build_number, rule_ids, forceFallbackMappingUpdate=False, when=None, backgroundRate=None): name = get_release_blob_name(productName, version, build_number, self.suffix) if when is not None: when = arrow.get(when) soon = arrow.now().shift(minutes=5) if when is None or when < soon: when = soon for rule_id in rule_ids: data, data_version = Rule(api_root=self.api_root, auth0_secrets=self.auth0_secrets, rule_id=rule_id).get_data() # If the _currently_ shipped release is at a background rate of # 100%, it's safe to set it as the fallback mapping. (Everyone # was getting it anyways, so it's OK for them to fall back to # it if they don't get the even newer one.) # If it was _not_ shipped at 100%, we can't set it as the fallback. # If we did, it would mean users on the wrong side of the die roll # would either get the even newer release, or the release that # previously wasn't shipped to everyone - which we can't assume is # safe. # Alternatively, if we were specifically asked to update the fallback mapping, do it :) if data["backgroundRate"] == 100 or forceFallbackMappingUpdate: data["fallbackMapping"] = data["mapping"] data["mapping"] = name data["data_verison"] = data_version data["rule_id"] = rule_id data["change_type"] = "update" # We receive an iso8601 datetime, but what Balrog needs is a to-the-millisecond epoch timestamp data["when"] = when.int_timestamp * 1000 if backgroundRate: data["backgroundRate"] = backgroundRate ScheduledRuleChange(api_root=self.api_root, auth0_secrets=self.auth0_secrets, rule_id=rule_id).add_scheduled_rule_change(**data)
parser.add_argument("--to", help="New release") parser.add_argument("--client-id", help="M2M Client ID for auth") parser.add_argument("--client-secret", help="M2M Client secret for auth") parser.add_argument("--mar-dir", help="Location to put/find partial mars") parser.add_argument("--nightly", help="Treat this as a nightly partial", action="store_true") args = parser.parse_args() balrog_opts = balrog_api_opts(args.client_id, args.client_secret) name = f"{PRODUCT_NAME}-{args.to}" # get release data from Balrog target_release = Release(name=name, **balrog_opts) # if the old build is 'nightly', infer it from the nightly Balrog Rule if args.old == 'nightly': nightly_rule = Rule(NIGHTLY_RULE_ID, **balrog_opts) nightly_rule_data = nightly_rule.get_data()[0] print(f"nightly = {nightly_rule_data['mapping']}") from_release = Release(name=nightly_rule_data["mapping"], **balrog_opts) else: from_release = Release(name=f"{PRODUCT_NAME}-{args.old}", **balrog_opts) from_release_data = from_release.get_data()[0] target_release_data = target_release.get_data()[0] # traverse platforms and locales for partials to build partials = [] for platform, platform_info in target_release_data['platforms'].items(): for locale, mars in platform_info.get('locales', {}).items(): try:
build_target=get_build_target_for_platform(platform), locale=locale, **balrog_opts) url = get_update_url(args.tag, PRODUCT_NAME, app_version, locale, platform) file_hash = get_file_hash(args.mar) build_data = { "buildID": args.bid, "appVersion": app_version, "displayVersion": app_version, "completes": [{ "from": "*", "filesize": os.path.getsize(args.mar), "hashValue": file_hash, "fileUrl": url }] } print(json.dumps(build_data, indent=2)) api.update_build(product=PRODUCT_NAME, hashFunction='sha512', buildData=json.dumps(build_data), schemaVersion=9) elif args.action == 'nightly': # get the nightly Rule and update mapping nightly_rule = Rule(NIGHTLY_RULE_ID, **balrog_opts) nightly_rule.update_rule(mapping=name)