Last active
December 18, 2016 15:21
-
-
Save iocentos/cc581206b80a6e28ac7c60ee1a1db3a7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
''' | |
The following script performs unsupervised apk upload to google play console. | |
Make sure first to create a service account and store the json file somwhere safe. | |
It also uploads the mapping.txt file so that we can see crash reports in developer console. | |
First install google api publisher api | |
$ pip install google-api-python-client | |
Create service account for unsupervised api calls and give access to your android application | |
Invoke like that | |
python android-publisher.py \ | |
--client-secrets-file /path/to/secrets_file.json \ | |
--mapping-txt-file /path/to/mapping.txt \ | |
--package-name com.package.name \ | |
--apk-file /path/to/app-signed.apk \ | |
--google-play-track {alpha,beta,production} \ | |
--noauth_local_webserver | |
''' | |
from __future__ import absolute_import [46/1984] | |
import argparse | |
import os | |
import sys | |
import httplib2 | |
from googleapiclient import discovery | |
from oauth2client import client | |
from oauth2client import file | |
from oauth2client import tools | |
from oauth2client.service_account import ServiceAccountCredentials | |
# Set up arguments | |
parser = argparse.ArgumentParser(add_help=False) | |
parser.add_argument("--client-secrets-file", help="File path with client secrets", type=str, required=True) | |
parser.add_argument("--package-name", help="Package name of android application", type=str, required=True) | |
parser.add_argument("--apk-file", help="Path to the signed apk file", type=str, required=True) | |
parser.add_argument("--mapping-txt-file", help="Deobfuscation file generated for the apk", type=str, required=True) | |
parser.add_argument("--google-play-track", | |
help="Google play track to publish the application", | |
type=str, | |
required=True, | |
choices=set(("alpha", "beta", "production"))) | |
def authenticate(argv, name, version, doc, filename, scope=None, parents=[], discovery_filename=None): | |
if scope is None: | |
scope = 'https://www.googleapis.com/auth/' + name | |
# Parser command-line arguments. | |
parent_parsers = [tools.argparser] | |
parent_parsers.extend(parents) | |
parser = argparse.ArgumentParser( | |
description=doc, | |
formatter_class=argparse.RawDescriptionHelpFormatter, | |
parents=parent_parsers) | |
flags = parser.parse_args(argv[1:]) | |
credentials = ServiceAccountCredentials.from_json_keyfile_name( flags.client_secrets_file, [scope]) | |
if credentials is None or credentials.invalid: | |
credentials = tools.run_flow(flow, storage, flags) | |
http = credentials.authorize(http = httplib2.Http()) | |
if discovery_filename is None: | |
# Construct a service object via the discovery service. | |
service = discovery.build(name, version, http=http) | |
else: | |
# Construct a service object using a local discovery document file. | |
with open(discovery_filename) as discovery_file: | |
service = discovery.build_from_document( | |
discovery_file.read(), | |
base='https://www.googleapis.com/', | |
http=http) | |
return (service, flags) | |
# Main code | |
def main(argv): | |
# Authenticate and construct service. | |
service, flags = authenticate(argv, | |
'androidpublisher', | |
'v2', | |
__doc__, | |
__file__, | |
parents=[parser], | |
scope='https://www.googleapis.com/auth/androidpublisher') | |
# Process flags and read their values. | |
package_name = flags.package_name | |
apk_file = flags.apk_file | |
google_play_track = flags.google_play_track | |
mapping_txt_file = flags = flags.mapping_txt_file | |
try: | |
edit_request = service.edits().insert(body={}, packageName=package_name) | |
result = edit_request.execute() | |
edit_id = result['id'] | |
apk_response = service.edits().apks().upload( | |
editId=edit_id, | |
packageName=package_name, | |
media_body=apk_file).execute() | |
apk_version_code = apk_response['versionCode'] | |
apk_response = service.edits().deobfuscationfiles().upload( | |
editId=edit_id, | |
packageName=package_name, | |
apkVersionCode=apk_version_code, | |
deobfuscationFileType="proguard", | |
media_mime_type="application/octet-stream", | |
media_body=mapping_txt_file).execute() | |
print 'Version code %d has been uploaded' % apk_version_code | |
track_response = service.edits().tracks().update( | |
editId=edit_id, | |
track=google_play_track, | |
packageName=package_name, | |
body={u'versionCodes': [apk_version_code]}).execute() | |
print 'Track %s is set for version code(s) %s' % ( | |
track_response['track'], str(track_response['versionCodes'])) | |
commit_request = service.edits().commit( | |
editId=edit_id, packageName=package_name).execute() | |
print 'Edit "%s" has been committed' % (commit_request['id']) | |
except client.AccessTokenRefreshError: | |
print ('The credentials have been revoked or expired, please re-run the ' | |
'application to re-authorize') | |
if __name__ == '__main__': | |
main(sys.argv) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment