Android Gradle:在构建时动态更改versionName

Ger*_*man 33 groovy android gradle android-gradle-plugin

我试图通过使用自定义版本的gradle-release插件来模拟Android中的Maven发布插件:https://github.com/townsfolk/gradle-release

有趣的步骤是:

  • 检查未提交的更改
  • 步骤版本代码并从版本名称中删除-SNAPSHOT后缀
  • 建立
  • 步骤版本名称并为下一个开发版本添加-SNAPSHOT后缀

但是生成的APK总是具有以前的版本(即1.0.0-SNAPSHOT而不是1.0.0).

版本号在gradle.properties中存储并正确更新,因此我假设我需要更新数据模型中的版本以使更改生效.

我的android插件配置:

defaultConfig {
    versionCode versionCode as int  // taken from gradle.properties
    versionName versionName // taken from gradle.properties
    minSdkVersion 10
    targetSdkVersion 19
}
Run Code Online (Sandbox Code Playgroud)

我试过的事情:

preBuild << {
    android.applicationVariants.each { variant ->
        variant.versionName = versionName
    }
}
Run Code Online (Sandbox Code Playgroud)

但是变体中没有versionName.

preBuild << {
    android.buildTypes.each { type ->
        type.versionName = versionName
    }
}
Run Code Online (Sandbox Code Playgroud)

但是类型中没有versionName.

preBuild << {
    android.productFlavors.each { flavor ->
        flavor.versionName = versionName
    }
}
Run Code Online (Sandbox Code Playgroud)

但是我的应用程序中没有任何风格(仅限普通的调试和发布版本类型).

我的另一种方法是在调用Gradle之前编写一个bash/bat脚本来处理版本,这几乎违背了使用Groovy来改进构建自定义的目的.

如何在执行阶段在Android Gradle插件中动态更新版本?

TWi*_*Rob 54

这就是buildTypes为了什么.你所描述的是一个release构建,IMO.

这是一个例子:执行assembleDebug它时会给你一个快照构建,执行assembleRelease会给你一个干净的构建,没有任何后缀和增加的版本号.下一个调试版本也将使用递增的数字.

在文件夹中创建文件时,以下是完整功能的构建.它也适用于口味,但这只是副产品:).Gradle 2.2.1,Android插件1.1.3

的build.gradle

apply plugin: 'com.android.application'
apply from: 'auto-version.gradle'

buildscript {
    repositories { jcenter() }
    dependencies { classpath 'com.android.tools.build:gradle:1.1.3' }
}

android {
    buildToolsVersion = "21.1.2"
    compileSdkVersion = "android-21"

    buildTypes {
        debug {
            versionNameSuffix "-SNAPSHOT"
        }
    }
}

println "config code: ${calculateVersionCode()}, name: ${calculateVersionName()}"
Run Code Online (Sandbox Code Playgroud)

的src /主/ AndroidManifest.xml中

<manifest package="com.example" />
Run Code Online (Sandbox Code Playgroud)

自动version.gradle

ext {
    versionFile = new File(project.rootDir, 'version.properties')
    calculateVersionName = {
        def version = readVersion()
        return "${version['major']}.${version['minor']}.${version['build']}"
    }
    calculateVersionCode = {
        def version = readVersion()
        def major = version['major'] as int // 1..?
        def minor = version['minor'] as int // 0..99
        def build = version['build'] as int // 0..999
        return (major * 100 + minor) * 1000 + build
    }
}


Properties readVersion() {
    def version = new Properties()
    def stream
    try {
        stream = new FileInputStream(versionFile)
        version.load(stream)
    } catch (FileNotFoundException ignore) {
    } finally {
        if (stream != null) stream.close()
    }
    // safety defaults in case file is missing
    if(!version['major']) version['major'] = "1"
    if(!version['minor']) version['minor'] = "0"
    if(!version['build']) version['build'] = "0"
    return version
}

void incrementVersionNumber() {
    def version = readVersion()

    // careful with the types, culprits: "9"++ = ":", "9" + 1 = "91"
    def build = version['build'] as int
    build++
    version['build'] = build.toString()

    def stream = new FileOutputStream(versionFile)
    try {
        version.store(stream, null)
    } finally {
        stream.close()
    }
}

task incrementVersion {
    description "Increments build counter in ${versionFile}"
    doFirst {
        incrementVersionNumber()
    }
}

if (plugins.hasPlugin('android') || plugins.hasPlugin('android-library')) {
    android {
        defaultConfig {
            versionName = calculateVersionName()
            versionCode = calculateVersionCode()
        }

        afterEvaluate {
            def autoIncrementVariant = { variant ->
                if (variant.buildType.name == buildTypes.release.name) { // don't increment on debug builds
                    variant.preBuild.dependsOn incrementVersion
                    incrementVersion.doLast {
                        variant.mergedFlavor.versionName = calculateVersionName()
                        variant.mergedFlavor.versionCode = calculateVersionCode()
                    }
                }
            }
            if (plugins.hasPlugin('android')) {
                applicationVariants.all { variant -> autoIncrementVariant(variant) }
            }
            if (plugins.hasPlugin('android-library')) {
                libraryVariants.all { variant -> autoIncrementVariant(variant) }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

执行gradle assembleDebug以正常gradle assembleRelease构建,增加和构建,以及gradle incrementVersion仅增加. 注意:要小心,gradle assemble因为顺序assembleDebugassembleRelease会产生不同的结果.

检查build目录中生成的文件,看看这些值是否符合您的喜好.

手动执行(来自评论)

您可能有多种风格,在这种情况下,版本会多次递增,因为多个变体与发布版本类型匹配.最初的问题是没有味道.如果您希望在版本号递增时有更多控制权,只需删除afterEvaluate块并随时调用incrementVersion任务:

gradle incrementVersion assembleFreeRelease assemblePaidRelease
Run Code Online (Sandbox Code Playgroud)

(上面的手动执行是一个未经考验的想法.)

检查未提交的更改

这个答案中没有涉及"检查未提交的更改",这是另一个游戏.tasks.preBuild.doFirst { /*fail here if uncommited changes*/ }如果我理解正确,你可以依靠.但这在很大程度上取决于您的版本控制.再问一个问题!


Jav*_*tor 12

我需要将当前git提交的代码修订版附加到版本名称.它在很多情况下都很方便.我最终得到了以下简单的gradle文件

apply plugin: 'com.android.application'

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.2"

    def gitCommitCount = "git rev-list HEAD --count".execute().text.trim()

    defaultConfig {
        applicationId "my.app.package.name"
        minSdkVersion 16
        targetSdkVersion 21
        versionCode 6
        versionName "0.8"
    }

    buildTypes {

        debug {
            versionNameSuffix ".${gitCommitCount}"
        }

        release {
            versionNameSuffix ".${gitCommitCount}"
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

与gitCommitCount类似,您可以生成自己的变量来自定义版本名称.因为我只是执行一个终端命令来将其结果存储在一个变量中.

  • 好主意.我现在通过获取所有分支的提交计数并转换为int来使用git commit number for versionCode:`def gitCommitCount ="git rev-list --all --count".execute().text.trim() .toInteger()` (4认同)

Tan*_*.7x 10

这并没有直接解决你如何完全更改versionName的问题,但这是我用来为我的buildTypes附加后缀的内容:

defaultConfig {
    versionName "1.0"
}

buildTypes {
    debug {
        versionNameSuffix "-SNAPSHOT"
    }
}
Run Code Online (Sandbox Code Playgroud)


Nei*_*l B 5

我只是使用了Javanator的答案并对其进行了一些修改,以便提交计数不仅有助于更改名称,还可以确保版本代码也保持唯一.以下是我所做的一些示例(可能有一些事情可以优化,但仍然可以为我完成工作):

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"
    def gitCommitCount = "git rev-list HEAD --count".execute().text.trim().toBigInteger()
    project.ext.set("versionCode", gitCommitCount)
    project.ext.set("versionNameSuffix", "(${gitCommitCount})")

    defaultConfig {
        applicationId "my.app.package.name"
        minSdkVersion 15
        targetSdkVersion 25
        versionCode  project.versionCode
        versionName "1.0"
        versionNameSuffix project.versionNameSuffix
        setProperty("archivesBaseName", "MyProject-$versionName")
        ....
    }

    signingConfigs {
        config {
            .........
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.config
        }
    }

    packagingOptions {
        .....
    }

    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            output.outputFile = new File(
                    output.outputFile.parent,
                    output.outputFile.name.replace(".apk", "-${variant.versionName}.apk"))
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑: 最后一点也可能是

    applicationVariants.all { variant ->
    if (variant.name.contains('release')) {
        variant.outputs.each { output ->
            variant.outputs.all {
                outputFileName = "MyProject-${variant.versionName}${variant.versionCode}.apk"
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)