Branch Strategy and Release Versioning
Keep main releasable, make releases predictable, and avoid versioning chaos
Branch Strategy and Release Versioning
Keep main releasable, make releases predictable, and avoid versioning chaos
← Part 5: Build Speed Engineering | Part 6 | Part 7: Release Automation and Play Console Delivery →
CI/CD becomes real when your team stops asking, “What are we shipping?” and starts asking, “When do we ship?”
That shift depends on two things:
- A branching strategy that keeps the codebase stable
- A versioning strategy that makes releases predictable
Android adds extra spice here because of versionCode, Play Console rules, multiple tracks, and sometimes multiple flavors. This part lays down a practical approach that works for most modern teams.
The real goal: main is always releasable
If main isn’t reliably releasable, you end up with:
- Last-minute “release fixes”
- Hidden changes piling up
- Hotfix panic
- A pipeline that can’t be trusted
Your branch strategy exists to keep main clean, not to create process theatre.

Ship with Confidence. Version with Discipline.
Branch strategy options that work in Android
Option 1: Trunk-based development
This is the modern default for many teams.
- Short-lived feature branches
- Pull requests merge into main quickly
- Main stays green and releasable
- Releases are created from main using tags
Why it works:
- Less merge pain
- Fewer long-running branches
- Faster integration
- CI stays meaningful
This is the best fit when:
- You ship regularly
- You have feature flags or staged rollouts
- You want consistent momentum
Option 2: Release branches, used sparingly
Release branches can be useful, but they’re easy to misuse.
A reasonable model:
- Main stays the integration trunk
- When you cut a release, create a short-lived
release/x.ybranch - Only stabilization fixes go into the release branch
- Main continues forward
- Tag releases from the release branch, then delete it after
This is a good fit when:
- You need longer stabilization periods
- Your org requires a formal release train
- Multiple releases may be supported at once
If release branches become permanent, you’re back in merge hell.
How to choose without overthinking
Here’s a simple rule:
- If you ship often and can do staged rollouts, prefer trunk-based
- If you ship less often or need formal stabilization windows, use short-lived release branches
Either way, don’t let branches become a substitute for quality gates. The pipeline should be doing most of the work.
The Android versioning problem
Android has a hard requirement:
versionCode must always increase for Play uploads.
It’s an integer. No cleverness. If you upload a build with a lower or equal versionCode, Play rejects it.
So your versioning strategy must make versionCode growth automatic and reliable, especially across branches, tracks, and hotfixes.
A practical strategy: semantic versionName, automatic versionCode
versionName
Use semantic versioning style:
1.4.01.4.12.0.0
Even if you don’t follow semantic versioning perfectly, this gives humans a clear handle on what shipped.
versionCode
Make it automatic. The two common approaches are:
Approach A: CI build number based
versionCodeis derived from a CI run number or timestamp- Always increases
- Easy for pipelines
Pros:
- Simple to automate
- Avoids branch collisions
Cons:
- Less meaningful locally unless you print it
Approach B: Structured versionCode from versionName
Common pattern:
- Encode major, minor, patch into an int
Example idea:
MMmmppbbbstyle, wherebbbis build increment
Pros:
- Predictable and ties to
versionName
Cons:
- Can be painful with hotfix branches and parallel releases
- Requires discipline to avoid collisions
For most teams, CI-based versionCode is the least painful.
A clean release flow: tags as the source of truth
A reliable pattern is:
- Main stays green
- When ready to ship, create a tag:
v1.4.0 - Release pipeline builds from that tag
- Pipeline uploads to Play and attaches artifacts
Why tags help:
- You can always rebuild the exact release
- It’s obvious what commit shipped
- Release notes and changelogs can reference the tag
Your release process becomes auditable without becoming bureaucratic.
Handling hotfixes without drama
Hotfixes are where many teams lose discipline.
Two reasonable hotfix models:
Hotfix model for trunk-based teams:
- Create a hotfix branch from the release tag or commit
- Apply the fix
- Tag a patch release like
v1.4.1 - Merge the hotfix back into main immediately
This keeps main aligned with what shipped.
Hotfix model with release branches:
- Create hotfix on the release branch
- Tag patch release from release branch
- Cherry-pick or merge into main
The rule stays the same: shipped fixes must land in main. Otherwise you’ll reintroduce bugs later.
Release notes and changelogs: automate what you can
People waste time writing release notes from memory. Don’t do that.
A practical approach:
- Require PR titles to follow a convention
- Generate release notes from merged PRs between tags
- Allow small manual edits at release time
Even basic automation is a win:
- Less forgotten changes
- Less “what went out?”
- Less manual busywork
You don’t need perfection. You need consistency.
Tracks and promotion strategy
Play tracks are a core part of modern release architecture.
A typical flow:
- Internal testing for validation
- Closed or open testing for broader coverage
- Production with staged rollout
Promotion can be:
- Automatic after checks, if you’re confident
- Manual, if you want a final human gate
The key is that the pipeline produces the same artifact and promotes it, rather than rebuilding new artifacts at each stage.
Rebuilds create risk. Promotions reduce risk.
Definition of done for Part 6
You’re done when:
✓ Your team has a clear branching model that keeps main releasable
✓ versionCode always increases automatically
✓ versionName is consistent and human-readable
✓ Releases are cut from tags, not from someone's laptop
✓ Hotfixes have a clear path and always get back into main
✓ Release notes are at least partially automated
Once this is in place, you have the backbone for safe automation.
Next: Release automation and Play Console delivery
Part 7 will cover:
- Building and signing release artifacts securely
- Uploading to Play tracks
- Staged rollouts and halt conditions
- Attaching mapping files and reports
- Making releases repeatable and low-stress
Series Navigation:
← Part 5: Build Speed Engineering | Part 6: Branch Strategy and Release Versioning | Part 7: Release Automation and Play Console Delivery →
메타데이터
- post_id
- cf70ca95cf9b
- slug
- branch-strategy-and-release-versioning-cf70ca95cf9b
- url
- https://medium.com/@androidmeda/branch-strategy-and-release-versioning-cf70ca95cf9b
- canonical_url
- https://medium.com/@androidmeda/branch-strategy-and-release-versioning-cf70ca95cf9b
- author_url
- https://medium.com/@androidmeda
- status
- ok
- fetched_at
- 2026-07-10 12:09:34