Skip to content
Notifications
Clear all

Anyone using Bitrise for production Android apps at scale?

4 Posts
4 Users
0 Reactions
11 Views
(@devops_grunt)
Honorable Member
Joined: 6 months ago
Posts: 566
Topic starter   [#25875]

We've been running our Android builds on Jenkins for about five years. The pipeline groovy scripts are a mess of conditional logic, shared libraries that no one fully understands, and flaky Docker agents. It works, but it's slow and a constant source of toil. Management is pushing for a managed SaaS solution to reduce maintenance overhead, and Bitrise keeps coming up in conversations.

I'm deeply skeptical. Our setup isn't trivial. We're talking about:
* A monorepo with 3 distinct app flavors, each with multiple build variants (debug, staging, release).
* Custom Gradle plugins we've developed internally.
* A significant suite of UI and unit tests that need to run on specific machine types.
* Artifact signing that involves fetching keys from a HashiCorp Vault cluster, not a simple env var.
* Post-build steps that push artifacts to an internal Artifactory and then trigger deployments to Firebase App Distribution and Google Play via API.

The Bitrise marketing makes it look like a few clicks, but I know the devil is in the details. My specific concerns are:

1. **Pipeline Translation:** How do you model complex, sequential+parallel stage logic in their YAML? In Jenkins we have elaborate `parallel` blocks with retry logic. Is this even possible?
2. **Secrets & Vault Integration:** Their secrets management seems env-var based. Has anyone integrated it with an external Vault? We cannot have our signing keys sitting as plaintext in any UI.
3. **Performance at Scale:** When you have 50+ devs merging PRs daily, do the queues get unmanageable? What's the actual cost for macOS medium/ large agents running for 30+ minutes per build?
4. **Custom Tooling:** How painful is it to bring your own Docker images or scripts? Our Gradle plugins require a specific environment setup.

I'm looking for concrete experiences, not sales pitches. If you've done this migration, I want to know:
* What your build complexity looked like before.
* A snippet of a non-trivial `bitrise.yml` you ended up with.
* How you handled secrets migration.
* The biggest "gotcha" that blew up your timeline.
* Whether you'd do it again.

Here's a sanitized example of the kind of logic we have in Jenkins now, to give you an idea:

```groovy
stage('Build and Test') {
parallel {
stage('Flavor A') {
steps {
sh './gradlew :app:assembleFlavorAStaging'
sh './gradlew :app:testFlavorAStagingUnitTest'
}
}
stage('Flavor B') {
steps {
sh './gradlew :app:assembleFlavorBStaging'
sh './gradlew :app:testFlavorBStagingUnitTest'
}
}
}
}
stage('Code Analysis') {
steps {
sh './gradlew sonarqube -Dsonar.branch.name=$BRANCH_NAME'
}
}
```

Can Bitrise workflows handle this pattern cleanly, or do you have to split it into multiple workflows and trigger them manually?


Automate everything. Twice.


   
Quote
(@ci_cd_plumber)
Honorable Member
Joined: 5 months ago
Posts: 510
 

Your skepticism is warranted. Moving from a bespoke Jenkins monster to a managed service is a culture shock, but it can be done.

Your specific concerns about pipeline translation are valid. Bitrise's workflow editor is visual, but the underlying config is YAML. You model sequential stages with `workflows`, and parallel steps within a stage using `before_run` lists or by spawning separate workflows. It's less flexible than raw Groovy for complex logic, but more structured. For your monorepo and multiple flavors, you'd likely use trigger maps or multiple workflows, not one giant pipeline.

The real gotcha for your setup will be the custom Gradle plugins and Vault integration. You'll need to package those plugins and host them somewhere Bitrise can pull them, like a private Maven repo. For Vault, you'll write a script step that uses the CLI/API to fetch secrets; it's not a built-in integration. That's where the initial "few clicks" promise falls apart.

If you proceed, budget twice the time you think for recreating those integrations. The reward is not having to fix a broken Docker agent at 3 AM.


Build once, deploy everywhere


   
ReplyQuote
(@data_analytics_rover)
Prominent Member
Joined: 6 months ago
Posts: 611
 

>Pipeline Translation: How do you model complex, sequential+parallel stage logic in their YAML?

You model dependencies via the `after_run` and `before_run` keys. Each workflow is a linear sequence of steps, but you can chain workflows to create a directed acyclic graph. For parallel stages, you define separate workflows triggered by the same event or by a parent workflow using triggers.

For your three app flavors, I'd suggest three independent workflows triggered by a shared start hook, running in parallel on separate stacks. The visual editor helps with this, but the YAML gets checked in - it's manageable.

The bigger translation challenge is the conditional logic from your Groovy scripts. Bitrise has environment variable-based conditionals per step, but for complex branching you might need to write wrapper scripts in your repo and call them as single Bitrise steps.



   
ReplyQuote
(@auditlog)
Honorable Member
Joined: 5 months ago
Posts: 450
 

That's a solid breakdown of the workflow chaining. I'd add a practical caveat about `after_run`: it's great for serial dependencies, but the parent workflow doesn't inherently wait for all its triggered workflows to finish. If you need a true gather point after parallel runs, you often have to implement a pattern using workflow artifacts or a final aggregator workflow, which adds another layer of YAML.

For the conditional logic problem, wrapper scripts are indeed the escape hatch, but they reintroduce the very maintenance burden you're trying to leave behind in Jenkins. Every wrapper script is a black box that bypasses Bitrise's built-in logging and audit trail. That makes compliance reviews, like tracking why a specific build step was skipped, much harder to prove.


Logs don't lie.


   
ReplyQuote