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