How to change the generated filename for App Bundles with Gradle?

You could use something like this:

defaultConfig {
  applicationId "com.test.app"
  versionCode 1
  versionName "1.0"
  setProperty("archivesBaseName", applicationId + "-v" + versionCode + "(" + versionName + ")")
}

Solution from @SaXXuM works great! Task is not necessary for renaming artifact. You can call setProperty() directly in the android {} block. I prefer to have in the file name:

  • app id
  • module name
  • version name
  • version code
  • date
  • build type

This is how I use it in my projects:

build.gradle:

apply from: "../utils.gradle"

android {
    ...
    setProperty("archivesBaseName", getArtifactName(defaultConfig))
}

utils.gradle:

ext.getArtifactName = {
    defaultConfig ->
        def date = new Date().format("yyyyMMdd")
        return defaultConfig.applicationId + "-" + project.name + "-" + defaultConfig.versionName + "-" + defaultConfig.versionCode + "-" + date
}

The result is:

com.example-app-1.2.0-10200000-20191206-release.aab

It works for both - APK and AAB.


Now I've wrote kind of a Exec template for cross-platform CLI execution, no matter what the commandLine is. My RenameTask can detect Linux & Windows, as well as release & debug.

Property archivesBaseName needs to be defined in defaultConfig:

android {
    defaultConfig {
        setProperty("archivesBaseName", "SomeApp_" + "1.0.0")
    }
}

RenameTask extends Exec performs the renaming (not to be confused with type: Rename):

import javax.inject.Inject

/**
 * App Bundle RenameTask
 * @author Martin Zeitler
**/
class RenameTask extends Exec {
    private String buildType
    @Inject RenameTask(String value) {this.setBuildType(value)}
    @Input String getBuildType() {return this.buildType}
    void setBuildType(String value) {this.buildType = value}
    @Override
    @TaskAction
    void exec() {
        def baseName = getProject().getProperty('archivesBaseName')
        def basePath = getProject().getProjectDir().getAbsolutePath()
        def bundlePath = "${basePath}/build/outputs/bundle/${this.getBuildType()}"
        def srcFile = "${bundlePath}/${baseName}-${this.getBuildType()}.aab"
        def dstFile = "${bundlePath}/${baseName}.aab"
        def os = org.gradle.internal.os.OperatingSystem.current()
        if (os.isUnix() || os.isLinux() || os.isMacOsX()) {
            commandLine "mv -v ${srcFile} ${dstFile}".split(" ")
        } else if (os.isWindows()) {
            commandLine "ren ${srcFile} ${dstFile}".split(" ")
        } else {
            throw new GradleException("Cannot move AAB with ${os.getName()}.")
        }
        super.exec()
    }
}

And it finalizes two other tasks:

// it defines tasks :renameBundleRelease & :renameBundleDebug
task renameBundleRelease(type: RenameTask, constructorArgs: ['release'])
task renameBundleDebug(type: RenameTask, constructorArgs: ['debug'])

// it sets finalizedBy for :bundleRelease & :bundleDebug
tasks.whenTaskAdded { task ->
    switch (task.name) {
        case 'bundleRelease': task.finalizedBy renameBundleRelease; break
        case   'bundleDebug': task.finalizedBy renameBundleDebug; break
    }
}

The advance is, that it leaves nothing behind and one can move the files wherever one wants.


As a more generic way to Martin Zeitlers answer the following will listen for added tasks, then insert rename tasks for any bundle* task that gets added.

Just add it to the bottom of your build.gradle file.

Note: It will add more tasks than necessary, but those tasks will be skipped since they don't match any folder. e.g. > Task :app:renameBundleDevelopmentDebugResourcesAab NO-SOURCE

tasks.whenTaskAdded { task ->
    if (task.name.startsWith("bundle")) {
        def renameTaskName = "rename${task.name.capitalize()}Aab"
        def flavor = task.name.substring("bundle".length()).uncapitalize()
        tasks.create(renameTaskName, Copy) {
            def path = "${buildDir}/outputs/bundle/${flavor}/"
            from(path)
            include "app.aab"
            destinationDir file("${buildDir}/outputs/renamedBundle/")
            rename "app.aab", "${flavor}.aab"
        }

        task.finalizedBy(renameTaskName)
    }
}