在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?这可行吗?这是解决我需求的有效方法吗?在此先感谢您的帮助!
答案 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
希望这有帮助!