This article is written by Chris Raastad (Product Manager at Codemagic)
If you are going to publish your app to App Store Connect or Google Play, each uploaded binary must have a new version. There are several approaches you can use for build versioning on Codemagic. One of the easiest ways to increment the app version with every build is by using the 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_NUMBERwill be exported as
PROJECT_BUILD_NUMBER: Holds the total count of builds (including the ongoing build) for a project in Codemagic. In contrast with
PROJECT_BUILD_NUMBERwill increase every time you build any of the workflows of the app.
Incrementing the app version using environment variables
Here are some examples of how you can increment the app version using Codemagic’s read-only environment variables in build arguments:
--build-name=2.0.$BUILD_NUMBER --build-number=$(($BUILD_NUMBER + 100)) --build-name=1.0.0 --build-number=$BUILD_NUMBER
Fetching the build number from pubsec.yaml
Add the following build argument:
--build-number=$(yq e .version pubspec.yaml)
It uses yq, a lightweight and portable command-line YAML processor.
Set the Xcode project build number via the command line
Calling agvtool is another way of forcing Xcode to set the build version for your next build.
#!/bin/sh set -e set -x cd $FCI_BUILD_DIR/ios agvtool new-version -all $(($BUILD_NUMBER + 1))
Get the latest App Store or TestFlight build number using Codemagic CLI Tools
In order to do this, you need to provide API access to the App Store Connect API by providing
PRIVATE_KEY as arguments to the action, as defined below.
Additionally, you will need to provide the Application Apple ID (an automatically generated ID assigned to your app, e.g.,
1234567890). It can be found under General > App Information > Apple ID under your application in App Store Connect.
codemagic.yamlconfig and you have automatic code signing set up, you can skip directly to Set the build number with
Creating the App Store Connect API key
It is recommended to create a dedicated App Store Connect API key for Codemagic in App Store Connect. To do so:
- Log in to App Store Connect, and navigate to Users and Access > Keys.
- Click on the + sign to generate a new API key.
- Enter the name for the key, and select an access level. We recommend choosing either
App Manager. You can read more about Apple Developer Program role permissions here.
- Click Generate.
- As soon as the key is generated, you can see it has been added to the list of active keys. Click Download API Key to save the private key for later. Note that the key can only be downloaded once.
Saving the API access arguments to environment variables
In App Store Connect > Users and Access > Keys, this is the Key ID of the key.
In App Store Connect > Users and Access > Keys, this is the Issuer ID displayed above the table of active keys.
This is the private API key downloaded from App Store Connect. Note that when encrypting files via the UI, they will be base64 encoded and will have to be decoded during the build. Alternatively, you can encrypt the contents of the file and save the encrypted value to the environment variable.
environment: vars: APP_STORE_CONNECT_ISSUER_ID: Encrypted(...) APP_STORE_CONNECT_KEY_IDENTIFIER: Encrypted(...) APP_STORE_CONNECT_PRIVATE_KEY: Encrypted(...)
scriptssection of the YAML file as a command argument to programs with dedicated flags. See the details here. In this case, the environment variables will be fallbacks for missing values in scripts.
Saving to environment variables in the Flutter workflow editor
Add the following environment variables to your Flutter project in App settings > Environment variables (see the details here):
Set the build number with
Once you have set the App Store Connect API access with the environment variables mentioned above, you can get the build number using the tool and set your incremented project version.
Add the following script under your
scripts field for
codemagic.yaml or as a custom pre-build script in the Flutter workflow editor:
export APP_STORE_CONNECT_PRIVATE_KEY=$(echo $APP_STORE_CONNECT_PRIVATE_KEY | base64 --decode) # if you encrypted the file itself, not its content LATEST_BUILD_NUMBER=$(app-store-connect get-latest-app-store-build-number '1234567890') # The argument is your application's Apple ID agvtool new-version -all $(($LATEST_BUILD_NUMBER + 1))
To use the latest build number from TestFlight, use a similar script:
export APP_STORE_CONNECT_PRIVATE_KEY=$(echo $APP_STORE_CONNECT_PRIVATE_KEY | base64 --decode) # if you encrypted the file itself, not its content LATEST_BUILD_NUMBER=$(app-store-connect get-latest-testflight-build-number '1234567890') # The argument is your application's Apple ID agvtool new-version -all $(($LATEST_BUILD_NUMBER + 1))
Helpful optional arguments:
--app-store-version=APP_STORE_VERSIONto get the latest build number for a particular version of your application (
--platform=IOS | MAC_OS | TV_OSto specify which platform to get the latest build number
Alternatively, if you use a
YAML configuration, you may just export the value to an environment variable and use it under your
Get the latest Google Play build number using Codemagic CLI Tools
In order to do that, you need to provide API access to the Google Play Developer API by providing
GCLOUD_SERVICE_ACCOUNT_CREDENTIALS as arguments to the action, as defined below.
Additionally, you will need to provide the package name of the app in the Google Play Console (e.g.,
codemagic.yamlconfig and you have Google Play publishing set up, you can reuse the existing service account credentials and skip directly to Get the build number. Just make sure they are specified under the
Creating Google service account credentials
You will need to set up a service account in the Google Play Console and create a JSON key with credentials. See how to set up a service account and create a key.
Saving the API access argument to environment variables in
environment: vars: GCLOUD_SERVICE_ACCOUNT_CREDENTIALS: Encrypted(...)
Saving the API access argument to environment variables in the Flutter workflow editor
GCLOUD_SERVICE_ACCOUNT_CREDENTIALS environment variable to your Flutter project in App settings > Environment variables (see the details here).
Get the build number
Once you have set the Google Play Developer API access with the environment variable mentioned above, you can get the build number using the tool:
export GCLOUD_SERVICE_ACCOUNT_CREDENTIALS=$(echo $GCLOUD_SERVICE_ACCOUNT_CREDENTIALS | base64 --decode) # if you encrypted the file itself, not its content LATEST_BUILD_NUMBER=$(google-play get-latest-build-number --package-name 'com.google.example') # use your own package name
production). If you want to limit the search, you can specify one or more particular tracks with the optional argument
--tracks, which is described here.
There are a number of ways you can pass the obtained build number to an Android project (through environment variables,
gradlew argument properties, a file, or a call from
build.gradle). Check the android-versioning-example repository for more details.
Get the build number in the Flutter workflow editor
If you encrypted the content (not the file) of your gcloud service account credentials and added it as the environment variable
GCLOUD_SERVICE_ACCOUNT_CREDENTIALS, you can call it immediately as a build argument to your Android build command to increment the build number:
--build-number=$(($(google-play get-latest-build-number --package-name 'com.google.example') + 1)) # use your own package name