install.ps1 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. param(
  2. [string]$ProjectPath = ".\PRS.Avalonia.Android.csproj",
  3. [string]$Configuration = "Release",
  4. [string]$Framework = "net8.0-android",
  5. [string]$AppId = "com.frogsoftware.avalonia",
  6. [int]$VersionCode = 858100,
  7. [string]$VersionName = "8.58.1",
  8. [string]$AndroidSDK = "/Users/frankvandenbos/Library/Android/sdk",
  9. # Keystore
  10. [string]$KeystorePath = ".\upload-keystore.jks",
  11. [string]$KeyAlias = "upload",
  12. # If omitted, you will be prompted without echo.
  13. [string]$KeystorePass = $null,
  14. [string]$KeyPass = $null,
  15. # Optional switches
  16. [switch]$HardClean = $true,
  17. [switch]$ClearNuGet = $false
  18. )
  19. $ErrorActionPreference = "Stop"
  20. Write-Host "=== Android AAB publish for $ProjectPath ===`n"
  21. # --- Helpers -----------------------------------------------------------------
  22. function Test-Cmd($cmd) {
  23. $null -ne (Get-Command $cmd -ErrorAction SilentlyContinue)
  24. }
  25. function Remove-DirIfExists([string]$path) {
  26. if (Test-Path $path) {
  27. Write-Host "Removing $path"
  28. Remove-Item -LiteralPath $path -Recurse -Force -ErrorAction SilentlyContinue
  29. }
  30. }
  31. function Clean-BuildArtifacts([string]$projectDir) {
  32. Remove-DirIfExists (Join-Path $projectDir "bin")
  33. Remove-DirIfExists (Join-Path $projectDir "obj")
  34. Write-Host "Removing nested bin/obj under $projectDir ..."
  35. Get-ChildItem -LiteralPath $projectDir -Directory -Recurse -Force |
  36. Where-Object { $_.Name -in @("bin","obj") } |
  37. ForEach-Object { Remove-DirIfExists $_.FullName }
  38. }
  39. function Clear-NuGetCaches {
  40. Write-Host "Clearing NuGet caches..."
  41. & dotnet nuget locals all --clear | Write-Host
  42. if ($LASTEXITCODE -ne 0) { throw "dotnet nuget locals --clear failed." }
  43. }
  44. function Restore-Project([string]$projectPath) {
  45. Write-Host "Restoring..."
  46. & dotnet restore "$projectPath"
  47. if ($LASTEXITCODE -ne 0) { throw "dotnet restore failed." }
  48. }
  49. function Publish-Project {
  50. param(
  51. [string]$projectPath,
  52. [string]$Configuration,
  53. [string]$Framework,
  54. [string]$AndroidSDK,
  55. [string]$KeystorePath,
  56. [string]$KeystorePass,
  57. [string]$KeyAlias,
  58. [string]$KeyPass,
  59. [string]$AppId,
  60. [int]$VersionCode,
  61. [string]$VersionName
  62. )
  63. Write-Host "Publishing signed .aab..."
  64. & dotnet publish "$projectPath" `
  65. -c "$Configuration" `
  66. -f "$Framework" `
  67. -v diag `
  68. /restore:false `
  69. /p:AndroidKeyStore=true `
  70. /p:AndroidSdkDirectory="$AndroidSDK" `
  71. /p:AndroidSigningKeyStore="$KeystorePath" `
  72. /p:AndroidSigningStorePass="$KeystorePass" `
  73. /p:AndroidSigningKeyAlias="$KeyAlias" `
  74. /p:AndroidSigningKeyPass="$KeyPass" `
  75. /p:AndroidPackageFormat=aab `
  76. /p:ApplicationId="$AppId" `
  77. /p:VersionCode="$VersionCode" `
  78. /p:VersionName="$VersionName"
  79. if ($LASTEXITCODE -ne 0) { throw "dotnet publish failed." }
  80. }
  81. function To-PlainText([SecureString]$sec) {
  82. if ($null -eq $sec) { return $null }
  83. $bstr = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($sec)
  84. try { return [Runtime.InteropServices.Marshal]::PtrToStringBSTR($bstr) }
  85. finally { [Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr) }
  86. }
  87. # --- Preconditions ------------------------------------------------------------
  88. if (-not (Test-Cmd "dotnet")) {
  89. throw "dotnet not found on PATH. Install .NET 9 SDK."
  90. }
  91. if (-not (Test-Path $AndroidSDK)) {
  92. throw "Android SDK directory not found: $AndroidSDK"
  93. }
  94. if (-not (Test-Path $ProjectPath)) {
  95. throw "Project not found at $ProjectPath"
  96. }
  97. $ProjectDir = Split-Path -Parent (Resolve-Path $ProjectPath)
  98. # keytool/jarsigner (only required if you want to auto-create keystore)
  99. $HasKeytool = Test-Cmd "keytool"
  100. if (-not $HasKeytool) {
  101. Write-Warning "keytool not found on PATH. Keystore auto-creation is disabled."
  102. }
  103. # --- Keystore and secrets -----------------------------------------------------
  104. if (-not (Test-Path $KeystorePath)) {
  105. throw "Keystore not found at '$KeystorePath'. Create it once (recommended) and re-run."
  106. # If you want auto-creation, uncomment and implement the keytool section here.
  107. }
  108. if (-not $KeystorePass) {
  109. $sec = Read-Host -AsSecureString "Enter keystore password"
  110. $KeystorePass = To-PlainText $sec
  111. }
  112. if (-not $KeyPass) {
  113. $sec2 = Read-Host -AsSecureString "Enter key password (press Enter to reuse keystore password)"
  114. $KeyPass = To-PlainText $sec2
  115. if ([string]::IsNullOrWhiteSpace($KeyPass)) { $KeyPass = $KeystorePass }
  116. }
  117. # --- Clean / Restore / Publish ------------------------------------------------
  118. if ($HardClean) { Clean-BuildArtifacts $ProjectDir }
  119. if ($ClearNuGet) { Clear-NuGetCaches }
  120. Restore-Project $ProjectPath
  121. $KeystoreFullPath = (Resolve-Path $KeystorePath).Path
  122. Write-Host "Keystore: $KeystoreFullPath"
  123. Write-Host "Alias: $KeyAlias"
  124. Write-Host "KeyPass empty? $([string]::IsNullOrWhiteSpace($KeyPass))"
  125. Publish-Project $ProjectPath `
  126. -Configuration $Configuration `
  127. -Framework $Framework `
  128. -AndroidSDK $AndroidSDK `
  129. -KeystorePath $KeystorePath `
  130. -KeystorePass $KeystorePass `
  131. -KeyAlias $KeyAlias `Ay
  132. -KeyPass $KeyPass `
  133. -AppId $AppId `
  134. -VersionCode $VersionCode `
  135. -VersionName $VersionName
  136. # --- Locate output ------------------------------------------------------------
  137. $binRoot = Join-Path $ProjectDir "bin\$Configuration\$Framework"
  138. $aab = Get-ChildItem -Path $binRoot -Recurse -Filter "*.aab" |
  139. Sort-Object LastWriteTime -Descending |
  140. Select-Object -First 1
  141. if (-not $aab) {
  142. throw "No .aab found under $binRoot"
  143. }
  144. Write-Host "`nSUCCESS"
  145. Write-Host "AAB: $($aab.FullName)"
  146. Write-Host "Size: $([Math]::Round($aab.Length / 1MB, 2)) MB"