build(android): build and sign a release, without the password touching anything
build-apk.ps1 -Release builds the Release configuration and signs with the user's keystore. Not through Delphi's Provisioning page, for three reasons: the .dproj is versioned, paclient --apksign puts the password ON THE COMMAND LINE where any process on the machine reads it, and tooling belongs in the repository rather than hidden in an IDE setting. apksigner called directly accepts --ks-pass env:. The password is asked for with Read-Host -AsSecureString - nothing echoed, nothing left in console history - handed over through an environment variable, and removed in a finally even when the script fails. It prints the certificate it signed with. A release signed by accident with the debug key installs and runs: nothing tells it apart in use, and one finds out only when the first update is refused. It does not install the release. Android refuses a different signature on an existing package, and uninstalling would wipe the local cache and the device's settings - a deliberate act, not a script's side effect. Keystores are gitignored. The debug path is unchanged and still builds.
This commit is contained in:
@@ -7,8 +7,22 @@
|
||||
# d'avant l'edition, et le pont echouait pour une raison qui n'existait plus.
|
||||
#
|
||||
# -NoInstall compile et empaquette sans toucher au telephone.
|
||||
# -Release configuration Release, signee avec VOTRE magasin de cles.
|
||||
#
|
||||
# LA RELEASE NE S'INSTALLE PAS PAR-DESSUS LE DEBOGAGE. Android refuse une
|
||||
# signature differente sur un paquet deja installe ; il faut desinstaller
|
||||
# d'abord, ce qui EFFACE le cache local et les reglages de l'appareil. Le
|
||||
# script ne le fait donc pas a votre place - il produit l'APK et s'arrete.
|
||||
#
|
||||
# .\android-client\build-apk.ps1 -Release `
|
||||
# -Keystore C:\cles\pmserver-release.jks -Alias pmserver
|
||||
|
||||
param([switch]$NoInstall)
|
||||
param(
|
||||
[switch]$NoInstall,
|
||||
[switch]$Release,
|
||||
[string]$Keystore,
|
||||
[string]$Alias = 'pmserver'
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$root = Split-Path $PSScriptRoot -Parent
|
||||
@@ -17,9 +31,20 @@ $sdk = 'C:\Users\Public\Documents\Embarcadero\Studio\23.0\CatalogRepository'
|
||||
$adb = "$sdk\AndroidSDK-2525-23.0.51511.6924\platform-tools\Adb.exe"
|
||||
$strip = "$sdk\AndroidNDK-21-23.0.51511.6924\android-ndk-r21\toolchains\" +
|
||||
'aarch64-linux-android-4.9\prebuilt\windows-x86_64\aarch64-linux-android\bin\strip.exe'
|
||||
$out = "$root\Android64\Debug"
|
||||
$cfg = if ($Release) { 'Release' } else { 'Debug' }
|
||||
$out = "$root\Android64\$cfg"
|
||||
$stage = "$out\pmserverApk"
|
||||
|
||||
if ($Release) {
|
||||
if (-not $Keystore) { throw 'Chemin du magasin de cles requis : -Keystore' }
|
||||
if (-not (Test-Path $Keystore)) { throw "Magasin introuvable : $Keystore" }
|
||||
# LU ICI ET NULLE PART AILLEURS. Read-Host -AsSecureString n'affiche rien et
|
||||
# ne laisse pas la frappe dans l'historique de la console.
|
||||
$sec = Read-Host "Mot de passe du magasin $([IO.Path]::GetFileName($Keystore))" -AsSecureString
|
||||
$env:PM_KS_PASS = [Runtime.InteropServices.Marshal]::PtrToStringBSTR(
|
||||
[Runtime.InteropServices.Marshal]::SecureStringToBSTR($sec))
|
||||
}
|
||||
|
||||
# 1. La page HTML -> ressource liee dans l'executable.
|
||||
Push-Location "$PSScriptRoot\web"
|
||||
& "$bin\brcc32.exe" web.rc -foweb.res | Out-Null
|
||||
@@ -27,7 +52,7 @@ Pop-Location
|
||||
|
||||
# 2. Compilation Delphi.
|
||||
$msbuild = "`"$bin\rsvars.bat`" && msbuild `"$root\pmserverApk.dproj`""
|
||||
$log = cmd /c "$msbuild /p:Platform=Android64 /p:Config=Debug /t:Build /v:minimal /nologo" 2>&1
|
||||
$log = cmd /c "$msbuild /p:Platform=Android64 /p:Config=$cfg /t:Build /v:minimal /nologo" 2>&1
|
||||
$err = $log | Select-String -Pattern 'error'
|
||||
if ($err) { $err | ForEach-Object { $_.Line }; throw 'compilation echouee' }
|
||||
$log | Select-String -Pattern 'lines,' | ForEach-Object { $_.Line.Trim() }
|
||||
@@ -48,13 +73,29 @@ Copy-Item "$out\pmserverApk.classes\*.dex" "$stage\classes\" -Force
|
||||
# manifeste resout vers un identifiant reel.
|
||||
#
|
||||
# On ne masque donc que CETTE erreur, nommement, et tout autre message remonte.
|
||||
$deploy = cmd /c "$msbuild /p:Platform=Android64 /p:Config=Debug /t:Deploy /v:minimal /nologo" 2>&1
|
||||
$deploy = cmd /c "$msbuild /p:Platform=Android64 /p:Config=$cfg /t:Deploy /v:minimal /nologo" 2>&1
|
||||
$deploy | Select-String -Pattern 'error' |
|
||||
Where-Object { $_.Line -notmatch 'network_security_config|Unable to execute.*Aapt\.exe' } |
|
||||
ForEach-Object { $_.Line }
|
||||
|
||||
# 4. aapt + zipalign + apksigner, et remise en place de ce que Deploy efface.
|
||||
& "$PSScriptRoot\repack-apk.ps1" | Select-Object -Last 1
|
||||
try {
|
||||
if ($Release) {
|
||||
& "$PSScriptRoot\repack-apk.ps1" -Config Release -Keystore $Keystore -Alias $Alias
|
||||
} else {
|
||||
& "$PSScriptRoot\repack-apk.ps1" | Select-Object -Last 1
|
||||
}
|
||||
} finally {
|
||||
# Le mot de passe ne survit pas au script, meme si celui-ci echoue.
|
||||
Remove-Item Env:PM_KS_PASS -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
if ($Release) {
|
||||
"APK signe : $stage\bin\pmserverApk.apk"
|
||||
'Non installe : desinstaller d''abord la version de debogage effacerait le' +
|
||||
' coffre local et les reglages.'
|
||||
return
|
||||
}
|
||||
|
||||
if ($NoInstall) { return }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user