For many development teams, automating your build, testing and release processes is essential. Multiple developers on one project can lead to chaos, broken builds and failing tests. That’s why many teams run a CI server to run tests on every commit to master for example.
Releasing can be a long manual task for a developer. So we like to use services, write scripts and generally make it one button press away.
Our team, currently uses CircleCI (https://circleci.com/). It runs our tests and builds our apps. We recently set out to automatically deploy an apk to the PlayStore, to speed up our distribution process.
Google provides an API to make edits to your PlayStore listing. It can be used to upload an apk and publish it. At present, they offer a Java and Python client library. Or you can go directly through HTTP. The way we wanted to use it in combination with CircleCI meant we had to go through HTTP.
First you will need to get a service account setup which has the permissions to deploy to the PlayStore. Click here, then follow the steps under ‘Using a service account’ to get that setup.
You will need to retain the json key you created during this process.
To make any calls to an API you need to obtain an access token. To do this you call a different Google API passing it a JWT token.
You will need the following variables from your json key:
AUTH_ISS - Field ‘client_email’
AUTH_AUD - Field ‘token_uri’
AUTH_TOKEN - Field ‘private_key’
In the snippet above, we are forming a JWT from the various components required, including signing the section. Note we have set an expiry date of 300 seconds time. Having an expiry is standard practice for these tokens, and just adds a level of security.
We use the JWT to request an access token from Google. Then checking the response is a success and using jq to retrieve the token.
To begin any PlayStore deployment you need to create an edit. You can think of this as a transaction, which you commit when ready.
First we create our post data, consisting of a JSON of an id and an expiry. You can pass any id you want, it should just be unique. We use our build number (passed into script) to ensure uniqueness, whilst also providing traceability. The expiry defines how long you would like the edit to stay open, before automatically deleting. This helps to clear edits out which have failed.
Then we make our POST request to googleapis.com/androidpublisher/v3/applications/$PACKAGE_NAME/edits, capturing the results. We then check for success and retrieve the id. We use the id received from the API to ensure we have the correct one, although it should be identical to the id we posted.
Note you will need your apps package name. This can be retrieved from your apk, using the aapt tool from the Android SDK build tools.
CircleCI comes with multiple versions of build tools, so in this snippet we grab aapt from the latest one.
We now upload our apk against our edit.
Here we post our apk file to googleapis.com/upload/androidpublisher/v3/applications/$PACKAGE_NAME/edits/$EDIT_ID/apks using the id of our edit to associate it.
Next, we set our meta information on the edit. We can specify track and version code amongst other things. See link for the full spec.
https://developers.google.com/android-publisher/api-ref/edits/tracks#resource
We create our post JSON and call googleapis.com/androidpublisher/v3/applications/$PACKAGE_NAME/edits/$EDIT_ID/tracks/$PLAYSTORE_TRACK. Again checking for success.
You will need the following variables:
PLAYSTORE_TRACK - One of "alpha", "beta", "production", "rollout" or "internal"
VERSION_CODE - You can retrieve the version code from your apk
STATUS - One of "completed", "draft", "halted", "inProgress". Halted and inProgress are for staged rollouts.
The only step left is to commit your edit, meaning you have finished with this “transaction”.
We simply post to googleapis.com/androidpublisher/v3/applications/$PACKAGE_NAME/edits/$EDIT_ID:commit.
If you now head over to the PlayStore console you should see your deployment in the console.
We have put all the various pieces together into a single script, expecting certain variables to be passed in. To call this from CircleCI:
We put this script in the .circleci folder of our repository. We have stored our service account key in environment variables, named PLAYSTORE_SERVICE_KEY.
Using the PlayStore API can be quite a complex process of steps. But hopefully this script will help simplify the process you for.
https://developers.google.com/identity/protocols/OAuth2ServiceAccount#authorizingrequests - The HTTP/REST tab
https://developers.google.com/identity/protocols/OAuth2ServiceAccount#callinganapi
https://developers.google.com/android-publisher/edits/#workflow
Search over 400 blog posts from our team
Subscribe to our monthly digest of blogs to stay in the loop and come with us on our journey to make things better!