# Automatic build versioning

> How to set a new build number to push to app stores



If you are going to publish your app to **App Store Connect** or **Google Play**, each uploaded artifact must have a new version satisfying each app store's requirements. You'll need to devise a build versioning strategy that satisfies the App Store and/or Google Play Store versioning requirements and works for your team's development processes. On this page, we will explain the App Store and Google Play build versioning requirements, how the Flutter framework generalizes build versioning, and various strategies to set your build versions using Codemagic. See the [build versioning codemagic blog article](https://blog.codemagic.io/build-versioning-with-codemagic/) for a detailed overview.

{{< youtube UezlgmCZLcU >}}

## Overview of Build Versioning Requirements

#### App Store Connect Requirements

The main values for iOS & macOS versioning are `CFBundleShortVersionString` (Release Version Number) and `CFBundleVersion` (Build Version Number). The best explanation of these two values, despite being outdated, is Apple's technical note on [Version Numbers and Build Numbers](https://developer.apple.com/library/archive/technotes/tn2420/_index.html).

[CFBundleShortVersionString](https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleshortversionstring), Release Version Number, is the external user facing release version of your app displayed in the App Store. It must follow the `{major}.{minor}.{patch}` version format of three period separated integers. This must be incremented every time you release a version to the App Store. It's advisable to commit this value to version control and update it for every new release of your app to the App Store.

[CFBundleVersion](https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleversion), Build Version Number, is the internal build version number of your application used for testing and development. It appears in `{major}.{minor}.{patch}` format of one to three period separated integers. If {minor}.{patch} are not provided, then they will default to zero. Build version number must be incremented with every release candidate submitted to TestFlight for a particular release version number. For iOS, build version number can be reused across different release version numbers while for macOS, build version number must be unique across all release version numbers. This value is best incremented and set by your CI/CD pipeline for every build you're submitting to TestFlight.


#### Google Play Requirements

You can find the Google Play build versioning requirements in the [Android documentation](https://developer.android.com/studio/publish/versioning#appversioning). The important values defined in the build.gradle file are `versionName` and `versionCode`.

`versionName` is a text based, external, version of your app that is displayed to users and visible in Google Play. There are no restrictions for `versionName`, so you should choose something that makes sense for you and your users, such as `{major}.{minor}.{patch}` versioning. It's advisable to commit this value to version control and update it for every new release of your app to the Play Store.

`versionCode` is an internal version of your app that must be an integer value between `1` and `2100000000`. This must be incremented for every build you upload to Google Play. This value is best incremented and set by your CI/CD pipeline for every build.


#### Flutter Build Versioning

Flutter generalizes iOS and Android build versioning with the [pubspec.yaml **version** property](https://github.com/flutter/flutter/blob/master/packages/flutter_tools/templates/app/pubspec.yaml.tmpl#L9-L19). This is a value in the form `{major}.{minor}.{patch}+{build_number}` (e.g. `1.2.3+45`). In Flutter builds, the value for build name, `{major}.{minor}.{patch}`, sets  `CFBundleShortVersionString` for iOS and `versionName` for Android. While the optional build number, `{build_number}`, sets `CFBundleVersion` for iOS and `versionCode` for Android. With `flutter build` commands these values can be overridden with the command line arguments `--build-name` and `--build-number` or by setting the environment variables `FLUTTER_BUILD_NAME` and `FLUTTER_BUILD_NUMBER`.

In order to complete an automatic build versioning process for Flutter iOS apps, make sure the following keys along with their string values are set in `ios/Runner/info.plist`:


```bash

<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>

```


It is advisable to set your build version (e.g. `1.2.3`) in the `pubspec.yaml` `version` property and commit this to version control, as this will only change on every app release. On the other hand, you should consider having your CI/CD pipeline increment and set build number automatically, as this should be updated for every build.


<br>

---


## Build versioning in Codemagic

### Environment variables

There are several approaches you can use for build versioning on Codemagic. One of the easiest ways to increment the application version on every build is by using the [environment variables](/variables/environment-variables) that Codemagic exports during the build. There are two environment variables that count the number of builds:

* `BUILD_NUMBER`. Holds the total count of builds (including the ongoing build) for a specific **workflow** in Codemagic. In other words, if you have triggered 10 builds for some workflow in Codemagic, the next time you build it, `BUILD_NUMBER` will be exported as `11`.

* `PROJECT_BUILD_NUMBER`. Holds the total count of builds (including the ongoing build) for a **project** (application) in Codemagic. In contrast with `BUILD_NUMBER`, `PROJECT_BUILD_NUMBER` will increase every time you build any of the workflows of the app.





### Option: Flutter



For Flutter, you can easily increment your build number and build name using the `PROJECT_BUILD_NUMBER` by passing the following to the build arguments:


```bash

--build-name=1.0.$PROJECT_BUILD_NUMBER --build-number=$PROJECT_BUILD_NUMBER

```



Note that if the build version is manually incremented in `pubspec.yaml`, these arguments do not need to be passed to the build command.

If you've added an existing project to Codemagic and need to offset the build number by the current build number, i.e. 200, then you can pass the following argument to correctly increment your build number.


```bash

--build-number=$(($PROJECT_BUILD_NUMBER + 200))

```







### Option: Xcode



You can use the [Xcode command line agvtool](https://developer.apple.com/library/archive/qa/qa1827/_index.html) to set the next build version name for your build.


```yaml

  scripts:
    - name: Set the build version
      script: | 
        #!/bin/sh
        set -e
        set -x
        cd $CM_BUILD_DIR
        agvtool new-version -all $(($BUILD_NUMBER + 1))

```







## App Store or TestFlight latest build number

Using Codemagic [CLI tools](../knowledge-codemagic/codemagic-cli-tools) it is possible to get the latest build number from **App Store** or from **TestFlight** so you can automatically increment the build version in your workflow. For more details, check the [get-latest-app-store-build-number](https://github.com/codemagic-ci-cd/cli-tools/blob/master/docs/app-store-connect/get-latest-app-store-build-number.md#get-latest-app-store-build-number) or [get-latest-testflight-build-number](https://github.com/codemagic-ci-cd/cli-tools/blob/master/docs/app-store-connect/get-latest-testflight-build-number.md#get-latest-testflight-build-number) actions from [app-store-connect](https://github.com/codemagic-ci-cd/cli-tools/tree/master/docs/app-store-connect#app-store-connect) Codemagic CLI Tool.


In order to allow Codemagic to connect to your App Store Connect account, you need to provide API access to App Store Connect API. It is possible that some of these environment variables are already configured as part of the iOS code signing configuration.

#### Creating the App Store Connect API key



1. Open your Codemagic app settings, and go to the **Environment variables** tab.
2. Enter the desired **_Variable name_**, e.g. `APP_STORE_CONNECT_KEY_IDENTIFIER`.
3. Enter the variable value as **_Variable value_**.
4. Enter the variable group name, e.g. **_app_store_credentials_**. Click the button to create the group.
5. Make sure the **Secret** option is selected.
6. Click the **Add** button to add the variable.
7. Repeat the steps to also add all of the above variables.

8. Add the variable group to your `codemagic.yaml` file

```yaml

  environment:
    groups:
      - app_store_credentials

```







### Option: Flutter workflow editor

%!s(<nil>)