Create Xamarin.Forms Android App Bundle (aab) and release it to Google Play Store with DevOps
I’ve decided to update my DevOps CD pipeline for one of my applications to produce the aab package instead of the apk. Why you might ask? Mainly because I wanted to decrease the size of my app package, which in turn should potentially result in more downloads and/or less uninstalls.
Mikolaj Kieres
Mobile development adventurer
More posts by Mikolaj Kieres.
Mikolaj Kieres
Update: Here’s my other blog post where I share the YAML code for the below build and release pipeline
I’ve decided to update my DevOps CD pipeline for one of my applications to produce the aab package instead of the apk. Why you might ask? Mainly because I wanted to decrease the size of my app package, which in turn should potentially result in more downloads and/or less uninstalls.
Don’t take my word for it though and watch this video by Google to learn about all the reasons behind switching to aab. If that’s not enough for you, there’s a great blog post by Jon Douglas, from Xamarin team, which also lists perks of switching to aab package format. Jon also walks the reader through the basics of setting up your project to work with this «new» package format.
At the time of writing this blog post I believe that there’s no official guideline of how to create the aab package with DevOps, therefore I’ve decided to write a guide myself. There is however a great article by Dan Siegel, which I took my inspiration from.
Let’s get started!
NOTE: I started writing this blog post around 10th of Jan but haven’t fully finished it because of my laziness/lack of time. In the meantime James Montemagno beat me to it and published (15th of Jan) a really nice blog post about DevOps and aab packages. I apologise in advance for the repetition of some of the content.
Build Pipeline
Assuming that you already have a working apk build pipeline, we will need to make few changes in it, in order to generate the signed aab file (instead of the singed apk) and then make it available to our release pipeline.
Firstly, we disable the Signing and aligning APK task because it doesn’t support signing aab packages yet. We do however need to provide signed version of the aab package when uploading to Google Play Store. In order to sign the aab package we will need to update the Xamarin.Android build step with some extra msbuild arguments.
Xamarin.Android DevOps build task Xamarin.Android DevOps msbuild arguments
Significance of the above arguments can be found in the documentation, therefore I won’t be explaining them in here. Nevertheless, I think it’s worth mentioning what are the $(. ) values for these arguments and where do we get them from.
- $(KeystorePassword) — this is one of the secret variables defined in your pipeline (see below screen), which contains the *.keystore password.
KeystorePassword secret variable
- $(KeyStore.secureFilePath) — this is the *.keystore file path that is the result of the Download Secure File task (NOTE: I assume that you have already stored your *.keystore file in the Library -> Secure Files).
Download Secure File DevOps task
Lastly, we will need to update the Copy Files task to copy the aab file instead of the apk to the be used later by the release pipeline. This is as simple as changing your Contents part of the task to a wildcard expression that will match any file with the aab extension: **/*.aab .
Copy Files DevOps task
You should now have the build pipeline producing signed aab package.
Copying aab packages to the drop folder
Release Pipeline
The below instructions are written under the assumption that you either already have a release pipeline or you can create one by yourself.
Fastlane is your friend. That’s what I’ve learned when trying to upload/publish the aab package to Google Play Store using DevOps release pipeline. We will use the supply command, which is very well documented. These docs will provide you with basic examples and get you started in no time.
As you can imagine our command won’t be as simple as in the samples found in the documentation. Nevertheless, we won’t add too many parameters to it. The final result will look like this:
Fastlane supply command to publish aab to Google Play Store
Some of the parameters in the above command are self explanatory but let’s go through all of them anyway:
- —aab — it’s the path to the package file that was copied to the drop location from the build pipeline
- —json_key — the path to a JSON file containing auth information of the Google Play Service Account. More details about this parameter later in the blog post.
- —track — the release track that your package will be uploaded to. By default it’s production , therefore it is vital to provide this argument ( beta or alpha ), to avoid pushing untested builds straight to the end users.
- —rollout — it’s a value between 0 — 1, which indicates the percentage of users that the new build will be rolled out to. In my case, I’m rolling out to 100% of my beta users.
- —package_name — Your app package name.
- —skip_upload_apk — We won’t be uploading an apk file, therefore we’re skipping this step.
In the DevOps the above command can be executed with the Bash task. In my case it looks like this:
DevOps Bash task executing Fastlane supply command
Google Play Service Account
Let’s talk about the —json_key parameter in the supply Fastlane command and its value $(serviceAccountAuth.secureFilePath) . In order to upload application package to Google Play Console we need to authenticate and have sufficient permissions to do so. Google handles this authentication/authorisation process with Service Accounts.
Fastlane docs to the rescue again! After completing the steps in this document you will create yourself a Service Account, which we will be used with our Fastlane supply command. Ensure that you save the JSON key file generated with one of the steps listed in that documentation. You will need to upload that file to Library -> Secure Files in DevOps. Below are the screenshots of my service account in google dev dashboards.
If you’re done with creating your Service Account you should see similar in your dashboards:
Service Account in Google Developers Console APIs
Service Account in Google Play Console
When editing permissions for the service account, make sure that you select the correct ones. Always aim to select the minimal required permissions for a specific account. For instance, if you will only deploy apps to Beta track from DevOps, then this account doesn’t need to have permissions to production releases. See my permissions configuration, for reference:
Custom Service Account permissions
Once you’re done with setting up the Service Account, you will need to upload the generated along the way JSON key file to the Secure Files in the DevOps. Afterwards, in your release pipeline, create a Download Secure File task which will reference that newly uploaded secure file.
Download Google Play Service Account JSON auth file
The important thing to note from the above screenshot is the output variable serviceAccountAuth.secureFilePath , which will contain the path to the JSON key file, which will be used as a parameter in the supply command.
Congratulations! You should now have a Continues Delivery (i.e. CD) pipeline for you app.
Summary
It’s been a bit of a hassle to work out all of the above by myself, without any proper documentation. Nevertheless, the feeling of accomplishment once it all comes together compensates for the frustrations on the way.
I’m really glad to see that at least a blog post from James Montemagno showed up, to guide Xamarin devs on how to deal with aab packages in DevOps. It feels though as there’s still quite a bit to do in terms of documentation around this subject.
Источник
Xamarin.Android — App Bundle Settings
Hi friends,
Today I will try to explain to you how we use App Bundle management, the method of publishing the APK on Xamarin.
Basically, the Advantage of the Application Package is said to reduce the application size by 20-50%.
When our application size is reduced, different advantages arise;
- Faster downloads
- Increased download rates
- Reduced removal rates, etc.
To perform these operations, you must have at least Visual Studio 16.4. First of all, we need to make sure that our Visual Studio is up to date.
Note: I did not add the details in Step 4. If you do not know how to create an APK, it is useful to check the document here, you need to know how to sign an application package.
If you are ready, apply step by step:
Step 1
Set the Realese Mode
Step 2
Go Project Properties(Project>ProjetName properties)
Go Tab on the Android Opitons Menu > Android Package Format and select «bundle»
Step 3
Go Build Menu > Archive and wait for building.
Step 4
Click the Distribute button and save format «.aab»
It’s done..
There was a change in my application as follows:
Источник
Android app bundle xamarin
Copy raw contents
Copy raw contents
This is the Android App Bundle and bundletool integration specification for Xamarin.Android.
What are «app bundles»?
Android App Bundles are a new publishing format for Google Play that has a wide array of benefits.
You no longer have to upload multiple APKs to Google Play:
With the Android App Bundle, you build one artifact that includes all of your app’s compiled code, resources, and native libraries for your app. You no longer need to build, sign, upload, and manage version codes for multiple APKs.
«Dynamic Delivery» provides an optimized APK download from Google Play:
Google Play’s Dynamic Delivery uses your Android App Bundle to build and serve APKs that are optimized for each device configuration. This results in a smaller app download for end-users by removing unused code and resources needed for other devices.
These first two features of Android App Bundles are a natural fit for Xamarin.Android apps. The first version of bundletool support in Xamarin.Android will focus on these two benefits.
Unfortunately the next two features will be more involved. We could perhaps support them in Xamarin.Android down the road.
Support for «Instant Apps»:
Instant-enable your Android App Bundle, so that users can launch an instant app entry point module from the Try Now button on Google Play and web links without installation.
Xamarin.Android does not yet have full support for Instant Apps, in general. There would likely be some changes needed to the runtime, and there is a file size limit on the base APK size. App Bundles won’t necessarily help anything for this.
Deliver features on-demand:
Further reduce the size of your app by installing only the features that the majority of your audience use. Users can download and install dynamic features when they’re needed. Use Android Studio 3.2 to build apps with dynamic features, and join the beta program to publish them on Google Play.
For Xamarin.Android to implement this feature, I believe Instant App support is needed first.
For more information on App Bundles, visit the getting started guide.
What is bundletool ?
bundletool is the underlying command-line tool that gradle, Android Studio, and Google Play use for working with Android App Bundles.
Xamarin.Android will need to run bundletool for the following cases:
- Create an Android App Bundle from a «base» zip file
- Create an APK Set ( .apks file) from an Android App Bundle
- Deploy an APK Set ( .apks file) to a device or emulator
The help text for bundletool reads:
The source code for bundletool is on Github!
To enable app bundles, a new MSBuild property is needed:
$(AndroidPackageFormat) will default to apk for the current Xamarin.Android behavior.
Due to the various requirements for Android App Bundles, here are a reasonable set of defaults for bundletool :
Using $(AndroidPackageFormat) could impact build times, since it takes some time for bundletool to generate an app bundle and device-specific APK set to be deployed. It would make sense, in a given Xamarin.Android .csproj file to use apk for Debug builds and aab for Release builds.
The first requirement is that App Bundles require a special protobuf format for resource files that can only be produced by aapt2 . Adding the —proto-format flag to the aapt2 call produces a resources.pb file:
This command-line switch is new in aapt2 and can only be used with the version of aapt2 from Maven. We are now shipping this new version in Xamarin.Android.
Generate a base ZIP file
Once we have a resources.pb file, we must generate a base ZIP file of the following structure:
- manifest/AndroidManifest.xml : in protobuf format
- dex/ : all .dex files
- res/ : all Android resources
- assets/ : all Android assets
- lib/ : all native libraries ( .so files)
- root/ : any arbitrary files that need to go in the root of the final APK on-device. Xamarin.Android will need to put .NET assemblies in root/assemblies .
- resources.pb : the resource table in protobuf format
See the .aab format spec for further detail.
Since .NET assemblies and typemap files must remain uncompressed in Xamarin.Android apps, we will also need to specify a BundleConfig.json file:
We also must include rules for what is specified in $(AndroidStoreUncompressedFileExtensions) , which is currently a delimited list of file extensions. Prepending **/* to each extension should match the glob-pattern syntax that bundletool expects.
See details about BundleConfig.json in the app bundle documentation, or the proto3 declaration on Github.
From here we can generate a .aab file with:
It appears that app bundles use android:extractNativeLibs=»false» by default, so that native libraries remain in the APK, but stored uncompressed.
They take it even further, in that the current default behavior ( extractNativeLibs=»true» ) cannot be enabled, and is only enabled on older API levels:
A developer’s extractNativeLibs setting in AndroidManifest.xml is basically ignored. To make matters worse, on some devices the value will be set and others not. This means we cannot rely on a known value at build time.
App Bundles can only be signed with jarsigner (not apksigner ). App Bundles do not need to use zipalign . Xamarin.Android should go ahead and sign the .aab file the same as it currently does for .apk files. A com.company.app-Signed.aab file will be generated in $(OutputPath) , to match our current behavior with APK files.
Google Play has recently added support for doing the final, production signing, but Xamarin.Android should sign App Bundles with what is configured in the existing MSBuild properties.
Create a device-specific APK Set
First, we will need to invoke bundletool to create an APK set:
Running the build-apks command, generates a .apks file.
The help text for bundletool build-apks reads:
] [—connected-device] [—device-id= ] [—device-spec= ] [—key-pass= ] [—ks=
Deploy an APK set
To deploy a .apks file to a connected device:
The install-apks command will finally get the app onto the device!
The help text for bundletool install-apks reads:
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Источник