Android项目 - 我可以使用init.gradle init脚本覆盖build.gradle中设置的signingConfigs吗?

时间:2017-08-05 02:03:08

标签: android gradle android-gradle build.gradle

在CI服务器中,我想摆脱开发人员在Android项目的build.gradle文件中设置的signingConfigs:

的build.gradle

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.3'
    }
}
apply plugin: 'com.android.application'

dependencies {
    compile fileTree(include: '*.jar', dir: 'libs')
}

android {
    signingConfigs {
        releaseConfig {
            keyAlias 'fake_key_alias'
            keyPassword 'fake_key_pass'
            storeFile file('C:/fake')
            storePassword 'fake_store_pass'
        }
    } 

    compileSdkVersion 25
    buildToolsVersion "25.0.0"

    defaultConfig {
        minSdkVersion 20
        targetSdkVersion 25
    }

    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            resources.srcDirs = ['src']
            aidl.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
        }

        // Move the tests to tests/java, tests/res, etc...
        instrumentTest.setRoot('tests')

        // Move the build types to build-types/<type>
        // For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ...
        // This moves them out of them default location under src/<type>/... which would
        // conflict with src/ being used by the main source set.
        // Adding new build types or product flavors should be accompanied
        // by a similar customization.
        debug.setRoot('build-types/debug')
        release.setRoot('build-types/release')
    }
    buildTypes {
        release {
            zipAlignEnabled true
            signingConfig signingConfigs.releaseConfig
        }
    }
}

然后,我想用在CI服务器中放置的init.gradle init脚本编写的signingConfig替换它们。我想使用相同的技术显示here(Gradle Init脚本插件)来替换存储库,但我无法引用signedConfigs。

init.gradle

apply plugin:EnterpriseSigningConfigPlugin

class EnterpriseSigningConfigPlugin implements Plugin<Gradle> {

    void apply(Gradle gradle) {

        gradle.allprojects{ project ->
            project.android.signingConfigs {

                // Remove all signingConfigs
                all {SigningConfig cfg ->
                        remove cfg
                }

                // add the signingConfig
                signingConfigs {
                        releaseConfig {
                            keyAlias 'CI_key_alias'
                            keyPassword 'CI_key_pass'
                            storeFile file('/CI_storeFile')
                            storePassword 'CI_store_pass'
                        }

                }
            }
        }
    }
}

当我执行命令gradle -I init.gradle clean assembleRelease时,出现以下错误:

FAILURE: Build failed with an exception.

* Where:
Initialization script 'C:\Users\it056548\.init\init.gradle' line: 11

* What went wrong:
Could not compile initialization script 'C:\Users\it056548\.init\init.gradle'.
> startup failed:
  initialization script 'C:\Users\it056548\.init\init.gradle': 11: unable to resolve class SigningConfig
   @ line 11, column 21.
                     all {SigningConfig cfg ->
                         ^

  1 error


* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 3.721 secs

我应该如何参考signingConfigs?这可行吗?这是解决我需求的有效方法吗?在此先感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

要解决这个问题,我必须考虑到Gradle构建生命周期分三个阶段进行:初始化,配置和执行。覆盖分发给版本signingConfig的{​​{1}}必须在配置阶段结束时发生,这意味着在构建评估了所有项目属性和任务之后,它们仍可用于修改。

Gradle提供项目挂钩buildType,允许在配置阶段结束时执行代码块,其中所有项目属性和任务都已设置,并且它们仍然可用于修改之前执行阶段开始。

使用此挂钩在初始化脚本中派上用场,如下所示:

<强> init.gradle

project.afterEvaluate()

我将所需的signingConfig属性外部化为一个文件,我在// Enter the scope of the root project rootProject{ println "" println "Project name: ${project.name}" println "" // Apply the subsequent code after the configuration phase has finished afterEvaluate{ //Check if it exixts the properties file for the signing configuration specified in gradle.properties by the property helloWorldAppSigningProperties. //Then read the signing configuration properties //If something goes wrong an exception is thrown and the build execution is terminated if (new File(helloWorldAppSigningProperties).exists()){ println "" println "Found properties file: ${helloWorldAppSigningProperties}!" def signingProps = new Properties() file(helloWorldAppSigningProperties).withInputStream{signingProps.load(it)} ext{ ka = signingProps.getProperty("keyAlias") kp = signingProps.getProperty("keyPassword") sf = signingProps.getProperty("storeFile") sp = signingProps.getProperty("storePassword") } if (ka == null){ throw new GradleException("Property keyAlias not found in file: ${helloWorldAppSigningProperties}") } else if (kp == null) { throw new GradleException("Property keyPassword not found in file: ${helloWorldAppSigningProperties}") } else if (sf == null) { throw new GradleException("Property storeFile not found in file: ${helloWorldAppSigningProperties}") } else if (sp == null) { throw new GradleException("Property storePassword not found in file: ${helloWorldAppSigningProperties}") } } else { throw new GradleException("Properties file: ${helloWorldAppSigningProperties} not found!") } //Add a signing configuration named "helloWorldApp_release" to the android build //Signing configuration properties that were loaded from an external properties file are here assigned println "" println "Adding new signingConfig helloWorldApp_release" android.signingConfigs{ helloWorldApp_release{ keyAlias ka keyPassword kp storeFile file(sf) storePassword sp } } //Display the list of the available signigConfigs println "" println "Available signingConfigs:" android.signingConfigs.all { sc -> println "------------------" println sc.name } println "------------------" //Display the list of the available buildTypes println "" println "Available buildTypes:" android.buildTypes.all { bt -> println "------------------" println bt.name } println "------------------" println "" println "SigningConfig assigned to the release buildType BEFORE overriding: ${android.buildTypes.release.signingConfig.name}" //Set the helloWorldApp_release signingConfig to the release buildType android.buildTypes.release.signingConfig android.signingConfigs.helloWorldApp_release println "" println "SigningConfig assigned to the release buildType AFTER overriding: ${android.buildTypes.release.signingConfig.name}" println "" } } 文件中引用了它的位置:

<强> gradle.properties

gradle.properties

它导致了一个成功的android构建,在执行命令org.gradle.jvmargs=-Xmx1536M .... .... .... //Signing config properties files helloWorldAppSigningProperties=C:\\Users\\it056548\\.signing\\HelloWorldApp.properties 时满足了我的需求:

gradle -I init.gradle clean assembleRelease

希望这有帮助!