From fb64129405c7b10d821916599b8c7db1ca5a0065 Mon Sep 17 00:00:00 2001 From: Youri van Mill Date: Tue, 28 Mar 2023 15:49:23 +0200 Subject: [PATCH 1/6] feat(cli): use apksigner instead of jarsigner --- cli/src/android/build.ts | 32 +++++++++++--------------------- cli/src/declarations.ts | 14 -------------- cli/src/definitions.ts | 2 -- cli/src/tasks/build.ts | 7 ------- 4 files changed, 11 insertions(+), 44 deletions(-) diff --git a/cli/src/android/build.ts b/cli/src/android/build.ts index de22a2ded1..de078db9be 100644 --- a/cli/src/android/build.ts +++ b/cli/src/android/build.ts @@ -16,13 +16,8 @@ export async function buildAndroid( const arg = releaseTypeIsAAB ? ':app:bundleRelease' : 'assembleRelease'; const gradleArgs = [arg]; - if ( - !buildOptions.keystorepath || - !buildOptions.keystorealias || - !buildOptions.keystorealiaspass || - !buildOptions.keystorepass - ) { - throw 'Missing options. Please supply all options for android signing. (Keystore Path, Keystore Password, Keystore Key Alias, Keystore Key Password)'; + if (!buildOptions.keystorepath || !buildOptions.keystorepass) { + throw 'Missing options. Please supply all options for android signing. (Keystore Path, Keystore Password)'; } try { @@ -61,24 +56,19 @@ export async function buildAndroid( ); const signingArgs = [ - '-sigalg', - 'SHA1withRSA', - '-digestalg', - 'SHA1', - '-keystore', + 'sign', + '--ks', buildOptions.keystorepath, - '-keypass', - buildOptions.keystorealiaspass, - '-storepass', - buildOptions.keystorepass, - `-signedjar`, - `${join(releasePath, signedReleaseName)}`, + '--ks-pass', + `pass:${buildOptions.keystorepass}`, + '--in', `${join(releasePath, unsignedReleaseName)}`, - buildOptions.keystorealias, - ]; + '--out', + `${join(releasePath, signedReleaseName)}`, + ] await runTask('Signing Release', async () => { - await runCommand('jarsigner', signingArgs, { + await runCommand('apksigner', signingArgs, { cwd: config.android.platformDirAbs, }); }); diff --git a/cli/src/declarations.ts b/cli/src/declarations.ts index b8b5c96e44..e9a609efaa 100644 --- a/cli/src/declarations.ts +++ b/cli/src/declarations.ts @@ -241,20 +241,6 @@ export interface CapacitorConfig { */ keystorePassword?: string; - /** - * Alias in the keystore to use - * - * @since 4.4.0 - */ - keystoreAlias?: string; - - /** - * Password for the alias in the keystore to use - * - * @since 4.4.0 - */ - keystoreAliasPassword?: string; - /** * Bundle type for your release build * diff --git a/cli/src/definitions.ts b/cli/src/definitions.ts index 5068c48303..2dc966a617 100644 --- a/cli/src/definitions.ts +++ b/cli/src/definitions.ts @@ -100,8 +100,6 @@ export interface AndroidConfig extends PlatformConfig { readonly buildOptions: { keystorePath?: string; keystorePassword?: string; - keystoreAlias?: string; - keystoreAliasPassword?: string; releaseType?: 'AAB' | 'APK'; }; } diff --git a/cli/src/tasks/build.ts b/cli/src/tasks/build.ts index 9522fa56ef..f66bc27c7a 100644 --- a/cli/src/tasks/build.ts +++ b/cli/src/tasks/build.ts @@ -8,8 +8,6 @@ export interface BuildCommandOptions { scheme?: string; keystorepath?: string; keystorepass?: string; - keystorealias?: string; - keystorealiaspass?: string; androidreleasetype?: 'AAB' | 'APK'; } @@ -35,11 +33,6 @@ export async function buildCommand( buildOptions.keystorepath || config.android.buildOptions.keystorePath, keystorepass: buildOptions.keystorepass || config.android.buildOptions.keystorePassword, - keystorealias: - buildOptions.keystorealias || config.android.buildOptions.keystoreAlias, - keystorealiaspass: - buildOptions.keystorealiaspass || - config.android.buildOptions.keystoreAliasPassword, androidreleasetype: buildOptions.androidreleasetype || config.android.buildOptions.releaseType || From 64135ccbb02ca3b8d6c0da6bfeb0ed3afc571d5e Mon Sep 17 00:00:00 2001 From: Youri van Mill Date: Tue, 11 Apr 2023 14:26:44 +0200 Subject: [PATCH 2/6] chore: run "npm run fmt" --- cli/src/android/build.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/src/android/build.ts b/cli/src/android/build.ts index 51cfa195de..39eefca79a 100644 --- a/cli/src/android/build.ts +++ b/cli/src/android/build.ts @@ -68,7 +68,7 @@ export async function buildAndroid( `${join(releasePath, unsignedReleaseName)}`, '--out', `${join(releasePath, signedReleaseName)}`, - ] + ]; await runTask('Signing Release', async () => { await runCommand('apksigner', signingArgs, { From 96bb3c5eec6684d0ad6e2b620d7d67c69d64c228 Mon Sep 17 00:00:00 2001 From: Youri van Mill Date: Wed, 12 Apr 2023 10:19:17 +0200 Subject: [PATCH 3/6] fix: remove keystoreAlias in buildOptions --- cli/src/config.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/cli/src/config.ts b/cli/src/config.ts index 5ac9037835..33c039fddb 100644 --- a/cli/src/config.ts +++ b/cli/src/config.ts @@ -239,9 +239,6 @@ async function loadAndroidConfig( const buildOptions = { keystorePath: extConfig.android?.buildOptions?.keystorePath, keystorePassword: extConfig.android?.buildOptions?.keystorePassword, - keystoreAlias: extConfig.android?.buildOptions?.keystoreAlias, - keystoreAliasPassword: - extConfig.android?.buildOptions?.keystoreAliasPassword, releaseType: extConfig.android?.buildOptions?.releaseType, }; From 37e822421eafb7c4c61e7cf9949e1bc97886d89b Mon Sep 17 00:00:00 2001 From: Youri van Mill Date: Wed, 12 Apr 2023 10:24:54 +0200 Subject: [PATCH 4/6] chore: remove keystorealias and keystorealiaspass build options --- cli/src/index.ts | 9 --------- 1 file changed, 9 deletions(-) diff --git a/cli/src/index.ts b/cli/src/index.ts index c1661b3bba..d8c075e584 100644 --- a/cli/src/index.ts +++ b/cli/src/index.ts @@ -144,11 +144,6 @@ export function runProgram(config: Config): void { .option('--flavor ', 'Android Flavor to build') .option('--keystorepath ', 'Path to the keystore') .option('--keystorepass ', 'Password to the keystore') - .option('--keystorealias ', 'Key Alias in the keystore') - .option( - '--keystorealiaspass ', - 'Password for the Key Alias', - ) .addOption( new Option( '--androidreleasetype ', @@ -165,8 +160,6 @@ export function runProgram(config: Config): void { scheme, keystorepath, keystorepass, - keystorealias, - keystorealiaspass, androidreleasetype, }, ) => { @@ -175,8 +168,6 @@ export function runProgram(config: Config): void { scheme, keystorepath, keystorepass, - keystorealias, - keystorealiaspass, androidreleasetype, }); }, From f80358cdb19066c50206bef63903fb8486ed1667 Mon Sep 17 00:00:00 2001 From: Youri van Mill Date: Mon, 24 Apr 2023 11:34:59 +0200 Subject: [PATCH 5/6] chore: npm run fmt --- cli/src/index.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/cli/src/index.ts b/cli/src/index.ts index d8c075e584..74ad123c75 100644 --- a/cli/src/index.ts +++ b/cli/src/index.ts @@ -156,12 +156,7 @@ export function runProgram(config: Config): void { config, async ( platform, - { - scheme, - keystorepath, - keystorepass, - androidreleasetype, - }, + { scheme, keystorepath, keystorepass, androidreleasetype }, ) => { const { buildCommand } = await import('./tasks/build'); await buildCommand(config, platform, { From c3972fdb683b5a49d0858b15fea7b7ef37b53e66 Mon Sep 17 00:00:00 2001 From: Mark Anderson Date: Wed, 14 Jun 2023 16:43:40 -0400 Subject: [PATCH 6/6] Add fallback to jarsigner --- cli/src/android/build.ts | 76 +++++++++++++++++++++++++++++++++++++--- cli/src/declarations.ts | 22 ++++++++++++ cli/src/definitions.ts | 3 ++ cli/src/index.ts | 24 ++++++++++++- cli/src/tasks/build.ts | 12 +++++++ 5 files changed, 131 insertions(+), 6 deletions(-) diff --git a/cli/src/android/build.ts b/cli/src/android/build.ts index 39eefca79a..73c31ebf6f 100644 --- a/cli/src/android/build.ts +++ b/cli/src/android/build.ts @@ -19,10 +19,6 @@ export async function buildAndroid( : `assemble${flavor}Release`; const gradleArgs = [arg]; - if (!buildOptions.keystorepath || !buildOptions.keystorepass) { - throw 'Missing options. Please supply all options for android signing. (Keystore Path, Keystore Password)'; - } - try { await runTask('Running Gradle build', async () => runCommand('./gradlew', gradleArgs, { @@ -58,6 +54,38 @@ export async function buildAndroid( `-release-signed.${releaseType.toLowerCase()}`, ); + if (buildOptions.signingtype == 'jarsigner') { + await signWithJarSigner( + config, + buildOptions, + releasePath, + signedReleaseName, + unsignedReleaseName, + ); + } else { + await signWithApkSigner( + config, + buildOptions, + releasePath, + signedReleaseName, + unsignedReleaseName, + ); + } + + logSuccess(`Successfully generated ${signedReleaseName} at: ${releasePath}`); +} + +async function signWithApkSigner( + config: Config, + buildOptions: BuildCommandOptions, + releasePath: string, + signedReleaseName: string, + unsignedReleaseName: string, +) { + if (!buildOptions.keystorepath || !buildOptions.keystorepass) { + throw 'Missing options. Please supply all options for android signing. (Keystore Path, Keystore Password)'; + } + const signingArgs = [ 'sign', '--ks', @@ -75,6 +103,44 @@ export async function buildAndroid( cwd: config.android.platformDirAbs, }); }); +} - logSuccess(`Successfully generated ${signedReleaseName} at: ${releasePath}`); +async function signWithJarSigner( + config: Config, + buildOptions: BuildCommandOptions, + releasePath: string, + signedReleaseName: string, + unsignedReleaseName: string, +) { + if ( + !buildOptions.keystorepath || + !buildOptions.keystorealias || + !buildOptions.keystorealiaspass || + !buildOptions.keystorepass + ) { + throw 'Missing options. Please supply all options for android signing. (Keystore Path, Keystore Password, Keystore Key Alias, Keystore Key Password)'; + } + + const signingArgs = [ + '-sigalg', + 'SHA1withRSA', + '-digestalg', + 'SHA1', + '-keystore', + buildOptions.keystorepath, + '-keypass', + buildOptions.keystorealiaspass, + '-storepass', + buildOptions.keystorepass, + `-signedjar`, + `${join(releasePath, signedReleaseName)}`, + `${join(releasePath, unsignedReleaseName)}`, + buildOptions.keystorealias, + ]; + + await runTask('Signing Release', async () => { + await runCommand('jarsigner', signingArgs, { + cwd: config.android.platformDirAbs, + }); + }); } diff --git a/cli/src/declarations.ts b/cli/src/declarations.ts index ae6626ebfd..7f123e30af 100644 --- a/cli/src/declarations.ts +++ b/cli/src/declarations.ts @@ -238,6 +238,20 @@ export interface CapacitorConfig { */ keystorePassword?: string; + /** + * Alias in the keystore to use + * + * @since 4.4.0 + */ + keystoreAlias?: string; + + /** + * Password for the alias in the keystore to use + * + * @since 4.4.0 + */ + keystoreAliasPassword?: string; + /** * Bundle type for your release build * @@ -245,6 +259,14 @@ export interface CapacitorConfig { * @default "AAB" */ releaseType?: 'AAB' | 'APK'; + + /** + * Program to sign your build with + * + * @since 5.1.0 + * @default "jarsigner" + */ + signingType?: 'apksigner' | 'jarsigner'; }; /** diff --git a/cli/src/definitions.ts b/cli/src/definitions.ts index 5299a49dad..8ac32b892f 100644 --- a/cli/src/definitions.ts +++ b/cli/src/definitions.ts @@ -100,7 +100,10 @@ export interface AndroidConfig extends PlatformConfig { readonly buildOptions: { keystorePath?: string; keystorePassword?: string; + keystoreAlias?: string; + keystoreAliasPassword?: string; releaseType?: 'AAB' | 'APK'; + signingType?: 'apksigner' | 'jarsigner'; }; } diff --git a/cli/src/index.ts b/cli/src/index.ts index 74ad123c75..2b12a7db39 100644 --- a/cli/src/index.ts +++ b/cli/src/index.ts @@ -144,26 +144,48 @@ export function runProgram(config: Config): void { .option('--flavor ', 'Android Flavor to build') .option('--keystorepath ', 'Path to the keystore') .option('--keystorepass ', 'Password to the keystore') + .option('--keystorealias ', 'Key Alias in the keystore') + .option( + '--keystorealiaspass ', + 'Password for the Key Alias', + ) .addOption( new Option( '--androidreleasetype ', 'Android release type; APK or AAB', ).choices(['AAB', 'APK']), ) + .addOption( + new Option( + '--signing-type ', + 'Program used to sign apps (default: jarsigner)', + ).choices(['apksigner', 'jarsigner']), + ) .action( wrapAction( telemetryAction( config, async ( platform, - { scheme, keystorepath, keystorepass, androidreleasetype }, + { + scheme, + keystorepath, + keystorepass, + keystorealias, + keystorealiaspass, + androidreleasetype, + signingtype, + }, ) => { const { buildCommand } = await import('./tasks/build'); await buildCommand(config, platform, { scheme, keystorepath, keystorepass, + keystorealias, + keystorealiaspass, androidreleasetype, + signingtype, }); }, ), diff --git a/cli/src/tasks/build.ts b/cli/src/tasks/build.ts index 1234ecbdb4..22d6268398 100644 --- a/cli/src/tasks/build.ts +++ b/cli/src/tasks/build.ts @@ -9,7 +9,10 @@ export interface BuildCommandOptions { flavor?: string; keystorepath?: string; keystorepass?: string; + keystorealias?: string; + keystorealiaspass?: string; androidreleasetype?: 'AAB' | 'APK'; + signingtype?: 'apksigner' | 'jarsigner'; } export async function buildCommand( @@ -35,10 +38,19 @@ export async function buildCommand( buildOptions.keystorepath || config.android.buildOptions.keystorePath, keystorepass: buildOptions.keystorepass || config.android.buildOptions.keystorePassword, + keystorealias: + buildOptions.keystorealias || config.android.buildOptions.keystoreAlias, + keystorealiaspass: + buildOptions.keystorealiaspass || + config.android.buildOptions.keystoreAliasPassword, androidreleasetype: buildOptions.androidreleasetype || config.android.buildOptions.releaseType || 'AAB', + signingtype: + buildOptions.signingtype || + config.android.buildOptions.signingType || + 'jarsigner', }; try {