Photo by Tim Mossholder

Generate an universal Apk from your Android App Bundle using Azure DevOps

Upload Android App Bundle to App Center!

Posted by Damien Aicheh on 05/05/2020 · 6 mins

Since Google introduced Android App Bundle, it becomes the new standard to distribute your Android application accross the stores. It allows us to generate a specific version of our application for any device, with only the recourses this device needs.

However for some cases you need to convert your Android App Bundle into an universal apk to be able to let your testers access the application. It’s the case if you use App Center to share your application with your testers. To do that you need to use a tool provided by Google: Bundletool, this allow to manipulate our Android App Bundle.

Introducting Bundletool Helper

When you setup your Azure DevOps pipeline you can specify a step to distribute your Android application through App Center but like mentioned before it only support apk. Also Azure DevOps does not have bundletool pre-installed on its agents.

To solve this problem I developed a new set of Azure DevOps tasks called Bundletool Helper, easy to use in your pipeline and free. This group of tasks provide a way to install the latest version of bundletool and use it to manipulate your Android App Bundle.


First of all, go to your Azure DevOps and install the Bundletool Helper extension into your organisation.

Bundletool Helper Tasks

Install Bundletool

This extension contains multiple tasks, the most important one is InstallBundletool. To use it in your azure-pipelines.yml you just have to call it like this:

- task: InstallBundletool@1
    username: 'githubUsername' # Optional but recommanded
    personalAccessToken: '$(githubPersonnalAccessToken)' # Optional but recommanded

This task will download the latest version of bundletool as a .jar.

The Github credentials are used to only read the bundletool public repository. If you don’t specify it you will be limited by the defaults rate limits of the Github API. If the limit is reached then the task will failed with this kind of message:

{“message”:”API rate limit exceeded for XXX.XXX.XXX.XXX. (But here’s the good news: Authenticated requests get a higher rate limit. Check out the documentation for more details.)”,”documentation_url”:””}

To get an access token it takes a few seconds, go to your Github account then Settings > Developer settings > Personal access tokens and click on Generate new token. Check only the public_repo access and generate it. Make sure you add it to your secure variables inside Azure DevOps so that it will not be visible during the build.

You have 3 ways to provide the bundletool jar path to use the following tasks:

  • Directly use the InstallBundletool task as we just did
  • Set the bundletoolpath variable on your agents (easy to do if you use Azure DevOps On Premise)
  • Provide the bundletool jar path directly with the bundletoolJarPath optional parameter

Convert your Android App Bundle to universal Apk

The next task available will allows us to generate an apk that can be distribute with App Center.

- task: AabConvertToUniversalApk@1
    aabFilePath: 'path/to/*.aab'
    keystoreFilePath: '$(keyStore.secureFilePath)'
    keystorePassword: '$(keystore.password)'
    keystoreAlias: '$(key.alias)'
    keystoreAliasPassword: '$(key.password)'
    outputFolder: 'path/to/folder' # Optional. Default is: $(Build.SourcesDirectory)
    bundletoolJarPath: 'path/to/bundletooljar' # Optional if you use the InstallBundletool task or set the bundletoolpath environment variable.

This task take an Android App Bundle as parameter and create an universal apk which will contains all the configurations for all devices. To generate this apk bundletool needs a keystore to sign it. To get your keystore from your secures files remember to use the DownloadSecureFile task available by default in Azure DevOps like this:

- task: DownloadSecureFile@1
  name: keyStore # Keystore variable to use to get the secure file path like above
  displayName: "Download keystore from secure files"
    secureFile: 'production.jks' # Your kestore here

Run custom commands with bundletool

Obviously you probably want to run a custom command with Bundletool that’s why I provide another task simply named Bundletool which is used just like this:

- task: Bundletool@1
    bundletoolArguments: 'version' # Default value
    bundletoolJarPath: 'path/to/bundletooljar' # Optional if you use the InstallBundletool task or set the bundletoolpath environment variable.

With this argument you will get the version of bundletool used.

Final touch

You now have the ability to build, sign and distribute your Android App Bundle with App Center and run the bundletool commands you want. As usual you will find the source code in this Github repository with a full example based on a Xamarin Android application.


Happy coding!

You liked this tutorial? Leave a star in the associated Github repository!

Do not hesitate to follow me on to not miss my next tutorial!