Search code examples
androidkotlinandroid-gradle-plugingradle-kotlin-dsl

Set different versionCode for different flavors dimension combination [Kotlin DSL]


In my app I have 2 dimensions "app" and "server" and in that I have 4 flavors. Now I want to have different versionCode for different flavor combination.

For Example:-

  • For ApponeLive I want to have versionCode 1.
  • For ApponeStaging I want to have versionCode 2.

build.gradle.kts

flavorDimensions.add("app")
flavorDimensions.add("server")

productFlavors {
    create("Appone") {
        val appName = "App One"
        applicationId = "com.app.one"
        dimension = "app"
        resValue("string", "appName", appName)
        manifestPlaceholders["launcherName"] = appName
    }

    create("Apptwo") {
        val appName = "App Two"
        applicationId = "com.app.two"
        dimension = "app"
        resValue("string", "appName", appName)
        manifestPlaceholders["launcherName"] = appName
    }

    create("live") {
        dimension = "server"
        manifestPlaceholders["appNameSuffix"] = ""
    }

    create("staging") {
        dimension = "server"
        applicationIdSuffix = ".staging"
        versionNameSuffix = "-staging"
        manifestPlaceholders["appNameSuffix"] = " Staging"
    }
}

I have tried to set version code using "applicationVariants.configureEach { }" but versionCode is val which means it cannot be reassigned.

According to "ProductFlavor.kt"

The version code associated with this flavor or null if none have been set. This is only the value set on this product flavor, not necessarily the actual version code used.

applicationVariants.configureEach {

        val app = productFlavors[0].name
        val server = productFlavors[1].name

        if (app == "Appone" && server == "live"){
            mergedFlavor.versionCode = 1
        }else if (app == "Appone" && server == "staging"){
            mergedFlavor.versionCode = 2
        }else {
            //Do something..
        }
    }

I even tried by casting "MergedFlavor" but it resulted in failed the gradle task and showed this which I assume is for Groovy.

applicationVariants.configureEach {

        val app = productFlavors[0].name
        val server = productFlavors[1].name

        if (app == "Appone" && server == "live"){
            (mergedFlavor as MergedFlavor).versionCode = 1
        }else if (app == "Appone" && server == "staging"){
            (mergedFlavor as MergedFlavor).versionCode = 2
        }else {
            //Do something..
        }
    }

Gradle Error

versionCode cannot be set on a mergedFlavor directly. versionCodeOverride can instead be set for variant outputs using the following syntax:

android {
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            output.versionCodeOverride = 1
        }
    } 
} 

Now I'm out of ideas, any kind of help will be appreciated.


Solution

  • After some research, I came up with this and It worked for me but I'm not sure if it is an optimal solution.

    Let me know if any optimisation can be done.

    android {
        androidComponents.onVariants {
            val app = it.productFlavors[0].second
            val server = it.productFlavors[1].second
            val output = it.outputs.firstOrNull() ?: return@onVariants
    
    
            if (app == "Appone" && server == "live"){
                output.versionCode.set(1)
            }else if (app == "Appone" && server == "staging"){
                output.versionCode.set(2)
            }else {
                //Add your logic
            }
        
        } 
    }
    

    Explanaton

    fun onVariants(
            selector: VariantSelector = selector().all(),
            callback: (VariantT) -> Unit
    )
    

    Code executing in the callback also has access to the VariantT information which is used to configure org.gradle.api.Task inputs (for example, the buildConfigFields). Such information represented as org.gradle.api.provider.Property can still be modified ensuring that all org.gradle.api.Tasks created by the Android Gradle Plugin use the updated value.