Android - change flavor version name based on build type

After hours of searching I've managed to remove all the changes made to the version name for the release build using this code

applicationVariants.all { variant ->
    if (variant.buildType.name == 'release') {
        variant.mergedFlavor.versionName = android.defaultConfig.versionName;
    }
}

For those wondering to use this using Kotlin DSL. At first try, it might not be allowing us to assign a new value to the version name.

enter image description here

The image above shown there's no setter for versionName for ProductFlavor class.

Attempt 1 (cast to ProductFlavorImpl):

applicationVariants.forEach { variant ->
  if (variant.buildType.name != "release") {
    variant.mergedFlavor.let {
      it as ProductFlavorImpl
      it.versionName = "sampingan-${defaultConfig.versionName}"
    }
  }
}

it as ProductFlavorImpl still doesn't work, due to MergedFlavor cannot be cast ProductFlavorImpl and throw this error:

com.android.builder.core.MergedFlavor cannot be cast to com.android.build.gradle.internal.api.dsl.model.ProductFlavorImpl

Attempt 2 (casting to MergedFlavor) instead:

  //
  variant.mergedFlavor.let {
    it as com.android.builder.core.MergedFlavor
  }
  // 

After trial & error, it looks like we were unable to directly change the versionName with MergedFlavor, instead another error logs shown below:

versionName cannot be set on a mergedFlavor directly.
versionNameOverride can instead be set for variant outputs using the following syntax:
android {
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            output.versionNameOverride = "1.0.0"
        }
    }
}

Attempt 3 (using ApplicationVariant object) instead:

So let's change our implementation to be like this

    applicationVariants.all(object : Action<com.android.build.gradle.api.ApplicationVariant> {
        override fun execute(variant: com.android.build.gradle.api.ApplicationVariant) {
            println("variant: ${variant}")
            variant.outputs.all(object : Action<com.android.build.gradle.api.BaseVariantOutput> {
                override fun execute(output: com.android.build.gradle.api.BaseVariantOutput) {

                    if (variant.buildType.name != "release") {
                    (output as com.android.build.gradle.internal.api.ApkVariantOutputImpl)
                            .versionNameOverride = "prefix-${variant.versionName}"
                    }
                }
            })
        }
    })

This whole approach, inspired by @david-mihola answer. He explained that groovy has its own magic here.

And if you want to change the APK name for each different buildTypes or productFlavors you can go to @david-mihola answer here.


Build Type should override the Product Flavor. Try next one.

buildTypes {

    release {
        versionName = android.defaultConfig.versionName
    }
}

Tags:

Android

Gradle