Esempio n. 1
0
    def __init__(self, config=None):
        Base.__init__(self, config=config)

        if self.config.track == 'rollout' and self.config.rollout_percentage is None:
            raise WrongArgumentGiven("When using track='rollout', rollout percentage must be provided too")
        if self.config.rollout_percentage is not None and self.config.track != 'rollout':
            raise WrongArgumentGiven("When using rollout-percentage, track must be set to rollout")
Esempio n. 2
0
def push_apk(apks,
             service_account,
             google_play_credentials_file,
             track,
             package_names_check,
             google_play_strings=NoGooglePlayStrings(),
             rollout_percentage=None,
             commit=True,
             contact_google_play=True,
             skip_check_ordered_version_codes=False,
             skip_check_multiple_locales=False,
             skip_check_same_locales=False,
             skip_checks_fennec=False):
    """

    Args:
        apks: list of APK files
        service_account: Google Play service account
        google_play_credentials_file: Credentials file to authenticate to Google Play
        track (str): Google Play track to deploy to (e.g.: "nightly"). If "rollout" is chosen, the parameter
            `rollout_percentage` must be specified as well
        package_names_check: Either mozapkpublisher.common.apk.checker.ExpectedPackageNamesCheck
            or mozapkpublisher.common.apk.checker.AnyPackageNamesCheck
        rollout_percentage (int): percentage of users to roll out this update to. Must be a number between [0-100].
            This option is only valid if `track` is set to "rollout"
        google_play_strings: Either `NoGooglePlayStrings`, `StoreGooglePlayStrings` or `FileGooglePlayStrings`
        commit (bool): `False` to do a dry-run
        contact_google_play (bool): `False` to avoid communicating with Google Play. Useful if you're using mock
            credentials.
        skip_checks_fennec (bool): skip Fennec-specific checks
        skip_check_same_locales (bool): skip check to ensure all APKs have the same locales
        skip_check_multiple_locales (bool): skip check to ensure all APKs have more than one locale
        skip_check_ordered_version_codes (bool): skip check to ensure that ensures all APKs have different version codes
            and that the x86 version code > the arm version code

    """
    # We want to tune down some logs, even when push_apk() isn't called from the command line
    main_logging.init()

    if track == 'rollout' and rollout_percentage is None:
        raise WrongArgumentGiven(
            "When using track='rollout', rollout percentage must be provided too"
        )
    if rollout_percentage is not None and track != 'rollout':
        raise WrongArgumentGiven(
            "When using rollout-percentage, track must be set to rollout")

    PushAPK(apks, service_account, google_play_credentials_file, track,
            package_names_check, google_play_strings, rollout_percentage,
            commit, contact_google_play, skip_check_ordered_version_codes,
            skip_check_multiple_locales, skip_check_same_locales,
            skip_checks_fennec).run()
Esempio n. 3
0
    def run(self):
        apks_paths = [apk.name for apk in self.config.apks]
        apks_metadata_per_paths = {
            apk_path: extractor.extract_metadata(apk_path)
            for apk_path in apks_paths
        }

        for package_name in [
                metadata['package_name']
                for metadata in apks_metadata_per_paths.values()
        ]:
            if not googleplay.is_valid_track_value_for_package(
                    self.config.track, package_name):
                raise WrongArgumentGiven(
                    "Track name '{}' not valid for package: {}. allowed values: {}"
                    .format(
                        self.config.track, package_name,
                        googleplay.get_valid_track_values_for_package(
                            package_name)))

        checker.cross_check_apks(apks_metadata_per_paths)

        # Each distinct product must be uploaded in different Google Play transaction, so we split them by package name here.
        split_apk_metadata = _split_apk_metadata_per_package_name(
            apks_metadata_per_paths)

        for (package_name, apks_metadata) in split_apk_metadata.items():
            if self.config.google_play_strings_file:
                l10n_strings = json.load(self.config.google_play_strings_file)
                store_l10n.check_translations_schema(l10n_strings)
                logger.info(
                    'Loaded listings and what\'s new section from "{}"'.format(
                        self.config.google_play_strings_file.name))
            elif self.config.update_google_play_strings_from_store:
                logger.info(
                    "Downloading listings and what's new section from L10n Store..."
                )
                l10n_strings = store_l10n.get_translations_per_google_play_locale_code(
                    package_name)
            elif not self.config.update_google_play_strings:
                logger.warn("Listing and what's new section won't be updated.")
                l10n_strings = None
            else:
                raise WrongArgumentGiven(
                    "Option missing. You must provide what to do in regards to Google Play strings."
                )

            self.upload_apks(apks_metadata, package_name, l10n_strings)
Esempio n. 4
0
    def run(self):
        # Matching version codes will be added during runtime.
        apks = {
            'armv7_v15': {
                'file': self.config.apk_file_armv7_v15.name,
            },
            'x86': {
                'file': self.config.apk_file_x86.name,
            },
        }

        if self.config.google_play_strings_file:
            l10n_strings = json.load(self.config.google_play_strings_file)
            store_l10n.check_translations_schema(l10n_strings)
            logger.info('Loaded listings and what\'s new section from "{}"'.format(self.config.google_play_strings_file.name))
        elif self.config.update_google_play_strings_from_store:
            logger.info("Downloading listings and what's new section from L10n Store...")
            l10n_strings = store_l10n.get_translations_per_google_play_locale_code(self.config.package_name)
        elif not self.config.update_google_play_strings:
            logger.warn("Listing and what's new section won't be updated.")
            l10n_strings = None
        else:
            raise WrongArgumentGiven("Option missing. You must provide what to do in regards to Google Play strings.")

        self.upload_apks(apks, l10n_strings)
Esempio n. 5
0
    def run(self):
        apks_paths = [apk.name for apk in self.config.apks]
        apks_metadata_per_paths = {
            apk_path: extractor.extract_metadata(apk_path)
            for apk_path in apks_paths
        }

        checker.cross_check_apks(apks_metadata_per_paths)
        package_name = list(
            apks_metadata_per_paths.values())[0]['package_name']

        if self.config.google_play_strings_file:
            l10n_strings = json.load(self.config.google_play_strings_file)
            store_l10n.check_translations_schema(l10n_strings)
            logger.info(
                'Loaded listings and what\'s new section from "{}"'.format(
                    self.config.google_play_strings_file.name))
        elif self.config.update_google_play_strings_from_store:
            logger.info(
                "Downloading listings and what's new section from L10n Store..."
            )
            l10n_strings = store_l10n.get_translations_per_google_play_locale_code(
                package_name)
        elif not self.config.update_google_play_strings:
            logger.warn("Listing and what's new section won't be updated.")
            l10n_strings = None
        else:
            raise WrongArgumentGiven(
                "Option missing. You must provide what to do in regards to Google Play strings."
            )

        self.upload_apks(apks_metadata_per_paths, package_name, l10n_strings)
Esempio n. 6
0
    def _update_track(self, track, version_codes, rollout_percentage=None):
        if track == 'rollout' and rollout_percentage is None:
            raise WrongArgumentGiven(
                "To perform a rollout, you must provide the target track "
                "(probably 'production') and a rollout_percentage")
        if rollout_percentage is not None:
            if track == 'rollout':
                logger.warn(
                    "track='rollout' is deprecated, assuming you meant 'production'. To avoid "
                    "this message, specify the target track to roll out to (probably 'production'"
                )
                track = 'production'
            if rollout_percentage < 0 or rollout_percentage > 100:
                raise WrongArgumentGiven(
                    'rollout percentage must be between 0 and 100. Value given: {}'
                    .format(rollout_percentage))

            release = {
                u'status': 'inProgress',
                u'userFraction':
                rollout_percentage / 100.0,  # Ensure float in Python 2
                u'versionCodes': version_codes,
            }
        else:
            release = {u'status': 'completed', u'versionCodes': version_codes}

        body = {
            u'releases': [release],
            u'track': track,
        }

        response = self._edit_resource.tracks().update(
            editId=self._edit_id,
            track=track,
            packageName=self._package_name,
            body=body).execute()
        logger.info('Track "{}" updated with: {}'.format(track, body))
        logger.debug('Track update response: {}'.format(response))
Esempio n. 7
0
    def update_track(self, track, version_codes, rollout_percentage=None):
        body = {u'versionCodes': version_codes}
        if rollout_percentage is not None:
            if rollout_percentage < 0 or rollout_percentage > 100:
                raise WrongArgumentGiven(
                    'rollout percentage must be between 0 and 100. Value given: {}'
                    .format(rollout_percentage))

            body[
                u'userFraction'] = rollout_percentage / 100.0  # Ensure float in Python 2

        response = self._service.tracks().update(
            editId=self._edit_id,
            track=track,
            packageName=self._package_name,
            body=body).execute()
        logger.info('Track "{}" updated with: {}'.format(track, body))
        logger.debug('Track update response: {}'.format(response))
Esempio n. 8
0
 def error(self, message):
     raise WrongArgumentGiven(message)