bundletool icon indicating copy to clipboard operation
bundletool copied to clipboard

Use keystore.properties file for signing bundles

Open HughIngram opened this issue 6 years ago • 6 comments

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

HughIngram avatar Nov 20 '19 17:11 HughIngram

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.

plecesne avatar Nov 20 '19 18:11 plecesne

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} 

HughIngram avatar Nov 21 '19 12:11 HughIngram

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

plecesne avatar Nov 22 '19 00:11 plecesne

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?

HughIngram avatar Nov 26 '19 11:11 HughIngram

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

plecesne avatar Nov 26 '19 12:11 plecesne

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

NatoBoram avatar Aug 08 '23 04:08 NatoBoram