I have ten Android projects in one folder. For each project, I can use ant debug
to build it. So it i开发者_开发技巧s no problem to write a simple script to compile all these projects. I use Hudson to build these projects daily, and it works fine.
But now our project needs to go to release phase. So the compile command becomes ant release
. For compiling a release project, I have to enter the password for the certificate every time during compilation. So I can't do the automation for release.
This compiling job kills me since I have ten projects that all need to interact with inputting the password.
How can I make the release build still be automatic?
Assuming you're using recent Android tools, say v9 or v10.
If you look at tools/ant/main_rules.xml
in the Android SDK directory:
<!-- called through target 'release'. Only executed if the keystore and
key alias are known but not their password. -->
<target name="-release-prompt-for-password" if="has.keystore" unless="has.password">
<!-- Gets passwords -->
<input
message="Please enter keystore password (store:${key.store}):"
addproperty="key.store.password" />
<input
message="Please enter password for alias '${key.alias}':"
addproperty="key.alias.password" />
</target>
<!-- called through target 'release'. Only executed if there's no
keystore/key alias set -->
<target name="-release-nosign" unless="has.keystore">
<echo>No key.store and key.alias properties found in build.properties.</echo>
<echo>Please sign ${out.unsigned.file} manually</echo>
<echo>and run zipalign from the Android SDK tools.</echo>
</target>
Searching the XML file for has.keystore
reveals:
<!-- properties for signing in release mode -->
<condition property="has.keystore">
<and>
<isset property="key.store" />
<length string="${key.store}" when="greater" length="0" />
<isset property="key.alias" />
</and>
</condition>
<condition property="has.password">
<and>
<isset property="has.keystore" />
<isset property="key.store.password" />
<isset property="key.alias.password" />
</and>
</condition>
So I'd assume you have to pass in four defines to the build.xml: key.store
, key.alias
, key.store.password
, key.alias.password
.
And remember not to pass those defines on the command line for security reasons. :)
Gradle-based builds
1) Create a secure.properties
file to contain your passwords:
key.store.password=<your keystore password>
key.alias.password=<your alias password>
You probably don't want it under version control, which is why we're putting the passwords in a separate *.properties
file. If you don't mind having your passwords under version control, you can enter your passwords directly into build.gradle
, but that's not recommended, so I'm not directly showing that.
2) Set up your build.gradle
as follows:
Properties secureProperties = new Properties()
secureProperties.load(new FileInputStream("secure.properties"))
android {
signingConfigs {
release {
storeFile file("<path to your keystore>")
storePassword secureProperties['key.store.password']
keyAlias "<alias name>"
keyPassword secureProperties['key.alias.password']
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}
}
And that's it. ./gradlew assembleRelease
now builds and signs my APK without prompting for my password.
Ant-based builds
1) Create a secure.properties
file to contain your passwords:
key.store.password=<your keystore password>
key.alias.password=<your alias password>
You probably don't want it under version control, which is why we're not putting the passwords in one of the existing *.properties
files. If you don't mind having your passwords under version control, put these two lines in ant.properties
and you're done.
2) Create a custom_rules.xml
file to tell the build system about your secure.properties
file.
<?xml version="1.0" encoding="UTF-8"?>
<project name="custom_rules" default="help">
<property file="secure.properties" />
</project>
I'm not familiar with this build system, so I'm not sure about the project
element's name
or default
properties, but I believe what I chose should work for everybody.
2b) Any recent version of the Android SDK tools should be good to go, but if for some reason your build.xml
file doesn't contain the following, you should add it:
<import file="custom_rules.xml" optional="true" />
And that should be it. ant release
now builds and signs my APK without prompting for my password.
You can define your keystore configure in your project.properties in your project folder. Just like this
key.store=/path/to/your/keystore
key.alias=yourkeyalias
key.store.password=yourkeystorepassword
key.alias.password=yourkeyaliaspassword
Just a note... I didn't want to set the passwords in a props file and by default your password will be echoed on the command line which is also a concern. Adding use of SecureInputHandler to you main_rules.xml works so that your password isn't exposed on the command line.
<target name="-release-prompt-for-password" if="has.keystore" unless="has.password">
<!-- Gets passwords -->
<input
message="Please enter keystore password (store:${key.store}):"
addproperty="key.store.password" >
<handler classname="org.apache.tools.ant.input.SecureInputHandler" />
</input>
<input
message="Please enter password for alias '${key.alias}':"
addproperty="key.alias.password" >
<handler classname="org.apache.tools.ant.input.SecureInputHandler" />
</input>
</target>
have a look at this article, especially where it starts mentioning key.store.password
. I've used it without troubles.
Basically you should create some secure.properties
file local to your (build) machine, that has to be kept relatively safe, e.g. not accessible to everyone or not stored for everyone in source control. That file stores the passwords as properties with the right names, and it's imported into project ANT build file.
精彩评论