11import fs from 'node:fs' ;
22import path from 'node:path' ;
3+ import type { SubprocessError } from '@rnef/tools' ;
34import {
45 color ,
56 getDotRnefPath ,
@@ -18,6 +19,8 @@ export type SignAndroidOptions = {
1819 apkPath : string ;
1920 keystorePath ?: string ;
2021 keystorePassword ?: string ;
22+ keyAlias ?: string ;
23+ keyPassword ?: string ;
2124 outputPath ?: string ;
2225 buildJsBundle ?: boolean ;
2326 jsBundlePath ?: string ;
@@ -63,14 +66,13 @@ export async function signAndroid(options: SignAndroidOptions) {
6366 loader . start ( 'Initializing output APK...' ) ;
6467 try {
6568 const zip = new AdmZip ( options . apkPath ) ;
69+ // Remove old signature files
6670 zip . deleteFile ( 'META-INF/*' ) ;
6771 zip . writeZip ( tempApkPath ) ;
6872 } catch ( error ) {
6973 throw new RnefError (
7074 `Failed to initialize output APK file: ${ options . outputPath } ` ,
71- {
72- cause : error ,
73- }
75+ { cause : ( error as SubprocessError ) . stderr }
7476 ) ;
7577 }
7678 loader . stop ( `Initialized output APK.` ) ;
@@ -104,6 +106,8 @@ export async function signAndroid(options: SignAndroidOptions) {
104106 apkPath : outputApkPath ,
105107 keystorePath,
106108 keystorePassword : options . keystorePassword ?? 'pass:android' ,
109+ keyAlias : options . keyAlias ,
110+ keyPassword : options . keyPassword ,
107111 } ) ;
108112 loader . stop (
109113 `Signed the APK file with keystore: ${ color . cyan ( keystorePath ) } .`
@@ -145,9 +149,7 @@ async function replaceJsBundle({
145149 } catch ( error ) {
146150 throw new RnefError (
147151 `Failed to replace JS bundle in destination file: ${ apkPath } }` ,
148- {
149- cause : error ,
150- }
152+ { cause : ( error as SubprocessError ) . stderr }
151153 ) ;
152154 }
153155}
@@ -185,9 +187,7 @@ Please follow instructions at: https://reactnative.dev/docs/set-up-your-environm
185187 } catch ( error ) {
186188 throw new RnefError (
187189 `Failed to align APK file: ${ zipAlignPath } ${ zipalignArgs . join ( ' ' ) } ` ,
188- {
189- cause : error ,
190- }
190+ { cause : ( error as SubprocessError ) . stderr }
191191 ) ;
192192 }
193193}
@@ -196,12 +196,16 @@ type SignApkOptions = {
196196 apkPath : string ;
197197 keystorePath : string ;
198198 keystorePassword : string ;
199+ keyAlias ?: string ;
200+ keyPassword ?: string ;
199201} ;
200202
201203async function signApkFile ( {
202204 apkPath,
203205 keystorePath,
204206 keystorePassword,
207+ keyAlias,
208+ keyPassword,
205209} : SignApkOptions ) {
206210 if ( ! fs . existsSync ( keystorePath ) ) {
207211 throw new RnefError (
@@ -219,23 +223,24 @@ Please follow instructions at: https://reactnative.dev/docs/set-up-your-environm
219223 ) ;
220224 }
221225
222- // apksigner sign --ks-pass "pass:android" --ks "android/app/debug.keystore" "$OUTPUT2_APK"
226+ // apksigner sign --ks-pass "pass:android" --ks "android/app/debug.keystore" --ks-key-alias "androiddebugkey" --key-pass "pass:android" "$OUTPUT2_APK"
223227 const apksignerArgs = [
224228 'sign' ,
225229 '--ks' ,
226230 keystorePath ,
227231 '--ks-pass' ,
228232 formatPassword ( keystorePassword ) ,
233+ ...( keyAlias ? [ '--ks-key-alias' , keyAlias ] : [ ] ) ,
234+ ...( keyPassword ? [ '--key-pass' , formatPassword ( keyPassword ) ] : [ ] ) ,
229235 apkPath ,
230236 ] ;
237+
231238 try {
232239 await spawn ( apksignerPath , apksignerArgs ) ;
233240 } catch ( error ) {
234241 throw new RnefError (
235242 `Failed to sign APK file: ${ apksignerPath } ${ apksignerArgs . join ( ' ' ) } ` ,
236- {
237- cause : error ,
238- }
243+ { cause : ( error as SubprocessError ) . stderr }
239244 ) ;
240245 }
241246}
0 commit comments