Automating the Android library release process with Kotlin Scripts

Egor Neliuba
Ellation Tech
Published in
3 min readMar 7, 2019

We have a couple of proprietary libraries and tools that our Android apps at Ellation use. Releasing them was a manual process until recently when we had some time to play around with Kotlin Scripts.

What we wanted

  1. Run 1 script to cover the whole release process
  2. The script should be fail-proof (or at least has some instructions on how to recover from errors (or at least easy to understand what has failed))
  3. The script should be testable

Release process

In order to create a new release of a library or a tool, the following steps should be done:

  1. Pull the master branch and run ./gradlew build
  2. Run ./gradlew uploadArchives to publish the artifact
  3. Create a Git tag for the released version and push it to remote
  4. Prepare the next version:
    1. Increment the version name in gradle.properties
    2. Add it to the changelog file
    3. Create a branch and a commit with these changes
    4. Since all our master branches are protected, create a pull request on GitHub

Kotlin Scripts

We really wanted to find a way to incorporate the Kotlin Scripts into our release process. Although we considered writing a Gradle plugin initially, it appeared to be too “heavy-weight” for the small task we had.

We use kscript which provides support for resolving dependencies and running the script from a URL.

Result

As a result, the whole release process of any library is done by running:

kscript https://raw.githubusercontent.com/crunchyroll/android-library-release-script/master/src/main/kotlin/Release.kt

All steps of the script are split up into classes which are then called from the main function. This makes it easier to read the script and unit test different pieces in isolation (I wish, though).

Config

The CliConfig class represents all possible arguments and options that could be passed from the command line. We used xenomachina/kotlin-argparser to parse them.

Preconditions

This class tries running different command line utilities that have to be installed for the whole script to work correctly. If any of them fail, it will abort the whole procedure.

Steps

All steps are wrapped into a nice lambda in order to print a pretty report in the end if something has failed. The steps are batched in main and are executed when all have been added.

  1. Upload artifact — this is just./gradlew uploadArchives
  2. Create and push release tag
  3. Increment version in gradle.properties
  4. Update release date in the changelog
  5. Add new version to the changelog
  6. Create a commit and pull request — using thehub command line utility

Development mode

To make the script development process more convenient, we bootstrapped a simple Gradle project with the help of kscript.

The script itself lives in the src/main and since we use external dependencies in the script, we would like the IDE to know about them too. This is done by adding them to the dependencies block in the build.gradle file as usual.

What can be improved

  • End-to-end testing
    The script currently doesn’t have any end-to-end tests. This is hard to achieve as there are multiple tools used (e.g Nexus repository, GitHub).
  • Splitting up the script
    Currently, the script is one giant (300 LoC) .kt file. It would be nice to have it split up into different files.
  • Linting
    Since this script is inside a simple Gradle project, we could add tools like ktlint and detekt.

--

--