App Center Build, Distribute Android "debug" buildType issue
Tags: android, azure, tutorial, mobile
Published: 2021-11-28 21:28:49

If you have yet familiar with App Center Build we had discussed a bit in previous article, be sure to check it out:
{% link peterchu999/automate-build-with-app-center-3c7b %} 

## The Issue 👀
It's been a while since I have been using App Center build and came across couple of issue, one that really hinder my work were a known issue where we can't automatically distribute a build from android "debug" buildType. 

![Can't Distribute Image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t6daof1ujjb8dperzi5v.png)

For more information read it from :
{% github https://github.com/microsoft/appcenter/issues/844 %}

**TL;DR**: "debug" buildType is typically used for QA test. Because it still have code logging capability, that can help us to identify more precise causes of error. So if this are your purpose of using App Center, then the issue might become a problem.

## Work Around 🔄
Based on some googling and the issue above, here is the possible work around :
- create a new separate buildType (ex: appcenterDebug)
- download the build (.apk) then re-upload it to App Center Distribute
- create a post-build script to automate distribution.

All of the options need some hassle 😅. The easiest was obviously **download and re-upload** alternative, but then, it become less automation (the very first reason we use this tools).

In my case, a **separate builtType** make a ton of problem for managing credentials files and android permission. So it's not a suitable way out.

At the time, I work on the **create a post-build script** solution, since it's the best solution for my case.

## Distribute Automation Using Post Build Script

For those who didn't know App Center Build Script, find out more at the [documentation](https://docs.microsoft.com/en-us/appcenter/build/custom/scripts/).

**TL;DR**: it's a custom `bash` script that run during certain build stages (post-clone, pre-build & post-build).

In this cases, we want to utilize the `post-build` script that run after the `.apk` was signed & created.

### Disclaimer & Note
Admittedly, I am not good at bash script. The script below worked based on trial and error, if know the best practice or better version of the code, please leave a comment.

If you want to try the bash script locally, install `appcenter cli` by using `npm i appcenter-cli -g`.

Bash variable that start with `ENV_` is Something that we defined in App Center Build environment variable, to load it check out this [`pre-build` script](https://github.com/peterchu999/appcenter-build-test/blob/master/appcenter-pre-build.sh).


### Post Build Script

Here is the specific script that distribute our `.apk` to App Center Distribution.

{% gist https://gist.github.com/peterchu999/d4681443d8ebc860eba5a951f3aa9f6e %}

**`APPCENTER_OUTPUT_DIRECTORY`**
Variable containing the path to `.apk` file. By default App Center have populate `APPCENTER_OUTPUT_DIRECTORY`, we just need to concat `/[file-name].apk`.

**`ENV_DISTRIBUTE_MESSAGE`**
Variable containing the distribution message. 
![Distribution message](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sg2d4r3wlwdnvys2ylkj.png)
 
**`ENV_APPCENTER_BUILD_TOKEN`**
Variable containing the App Center token. It is use to authorized App Center Cli. you could generate App Center token in App Center website over `Settings > App API tokens > New API Token`. Make sure you choose **Full Access** options when the generated API Token.

![Generate App API Token Menu](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p26a4u215h024rz6w0bm.png)

**`ENV_APP_NAME `**
Variable containing App Center App Name, it is used by App Center Cli to identify which project we are working on. the easiest way is by combining your `[username]/[project name]` in the example it was `[werdnaretep99-gmail.com/App-Center-Testing-Android]`

![App Center Build URL](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xove5e43rpjimj2oe33s.png)

the other way, use App Center cli `appcenter apps list` command. it will list all of the apps name we possessed.
![App Center Cli Apps List](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bvzxshnsilw6imml7zwf.png)
 
**`ENV_DISTRIBUTE_GROUP `**
Variable containing list of distribution group separated by comma(,), ex: 'Group 1, group 2, group n'.By default App Center already make 1 distribution group which is `Collaborators`. You could make a new group on App Center website over `Distribute > Groups > Add New Group`.

![Generated New Group Menu](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9aj6kuovy87vqidugkkh.png)

**Notes**
Bear in mind, you might want to remove line 1 - 7, from the github gist code (because it contains credential, plus it's more dynamic to set distribution group and release note on ENV). for every variable start with `ENV_` must be place on App Center Environment Variable or your `.env`.

![App Center Environment Variable](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/io0ke9o8f6hal0frt554.png)
 
### Additional Post Build Script (React Native)
If we are using react native, big chances our `Android` and `iOS` repository was not separated. Once we push our `appcenter-post-build.sh` script the build will run whether we build an `Android` project and `iOS` project. this will inevitably become a problem for `iOS` build. since there is no `.apk` and the `ENV_APPCENTER_BUILD_TOKEN` different across project.

We need to make an exception, so the distribution script doesn't run when we build iOS App. My current solution is checking if default [Android Environment Variable](https://docs.microsoft.com/en-us/appcenter/build/custom/variables/) available.

{% gist https://gist.github.com/peterchu999/37890fad6888c41b20777ad81f2da083 %}


### Trick to Set Default Distribution Group
We might want to set default distribution group to all group. it's a bother if we need to manually update our `ENV_DISTRIBUTE_GROUP` when we add new group. I found out a little tricks that work on my project (but i don't know if it's a best practice).

App Center Cli provide a way to get list of our distribution group using `appcenter distribute groups list` command. there is some parameters needed for the command above to work perfectly.

{% gist https://gist.github.com/peterchu999/7cb405a3a25583b4c9c8362fa34d15e9 %}

In the code example, we get the list of distribution group as json. We need to remapped the json into string with each elements separated by comma. I used `jq` a json library to extract the list.

After a lot of trial and error work perfectly 💪🤩.

checkout the code full version on github (several branches)
{% github peterchu999/appcenter-build-test %}


## Personal Thought
The `post-script` workaround might have pros and cons depending on our cases. For example we might want to use another distribution platform like `Firebase - App Distribution`, as long as the platform accommodate cli based distribution with could use `post-script` to distribute the build. on the contrary, if we want a simple solution (not recommended), give access and ask QA to download the build (.apk) from the App Center Build directly.

Thanks for reading, constructive comment will be really appreciated ❤️ ❤️ ❤️.