How to make a common build number on TeamCity build chains (for your Unity project)

Learn how to make a common build number on TeamCity's build chain feature (for your Unity project).

How to make a common build number on TeamCity build chains (for your Unity project)
Photo by Carlos Irineu da Costa / Unsplash

Lately, I have started using TeamCity to run my Unity builds on my local machine due to the increased costs of Unity's Cloud Build.

Here is the build configuration for my upcoming mobile game:

TeamCity Build Configuration

As you can see, I'm building for Android and iOS and deploy everything to the TestFlight and Android's Internal Test Track.

Now I want to have one build number for Android and iOS. By nature, each build number for Android and iOS will diverge if one of them runs into an error while building, and you only build the erroneous platform to check if it works again.

There are years-old issues regarding TeamCity's need for a feature for sharing a build number, yet there is no "official" solution for that.

Here's one that works for me!

TeamCity build configuration setup

As you can see from the image, I've a "Meta" project with one build configuration called "BuildNumber". It has no build steps and the build number format is set to %build.counter%.

Add a dependency like this:

Dependency for Android and iOS build configuration

After that, create a new environment variable:

Environment variable
  • Name: env.DEPLOY_ID
  • Value: %dep.YourProject_Meta_BuildNumber.build.number%

With dep you can access any depedency's parameters, we use it to set an environment variable DEPLOY_ID we're going to use in Unity later.

Repeat those steps with each build configuration you have.

Note: all my platform builds produce the final output for each store. An AAB file for Android and a IPA file for iOS.

Deployment build configuration

In your build configuration that you're using for deployment to the stores (in my case it's called "Store Release") add a new dependency:

"Store Release" dependency

It's important to uncheck "Do not run new build if there is a suitable one". This guarantees that each time you run the deployment build configuration you get a new build number for your builds. Otherwise both stores will reject the upload!

Lastly, this is optional, I like to sync the deployment build configuration's build number to the "BuildNumber" configuration. To do so, set the build number format to %dep.YourProject_Meta_BuildNumber.build.number%:

Deployment build configuration's build number format

Now you can always see whats the current build number directly in your deployment build configuration which will always the correct version.

Unity integration

Finally, we need to use the DEPLOY_ID environment variable in Unity.

Create a new Editor script with the following content:

public class SetBuildNumberFromEnvironment : IPreprocessBuildWithReport
{
  public int callbackOrder { get; }

  public void OnPreprocessBuild(BuildReport report)
  {
    var buildNumber = Environment.GetEnvironmentVariable("DEPLOY_ID");

    if (!string.IsNullOrWhiteSpace(buildNumber))
    {
      Debug.Log($"Setting build number: {buildNumber}");
      PlayerSettings.iOS.buildNumber = buildNumber;
      PlayerSettings.Android.bundleVersionCode = int.Parse(buildNumber);
    }
  }
}

This script will set both the iOS buildNumber and the Android bundleVersionCode.

Cheers!