-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Switch to google-auth lib for authentication (bug 1864638) #252
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,27 +37,17 @@ source venv/bin/activate | |
* `sudo ln -s /usr/local/Cellar/openssl/1.0.2j/include/openssl/ /usr/local/include/openssl` | ||
5. Restore original permissions on /usr/local/bin: | ||
* `sudo chown root:wheel /usr/local` | ||
1. Some errors might happen when executing `mozapkpublisher/push_apk.py` | ||
1. You might have errors like | ||
* Errors in from_p12_keyfile in oauth2client/service_account.py or | ||
* ImportError: cannot import name `_openssl_crypt` | ||
* `pip uninstall oauth2client` | ||
* `pip install oauth2client==2.0.0` | ||
* `pip install google-api-python-client==1.5.0` | ||
1. Symbol not found: `_BIO_new_CMS` | ||
* `pip uninstall cryptography` | ||
* `LDFLAGS="-L/usr/local/opt/openssl/lib" pip install cryptography --no-use-wheel` | ||
Comment on lines
-40
to
-49
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Glad to see these lines gone |
||
|
||
## What to do when pushapk_scriptworker doesn't work? | ||
|
||
> A guide to manually publish APKs onto Google Play Store | ||
|
||
1. Generate a Google Play Store p12 certificate. This certificate needs to have write access to the app you want to publish. In this context, "app" means Fennec, Fennec Beta or Fennec Nightly. | ||
1. Generate a Google Play Store json certificate. This certificate needs to have write access to the app you want to publish. In this context, "app" means Fennec, Fennec Beta or Fennec Nightly. | ||
1. Execute the steps defined in the section above. | ||
1. Download the latest signed builds. For instance, for Fennec Nightly: `./mozapkpublisher/get_apk.py --latest-nightly` | ||
1. | ||
```sh | ||
./mozapkpublisher/push_apk.py --no-gp-string-update --track beta --credentials /path/to/your/googleplay/creds.p12 --service-account [email protected] x86.apk arm.apk | ||
./mozapkpublisher/push_apk.py --no-gp-string-update --track beta --credentials /path/to/your/googleplay/creds.json x86.apk arm.apk | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Much cleaner! |
||
``` | ||
|
||
* Note `beta` track on Google Play, that's our way to show to people on Play Store that it's not a finished product. We don't use the "production" track for Nightly, unlike beta and release. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,14 @@ | ||
from contextlib import contextmanager | ||
|
||
import httplib2 | ||
import json | ||
import logging | ||
|
||
import google.auth | ||
import httplib2 | ||
|
||
from apiclient.discovery import build | ||
from oauth2client.service_account import ServiceAccountCredentials | ||
from googleapiclient.errors import HttpError | ||
from google.oauth2 import service_account | ||
# HACK: importing mock in production is useful for option `--do-not-contact-google-play` | ||
from unittest.mock import MagicMock | ||
|
||
|
@@ -16,16 +18,15 @@ | |
|
||
|
||
def add_general_google_play_arguments(parser): | ||
parser.add_argument('--service-account', help='The service account email', required=True) | ||
parser.add_argument('--credentials', dest='google_play_credentials_filename', | ||
help='The p12 authentication file', required=True) | ||
help='The json authentication file', required=True) | ||
|
||
parser.add_argument('--commit', action='store_true', | ||
help='Commit changes onto Google Play. This action cannot be reverted.') | ||
parser.add_argument('--do-not-contact-google-play', action='store_false', dest='contact_google_play', | ||
help='''Prevent any request to reach Google Play. Use this option if you want to run the script | ||
without any valid credentials nor valid APKs. In fact, Google Play may error out at the first invalid piece of data sent. | ||
--service-account and --credentials must still be provided (you can just fill them with random string and file).''') | ||
--credentials must still be provided (you can pass a random file name).''') | ||
|
||
|
||
class _ExecuteDummy: | ||
|
@@ -186,8 +187,8 @@ def update_whats_new(self, language, apk_version_code, whats_new): | |
|
||
@staticmethod | ||
@contextmanager | ||
def transaction(service_account, credentials_file_name, package_name, *, contact_server, dry_run): | ||
edit_resource = _create_google_edit_resource(contact_server, service_account, credentials_file_name) | ||
def transaction(credentials_file_name, package_name, *, contact_server, dry_run): | ||
edit_resource = _create_google_edit_resource(contact_server, credentials_file_name) | ||
edit_id = edit_resource.insert(body={}, packageName=package_name).execute()['id'] | ||
google_play = GooglePlayEdit(edit_resource, edit_id, package_name) | ||
yield google_play | ||
|
@@ -199,23 +200,16 @@ def transaction(service_account, credentials_file_name, package_name, *, contact | |
logger.warning('Transaction not committed, since `dry_run` was `True`') | ||
|
||
|
||
def _create_google_edit_resource(contact_google_play, service_account, credentials_file_name): | ||
def _create_google_edit_resource(contact_google_play, credentials_file_name): | ||
if contact_google_play: | ||
# Create an httplib2.Http object to handle our HTTP requests an | ||
# authorize it with the Credentials. Note that the first parameter, | ||
# service_account_name, is the Email address created for the Service | ||
# account. It must be the email address associated with the key that | ||
# was created. | ||
scope = 'https://www.googleapis.com/auth/androidpublisher' | ||
credentials = ServiceAccountCredentials.from_p12_keyfile( | ||
service_account, | ||
credentials = service_account.Credentials.from_service_account_file( | ||
credentials_file_name, | ||
scopes=scope | ||
scopes=[scope], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
) | ||
http = httplib2.Http() | ||
http = credentials.authorize(http) | ||
|
||
service = build(serviceName='androidpublisher', version='v3', http=http, | ||
service = build(serviceName='androidpublisher', version='v3', | ||
credentials=credentials, | ||
cache_discovery=False) | ||
|
||
return service.edits() | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,9 +24,6 @@ | |
aab2 = NamedTemporaryFile() | ||
|
||
AABS = [aab1, aab2] | ||
SERVICE_ACCOUNT = '[email protected]' | ||
CLIENT_ID = 'client' | ||
CLIENT_SECRET = 'secret' | ||
|
||
|
||
def patch_extract_metadata(monkeypatch): | ||
|
@@ -54,7 +51,7 @@ def patch_store_transaction(monkeypatch_, patch_target): | |
mock_edit = create_autospec(patch_target) | ||
|
||
@contextmanager | ||
def fake_transaction(_, __, ___, *, contact_server, dry_run): | ||
def fake_transaction(_, __, *, contact_server, dry_run): | ||
yield mock_edit | ||
|
||
monkeypatch_.setattr(patch_target, 'transaction', fake_transaction) | ||
|
@@ -64,7 +61,7 @@ def fake_transaction(_, __, ___, *, contact_server, dry_run): | |
def test_google(monkeypatch): | ||
mock_metadata = patch_extract_metadata(monkeypatch) | ||
edit_mock = patch_store_transaction(monkeypatch, store.GooglePlayEdit) | ||
push_aab(AABS, SERVICE_ACCOUNT, credentials, 'production', rollout_percentage=50, | ||
push_aab(AABS, credentials, 'production', rollout_percentage=50, | ||
contact_server=False) | ||
edit_mock.update_aab.assert_called_once_with([ | ||
(aab1, mock_metadata[aab1]), | ||
|
@@ -78,7 +75,7 @@ def test_push_aab_tunes_down_logs(monkeypatch): | |
monkeypatch.setattr('mozapkpublisher.push_aab.extract_aabs_metadata', MagicMock()) | ||
monkeypatch.setattr('mozapkpublisher.common.utils.metadata_by_package_name', MagicMock()) | ||
|
||
push_aab(AABS, SERVICE_ACCOUNT, credentials, 'alpha', contact_server=False) | ||
push_aab(AABS, credentials, 'alpha', contact_server=False) | ||
|
||
main_logging_mock.init.assert_called_once_with() | ||
|
||
|
@@ -94,7 +91,6 @@ def test_main_google(monkeypatch): | |
file = os.path.join(os.path.dirname(__file__), 'data', 'blob') | ||
fail_manual_validation_args = [ | ||
'script', | ||
'--username', '[email protected]', | ||
'--secret', file, | ||
'alpha', | ||
file, | ||
|
@@ -106,7 +102,6 @@ def test_main_google(monkeypatch): | |
|
||
mock_push_aab.assert_called_once_with( | ||
ANY, | ||
'[email protected]', | ||
file, | ||
'alpha', | ||
None, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!