diff --git a/cli/src/android/build.ts b/cli/src/android/build.ts index 79503501b..73c31ebf6 100644 --- a/cli/src/android/build.ts +++ b/cli/src/android/build.ts @@ -19,15 +19,6 @@ export async function buildAndroid( : `assemble${flavor}Release`; 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)'; - } - try { await runTask('Running Gradle build', async () => runCommand('./gradlew', gradleArgs, { @@ -63,6 +54,73 @@ 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', + buildOptions.keystorepath, + '--ks-pass', + `pass:${buildOptions.keystorepass}`, + '--in', + `${join(releasePath, unsignedReleaseName)}`, + '--out', + `${join(releasePath, signedReleaseName)}`, + ]; + + await runTask('Signing Release', async () => { + await runCommand('apksigner', signingArgs, { + cwd: config.android.platformDirAbs, + }); + }); +} + +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', @@ -85,6 +143,4 @@ export async function buildAndroid( cwd: config.android.platformDirAbs, }); }); - - logSuccess(`Successfully generated ${signedReleaseName} at: ${releasePath}`); } diff --git a/cli/src/config.ts b/cli/src/config.ts index 7e13e10ce..670be5255 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, }; diff --git a/cli/src/declarations.ts b/cli/src/declarations.ts index e3e48f64e..7f123e30a 100644 --- a/cli/src/declarations.ts +++ b/cli/src/declarations.ts @@ -259,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 c50721660..8ac32b892 100644 --- a/cli/src/definitions.ts +++ b/cli/src/definitions.ts @@ -103,6 +103,7 @@ export interface AndroidConfig extends PlatformConfig { keystoreAlias?: string; keystoreAliasPassword?: string; releaseType?: 'AAB' | 'APK'; + signingType?: 'apksigner' | 'jarsigner'; }; } diff --git a/cli/src/index.ts b/cli/src/index.ts index 608f12c0d..9385aee56 100644 --- a/cli/src/index.ts +++ b/cli/src/index.ts @@ -155,6 +155,12 @@ export function runProgram(config: Config): void { '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( @@ -168,6 +174,7 @@ export function runProgram(config: Config): void { keystorealias, keystorealiaspass, androidreleasetype, + signingtype, }, ) => { const { buildCommand } = await import('./tasks/build'); @@ -178,6 +185,7 @@ export function runProgram(config: Config): void { keystorealias, keystorealiaspass, androidreleasetype, + signingtype, }); }, ), diff --git a/cli/src/tasks/build.ts b/cli/src/tasks/build.ts index 9a108c9e0..22d626839 100644 --- a/cli/src/tasks/build.ts +++ b/cli/src/tasks/build.ts @@ -12,6 +12,7 @@ export interface BuildCommandOptions { keystorealias?: string; keystorealiaspass?: string; androidreleasetype?: 'AAB' | 'APK'; + signingtype?: 'apksigner' | 'jarsigner'; } export async function buildCommand( @@ -46,6 +47,10 @@ export async function buildCommand( buildOptions.androidreleasetype || config.android.buildOptions.releaseType || 'AAB', + signingtype: + buildOptions.signingtype || + config.android.buildOptions.signingType || + 'jarsigner', }; try {