开发者

Automation for Android release build

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜