Get Started with Appcircle
Save time, reduce costs, and increase developer productivity now.
Get informed about news, new releases, and mobile DevOps.
Learn Android app versioning rules for version numbers and build numbers, Google Play constraints, and best practices with Appcircle automation.
Android apps use two numbers to track releases: the version name (also called the marketing version) and the version code (also called the internal version code). These values must be managed carefully because Google Play requires them to follow strict rules for publishing updates.
• The version name (versionName) is what users see in the store (for example, 2.3.1). It follows Semantic Versioning principles to show whether a release is a bug fix, a new feature, or a major update.
• The version code (versionCode) is an integer that must always increase with each submission, ensuring the stores recognize it as a newer build.
Example: An app is released with version 1.2.0 (build 15). The team fixes a minor bug and publishes version 1.2.1 (build 16). Later, they add a new feature and release 1.3.0 (build 17). Android enforce that the build number increases each time, while the version number communicates the type of change to end users.
In Android, the version number is stored as versionName in the Gradle configuration. This is the marketing version shown to users in the Play Store and usually follows Semantic Versioning in the format MAJOR.MINOR.PATCH.
The version number can be set dynamically from an environment variable or taken directly from the Gradle file if Gradle is selected as the source in Appcircle. You can also apply an offset and define an increment strategy. Patch increments (for example, 1.2.3 → 1.2.4) are used for bug fixes, minor increments (1.2.3 → 1.3.0) for new features, and major increments (1.2.3 → 2.0.0) for breaking changes.
Example: A team configures Appcircle to use an environment variable for versioning with the increment strategy set to patch. If the current version is 1.4.0, the pipeline automatically increments it to 1.4.1 for the next release. Another team configures Appcircle to use the version defined in Gradle as the source. With the increment strategy set to minor, Appcircle updates the version from 2.0.0 to 2.1.0 automatically during the build. Both approaches ensure version numbers remain consistent and clearly communicate changes to end users.
In Android, the version code is stored as versionCode in the Gradle configuration. It must always increase for every release to the Play Console, even if the version name does not change.
In Appcircle, the build number can be set dynamically from an environment variable in the pipeline or taken directly from the Gradle file. You can also apply an offset to align numbering across builds and ensure uniqueness.
Example: A team sets the build number using the BUILD_ID environment variable. If the ID is 25 and the offset is 10, the final versionCode becomes 35. In another case, the developer defines versionCode 42 in build.gradle, and with the same offset applied, the published build uses 52. Both methods guarantee that every release has a unique and incrementing build number for Play Console submissions.
Google Play enforces strict versioning requirements for all Android apps submitted to the Play Console. These rules ensure that every build is uniquely identifiable and that version numbers remain consistent across releases.
Version Name (versionName):
• Should be a string. Can be described as a <major>.<minor>.<point> string or as any other type of absolute or relative version identifier. (Semantic Versioning is recommended.)
• Displayed to users in the Play Store.
• Can be a free-form string, but structured numbering is best practice.
Version Code (VersionCode):
• Must be a non-negative integer
• Must always increase with every new submission to Google Play, even if the version name remains the same.
Common pitfalls that cause rejections:
• Reusing the same version code for multiple submissions.
•Skipping increments or rolling back version codes.
• Using an invalid format for the version name that confuses users.
Example: A team uses Appcircle to automate their versioning strategy. By letting Appcircle manage both the version name and version code automatically, they ensure that every submission follows Google Play's rules. This prevents common pitfalls like reusing version codes or skipping increments, guaranteeing their apps will not be rejected from Google Play due to versioning errors.
Managing version numbers and build numbers correctly is critical to ensure smooth App Store submissions and clear communication with users. Following these best practices helps teams avoid rejections and maintain consistency across environments:
• Treat versionName as the user-facing string: Use any string format you prefer. Many teams follow Semantic Versioning for clarity, but it is not required. versionName is what users see.
• Automate version codes: Configure CI/CD pipelines to increment the build number automatically with every new submission to stay compliant with Google Play Store rules.
• Use offsets across environments: Apply offsets to keep versioning synchronized between development, staging, and production builds, which prevents conflicts when multiple pipelines run in parallel.
• Expose version info only where appropriate: Apps and publishing services should not display versionCode to users. Use versionName for display.
• Optionally base your strategy on SemVer: Google notes many developers use Semantic Versioning as a solid basis for a versioning strategy.
Example: A developer team configures Appcircle to automate their Android versioning strategy. In Gradle, they set versionName to follow Semantic Versioning and define per-flavor offsets for versionCode so development, staging, and production never collide. Appcircle reads the current values during each pipeline run, increments the versionCode automatically for every Google Play submission, and updates the versionName based on the chosen increment strategy. The result is consistent versioning across environments, clear user-facing versions in Google Play, and fewer upload errors. Developers can focus on building features and improving the app rather than worrying about versioning details or Play Console rejections.