martinpelant
martinpelant

Reputation: 2981

Android - change flavor version name based on build type

I want to change version name for app flavors but only if it's a debug build.

(e.g. debug builds will have versions like 1.0.1 D (DEBUG) 555 or 1.0.1 P (DEBUG) 555, however I want the release builds only to have version like 1.0.1) How can I achieve this?

Basically I have these build types:

buildTypes {


    debug {
        versionNameSuffix " (DEBUG) " + mBuild

    }
    release {
        runProguard true
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), file('proguard-project.txt')
        signingConfig signingConfigs.release
    }
}

and these flavors (for different api environment):

productFlavors {
    dev {
        versionName = android.defaultConfig.versionName + " D"
    }
    prod {
        versionName = android.defaultConfig.versionName + " P"
    }
}

Is there any way how to make release builds without product flavors version name change?

I've tried to set the version name dynamically via

    buildTypes.each { buildType ->
    if(buildType.name == 'debug') {
        productFlavors.dev.versionName = android.defaultConfig.versionName + " D"
    }
}

but this results in

Could not find property 'dev' on GroupableProductFlavorDsl container.

Upvotes: 30

Views: 26480

Answers (6)

ininmm
ininmm

Reputation: 552

If someone is using Gradle Kotlin DSL, you can write below code like this:

flavorDimensions.add("fruit")

productFlavors {
    create("apple") {
        dimension = "fruit"
    }
    create("tomato") {
        dimension = "fruit"
        versionName = "0.0.1-vegetable"
    }
}

Current Gradle version is 8.0.2

Upvotes: 0

Arul
Arul

Reputation: 1209

The latest simple solution worked well and was tested. Define productflavour and buildTypes inside these and remove the versionName.

And using output.versionNameOverride = versionName we can change versionName depending on buildType and productFlavour.

Code:

 applicationVariants.all { variant ->
    variant.outputs.all { output ->
        def flavor = variant.getFlavorName()
        def versionName = "1.0.0"
        switch (flavor){
            case "paid":
                flavor = "Paid"
                if (variant.buildType.name == 'release') {
                    versionName = "1.0.0.8"
                } else if (variant.buildType.name == 'staging') {
                    versionName = "1.0.0.8"
                } else {
                    versionName = "1.0.0.8"
                }
                break
            case "free":
                flavor = "Free"
                if (variant.buildType.name == 'release') {
                    versionName = "1.0.0.14"
                } else if (variant.buildType.name == 'staging') {
                    versionName = "1.0.0.14"
                } else {
                    versionName = "1.0.0.14"
                }
                break
            case "trial":
                flavor = "Trial"
                if (variant.buildType.name == 'release') {
                    versionName = "1.0.0.3"
                } else if (variant.buildType.name == 'staging') {
                    versionName = "1.0.0.3"
                } else {
                    versionName = "1.0.0.3"
                }
                break
        }
        output.versionNameOverride = versionName
        outputFileName = "${flavor}_v${versionName}.apk"
    }
}

Upvotes: 2

Darush
Darush

Reputation: 12031

I wanted to set a different versionName for debug build:

android {
    applicationVariants.all { variant ->
        variant.outputs.all { output ->
            if (variant.buildType.name == 'debug') {
                output.versionNameOverride = "1"
            }
        }
    }
}

Upvotes: -1

mochadwi
mochadwi

Reputation: 1268

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.

Upvotes: 3

martinpelant
martinpelant

Reputation: 2981

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;
    }
}

Upvotes: 36

Sergii Pechenizkyi
Sergii Pechenizkyi

Reputation: 22232

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

buildTypes {

    release {
        versionName = android.defaultConfig.versionName
    }
}

Upvotes: 0

Related Questions