Programming, Life-style, Random


When I joined AsanaRebel, I picked up the project and I started to navigate through the repository, focusing especially on the build.gradle file.

Sadly, I had no CI setup to understand how to build the project on one side and, on the other side, I was facing 3 build types and 4 flavors, with not even a single line of documentation. Discomfort.

The plan: simplification

Simplification is the most complex thing to do

but I could count on a highly motivated QA team and I wanted to empower them even more, enabling them to take control on the Android release process.

My first goal was to automate the release process as much as possible, because I wanted to focus more on developing the app itself, having a lot of features to catch up with, compared to the iOS app.

As usual, when I approach new projects, the first step was to make sense out of the build.gradle file.


No joy there! 🤦‍

The good news was that when you are the only developer, there is no documentation or nobody to ask, and you are working for one of the fastest growing startup in Berlin, if you can’t make sense out of something in your project, you have any right to kill it. I mean it!

You are responsible for the code base, you are the one accountable for the status of the app, you are the one who’s gonna answer to any possible Android question from now on and you can’t afford to live with an area of your domain that you don’t know anything about, you don’t know the reasoning behind those decisions, and, even worst, if something goes south, you have no idea where to start to fix things.

Long story short,

Ciao ciao flavors

The current setup has two build types: debug and release. That’s it. No more releaseStaging or debugMockProduction nonsense:


Build server

I wanted a CI, of course. It’s a invaluable tool for any modern project and, with the plan to add more developers to the team, it was a necessary step to move forward with the right attitude: automation, safety nets and quick response.

Attempt #1: Circle CI

CircleCI was the first service I tried. They had a free tier so I could play around a bit and figure out scenarios.

It wasn’t nice, unfortunately.

The first pain point was the setup. They were, and probably still are, using a .yml file to setup the build workflow. This means that before being able to start building your project, you need to look for documentation, tutorials and examples by those who came before you and were kind enough to put that on writing. Painful.

Once you have the first draft of yml, you can start experimenting:

  1. Change something
  2. Commit and push
  3. Fingers crossed 🤞
  4. Build failed
  5. Go to 1

The Try&Error almost drove me crazy and generated this sort of git history:

CI related Git commits

You can guess my frustration. Eventually I managed to setup a successful build… kinda. I had to simplify a lot because the docker containers were failing due to not enough memory 😔

The free tier limits the available RAM in the container to 4GB, so I couldn’t run lint and anything else that would suck RAM, but at least, I had a CI.

Let’s connect it to Slack now to get build notifications!

Well, there was no ready-to-use solution available, so I had to come up with a Gradle task and some curl commands to pull the data from CircleCI and push it to Slack via Slack API. Here is a snippet:

The whole setup was working, but it was a bit flaky. Builds were still failing every now and then due to the memory problem in the container so I decided to look into it and we decided to switch to the premium plan to enable up to 8GB RAM containers.

I was pretty happy: after weeks of struggling, I was finally going to have a proper CI. Well, not really. We hit a blocker due to some undocumented change in the pricing in CircleCI. The premium plan was gone, replaced by a Performance plan with a different price bla bla bla with different performance yabba yabba…

I was pissed for the wasted time and wasted money so, living in a free world with a free market, I turned to another service.

Attempt #2: Bitrise

I created a Bitrise account, I linked GitHub. I started playing with the website and 20 minutes later I had a fully setup CI. FFS!!

No configuration file, no bullshit.

The GitHub hook allowed me to create triggers and connect triggers to workflows. Our current triggers setup is based on 4 branches:

  • master
  • develop
  • feature/*
  • hotfix/*

These triggers fire different workflows:

  • masterDeployAlpha
  • developDeployInternal
  • feature/*BuildStaging
  • hotfix/*BuildRelease

I trust your ability to infer what’s going on here, but still, let’s put some detail in. We are using Git-flow so master contains the current production release. This means that we only merge to master when the QA team and the PM give us the 👍

Once we merge to master and push it to GitHub, Bitrise kicks in:

  1. DeployAlpha workflow starts
  2. The CI pulls master
  3. It runs gradle assRel
  4. It deploys to the Google Play Store Alpha Channel
  5. It sends a Slack message to notify QA and Support team when the new build is available.

Something similar happens pushing develop, but the build ends up on the Internal Testing channel of the Play Store where I have a handful of brave colleagues that at willing to try these Internal builds. They like to live dangerously.

I also like to live dangerously

Once the new release reaches the Play Store, my work as a developer is complete and the ball is in Antonia Landi’s back yard. She is in charge of the release process: final QA approval, Alpha/Beta/Production staged roll-out, Play Store listing management and overall quality monitoring.

If something goes south, she’ll knock to my door and we start the whole process all over again.

Take aways

Having a releasing pipeline that you can trust is an incredibly powerful asset to guarantee speed, quality and resilience:

Happy releasing, people 😉

0 responses to “SHIIIIIIIP IIIIIIT!!1!1!!”

Go to top