How to automate Android build process on Bitrise CI (part 2)

Hesam Kamalan
7 min readMar 30, 2016

--

Please have a look at part 1 if you have not integrated your repo into Bitrise yet. In this post I’ll focus on design of Release workflow. I assume you know how to create and modify Bitrise workflows to shorten this post. Please have a look at Manage your Bitrise workflow and The new Workflow system in case you need more info regard that.

We add Android version code and version name to our curl since we want to start Release build by curl command. Final curl command for release build looks like this (token modified, otherwise everyone in the world is able to run my release build :-) ).

$ curl https://www.bitrise.io/app/4886abd509866ee0/build/start.json — data ‘{“hook_info”:{“type”:”bitrise”,”api_token”:”MluWwLmB_5gEAtwJYHRTbB”},”build_params”:{“branch”:”master”,”workflow_id”:”release”,”environments”:[{“mapped_to”:”BUILD_VERSION_CODE”,”value”:”1",”is_expand”:true},{“mapped_to”:”BUILD_VERSION_NAME”,”value”:”1.0",”is_expand”:true}]}}’

By hitting Enter, Bitrise gets it, parse it and starts Release workflow since our workflow_id is release (I’ll talk about it later in this post), then passes version code and name to the Gradle in order to build a release apk file. Therefore, we have to modify to parts, first our Android project (particularly gradle file) and second Release workflow.

Android Project

You can find my sample project on Github. We don’t care what this project does but we care two files, Readme file and build.gradle file in app module.

  1. Readme.md: BumpVersion task is responsible to get Android version code and version name from gradle project and inject it to readme file. For more detail please have a look at Episode 38: Gradle Plugin Basics by Annyce Davis.
  2. build.gradle: everything is normal here except versionCode and versionName on lines 24 and 25. The difference is we are calling getAppVersionCode() and getAppVersionName() in order to get them rather than assign them a value manually.
build.gradle file in app module

In order to make sure our change works properly, open your terminal and run this command:

$ ./gradlew assembleDebug -PversionCode=5 -PversionName=5.0.0

The project must compile successfully and you get app-debug-5.0.0–5–0107d34.apk in your ./root/app/build/outputs/apk/ directory (your SHA would be different). It shows getAppVersionCode() and getAppVersionName() methods of build.gradle file are working properly.

In order to make sure bumpVersion task works properly too, open your terminal and run this command:

$ ./gradlew bumpVersion -PversionName=5.0 -PversionCode=5

After gradle task is done you should see the change in your readme.md file.

Readme.md file before and after running bumpVersion command

Congratulations! we are done with Android project. We add these two commands in build script -we will write- and put it into Release workflow later.

Release workflow

Open Bitrise.io site and navigate to workflow page and click on MANAGE WORKFLOW button. I assume you have Primary workflow which has been created automatically by Bitrise. Click on + sign and create a new workflow based on your Primary workflow. Rename it to release so it let us to call it later by curl command as you saw above.

Screenshot, after creating release workflow

We must add some steps to this release workflow in order to automate our build process. We will create a tag and push it to repo in last step if build is done successfully. Therefore, in first step we must check repo to see is there any tag with similar signature. If found then exit build and notify us in log otherwise continue.

Check Tag: Add an Script between Git Clone Repository and Gradle Runner. Rename it to Check Tag (or whatever you like). Add following code in it. Make sure Replace variables in input is not checked?

“If you use a Script step you should *not* enable this option — Bash will replace the variables when the script is running. Enabling it might cause issues, as that’ll replace the variables *before* the script would start.”, as mentioned by Bitrise.

#!/bin/bashecho “Version code:${BUILD_VERSION_CODE}”
echo “Version name:${BUILD_VERSION_NAME}”
# Check if the tag exists in the rev-list.
if GIT_DIR=./.git git rev-parse “${BUILD_VERSION_NAME}-${BUILD_VERSION_CODE}” >/dev/null 2>&1
then
echo “Tag with same Android version code and name found. Please change Tag name or delete current Tag.”
exit 1
fi
Check Tag step

Gradle Runner: all settings are as default except Gradle task to run.

  1. Set it to $GRADLE_TASK_RELEASE
  2. Click on App Env Vars (left panel), Add new Environment variable, call it GRADLE_TASK_RELEASE and assign it following command. This command must be familiar to you (you saw it in Android Project, above).
assembleRelease -PversionCode=${BUILD_VERSION_CODE} -PversionName=${BUILD_VERSION_NAME}
Setting GRADLE_TASK_RELEASE environment variable

It must be self explanatory what is happening in this step. Don’t forget to click on SAVE button otherwise noting get saved for you.

Click on Workflow Editor to get back to Release workflow.

I have added Findbugs Check and Gradle Unit Test steps to workflow. Nothing is special about them.

Findbugs Check and Gradle Unit Test steps

Create Tag: this is the last and most important script we add into release workflow. Add an script after Deploy To Bitrise step. Rename it to Create Tag.

Create Tag step

In this step, as it’s name suggest, we are creating a tag. But there are several things we need to care about.

  1. Check to see what is build status, we continue if build has passed.
  2. Github repo must be added as known hosts otherwise we are not able to push commit and tag.
  3. In order to push something, git must know who is pushing. Therefore, we must add username and email address.
  4. We want to push commit (due to change in readme file) and tag in one shoot. Therefore we must enable its flag in git configuration. When you push something to repo Default or Primary workflow starts. If we don’t config like this and follow normal way, we will have two pushes one for commit and the other for tag and it leads to trigger two builds on Bitrise. One push is better, isn’t it?
  5. Run bumpVersion gradle task and pass it Android version code and version name (as we tested above). The change applies in readme file. So we must commit this change in normal git way.
  6. Create annotated tag based on Android version code and version name.
  7. Push commit and tag to repo.

The script that does all of above items:

#!/bin/bashecho “Try to set version code:${BUILD_VERSION_CODE}”
echo “Try to set version name:${BUILD_VERSION_NAME}”
if [ “${BITRISE_BUILD_STATUS}” = “0” ]; then# Since we want to push, Github must be added to known hosts
ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts
# Config git since we will push a commit and tag
git config — global user.email “hesam.kamalan@grabtaxi.com
git config — global user.name “bitrise”
git config — global push.followTags true

# Trying to update README file based on latest version code and name
./gradlew bumpVersion -PversionCode=”${BUILD_VERSION_CODE}” -PversionName=”${BUILD_VERSION_NAME}”
git add README.md
git commit -m “Version code is set to ${BUILD_VERSION_CODE}, Version name is set to ${BUILD_VERSION_NAME} by ${GIT_CLONE_COMMIT_AUTHOR_NAME}”
# Trying to create annotated tag based on submitted version code and name
git tag -a “${BUILD_VERSION_NAME}-${BUILD_VERSION_CODE}” -m “The tag created by release workflow on Bitrise”
# Push commit and tag to repo
git push — follow-tags
git show “${BUILD_VERSION_NAME}-${BUILD_VERSION_CODE}”
fi

Note1: Seems Medium’s code script interpreter replaces dash by “—” which is incorrect. Double dash is correct. Please have a look at following screenshot.

Note 2: Don’t forget to *not* check Replace variables in input?

Create Tag step

WE ARE DONE!!!

Open your terminal and run your release build by curl command.

$ curl https://www.bitrise.io/app/4886abd509866ee0/build/start.json — data ‘{“hook_info”:{“type”:”bitrise”,”api_token”:”MluWwLmB_5gEAtwJYHRTbB”},”build_params”:{“branch”:”master”,”workflow_id”:”release”,”environments”:[{“mapped_to”:”BUILD_VERSION_CODE”,”value”:”1",”is_expand”:true},{“mapped_to”:”BUILD_VERSION_NAME”,”value”:”1.0",”is_expand”:true}]}}’

Once you hit Enter, you should see your build has been started in build page of Bitrise. It takes some minutes…

Release Build is in progress

You will receive email once release build is done. In your repo:

  1. Check your readme file to make sure version code and name are updated.
  2. Check your tag page to make sure the tag has been created successfully.

Supper Important: You should not push anything from your Default/Primary workflow to your repo. Otherwise your build falls in infinite loop. We are pushing from release build to repo, this push triggers Default/Primary workflow. Since we are not pushing from Primary workflow then the build process will be stopped once it is done.

Important: you can share curl command with other developers and let them create a release build. This curl command is valid as long as its token is valid. Token is valid as long as you have not regenerated token from code page. In other words, you can invalidate your current Token from code page.

Code page — How to regenerate Token

If you like this article, please hit the ♥ and share it with your friends.

--

--