google / bundletool

Bundletool is a command-line tool to manipulate Android App Bundles
https://g.co/androidappbundle
Apache License 2.0
3.57k stars 388 forks source link

Use keystore.properties file for signing bundles #132

Open HughIngram opened 5 years ago

HughIngram commented 5 years ago

Is your feature request related to a problem? Please describe.

I have a step in my CI build which uses the command build-apks. In my case these .apk files need to be signed. For this project, we have a file keystore.properties in a format like this.

With this approach, it is difficult to pass these values to bundletool.

Describe the solution you'd like

I would like to pass a single flag like --keystore-properties=keystore.properties, to set all of the signing parameters at once.

Describe alternatives you've considered I made a gradle task which extracts the value for each field from keystore.properties, and saves each property them into a new file. These files are then copied to variables in fastlane, so that they can be passed back to bundletool

plecesne commented 5 years ago

Thank you for the feedback.

Could you explain what makes this proposition more attractive than the status quo with multiple flags? There doesn't seem to be a standard around the property names, so unless you'd happen to have the exact same property names as your current properties file, you would still need some conversion between your keystore.properties and the one bundletool requires.

HughIngram commented 5 years ago

Thanks @plecesne The advantage of this proposition, over the status quo is really just a matter of convenience for developers who are using this approach with keystore.properties storing build secrets. This eliminates the need to manually parse the file in build scripts, and also the need to look up then copy-paste the details when running manually.

It looks as if the approach of using a keystore.properties file is pretty popular: https://github.com/search?utf8=%E2%9C%93&q=filename%3Akeystore.properties&type=Code&ref=advsearch&l=&l=

There is no standardized format for this file, but it looks like there is a de facto standard of:

storePassword={string}
keyPassword={string}
keyAlias={string}
storeFile={path}

Another sensible format for this could be to use the names of bundletool's flags:

ks-pass={string}
key-pass={string}
ks-key-alias={string}
ks={path} 
plecesne commented 5 years ago

You make a compelling argument. Would you like to make a contribution to bundletool?

HughIngram commented 5 years ago

I'm interested in contributing. I have been looking through the code, and I found this note in BuildApksCommand.java:

  // Signing-related flags: should match flags from apksig library.
  private static final Flag<Path> KEYSTORE_FLAG = Flag.path("ks");
  private static final Flag<String> KEY_ALIAS_FLAG = Flag.string("ks-key-alias");
  private static final Flag<Password> KEYSTORE_PASSWORD = Flag.password("ks-pass");
  private static final Flag<Password> KEY_PASSWORD = Flag.password("key-pass");

So adding a new flag here would mean that bundletool won't match apksig exactly. What do you think @plecesne?

plecesne commented 5 years ago

Since this is a new flag, I think that's fine.

NatoBoram commented 1 year ago

To use a file to sign with Gradle in the first place, we have to do something like this:

signingConfigs {
    release {
        keyAlias keystoreProperties['keyAlias']
        keyPassword keystoreProperties['keyPassword']
        storeFile file(keystoreProperties['storeFile'])
        storePassword keystoreProperties['storePassword']
    }
}

So the names keyAlias, keyPassword, storeFile and storePassword are already standard.

Not only that, but these variables are declared in a file called keystore.properties or key.properties.

Being able to use the same system as we're already using with Gradle would be so much easier.

You can do something like this on Linux/MacOS, but not sure about other systems.

export env $(cat android/key.properties | xargs)
bundletool build-apks --bundle=android/app/build/outputs/bundle/release/app-release.aab --key-pass=\"pass:$keyPassword\" --ks-key-alias=\"$keyAlias\" --ks-pass=\"pass:$storePassword\" --ks=\"$storeFile\" --output=android/app/build/outputs/bundle/release/app-release.apks --overwrite
bundletool install-apks --apks=android/app/build/outputs/bundle/release/app-release.apks