30

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.

martinpelant
  • 2,961
  • 1
  • 30
  • 39

6 Answers6

35

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;
    }
}
martinpelant
  • 2,961
  • 1
  • 30
  • 39
  • this notation (android.defaultConfig.versionName) worked for me until today I upgraded from AndroidStudio 0.5.5 to 0.8.1. Any idea what should be used now instead? – Gavriel Jul 12 '14 at 22:57
  • 2
    I get a `Could not find property 'applicationVariants' on project:...` error. – Micky Aug 11 '14 at 08:45
  • 2
    use applicationVariants.each Instead of applicationVariants.all – San Jan 14 '15 at 22:20
  • To my surprise, this works for `android.libraryVrariants.all` as well. – user3829751 Jun 06 '16 at 15:21
  • 1
    This doesn't work, as this code creates a new variable "versionName" in `BuildConfig.java` rather than updating the existing versions in `AndroidManifest.xml` – Vipul Asri Aug 02 '18 at 04:15
  • 1
    I got the error: ```ERROR: versionCode cannot be set on a mergedFlavor directly.``` – Darush Apr 02 '19 at 05:06
3

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.

mochadwi
  • 1,190
  • 9
  • 32
  • 87
1

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"
    }
}
Arul
  • 1,031
  • 13
  • 23
0

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

buildTypes {

    release {
        versionName = android.defaultConfig.versionName
    }
}
Sergii Pechenizkyi
  • 22,227
  • 7
  • 60
  • 71
  • 10
    I've already tried that. The problem is that build type doesn't have versionName property, only versionNameSuffix. The code above results in 'Creating properties on demand (a.k.a. dynamic properties) has been de .0. Please read http://gradle.org/docs/current/dsl/org.gradle.api.plu on the replacement for dynamic properties. Deprecated dynamic property: "versionName" on "BuildTypeDsl_Decorated' – martinpelant Nov 02 '13 at 00:13
  • Got the error: ```RROR: Could not set unknown property 'versionName' for BuildType_Decorated``` – Darush Apr 02 '19 at 05:08
0

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

ininmm
  • 502
  • 4
  • 12
-1

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"
            }
        }
    }
}
Darush
  • 11,403
  • 9
  • 62
  • 60
  • 1
    @Marius make sure you have placed the code in the right place. We are using the exact same code in our production app without any issues. – Darush Apr 21 '20 at 02:17
  • I've tested it in different places and the version is not overriden. I've even tested it in a new project and looked at the `BuildConfig` file after building. Maybe you have to specify exactly where to put it in your answer. – mbo Apr 21 '20 at 08:55
  • Working solution – Arul Jan 31 '23 at 08:51