|
|
@@ -0,0 +1,125 @@
|
|
|
+<#
|
|
|
+publish-android.ps1
|
|
|
+Builds and signs an Android App Bundle (.aab) for a net9.0-android Avalonia app.
|
|
|
+Usage examples:
|
|
|
+ .\publish-android.ps1 -ProjectPath .\YourApp.Android.csproj -AppId com.example.weave -VersionCode 12 -VersionName 1.1.0 `
|
|
|
+ -KeystorePath "$env:USERPROFILE\keystores\upload.jks" -KeyAlias upload
|
|
|
+#>
|
|
|
+
|
|
|
+param(
|
|
|
+ [string]$ProjectPath = ".\PRS.Avalonia.Android.csproj",
|
|
|
+ [string]$Configuration = "Release",
|
|
|
+ [string]$Framework = "net9.0-android",
|
|
|
+ [string]$AppId = "com.frogsoftware.avalonia",
|
|
|
+ [int]$VersionCode = 1,
|
|
|
+ [string]$VersionName = "1.0.0",
|
|
|
+ [string]$AndroidSDK = "C:\Users\frank.vandenbos\AppData\Local\Android\sdk",
|
|
|
+
|
|
|
+ # Keystore
|
|
|
+ [string]$KeystorePath = ".\upload-keystore.jks",
|
|
|
+ [string]$KeyAlias = "upload",
|
|
|
+
|
|
|
+ # Optional. If omitted, you will be prompted without echo.
|
|
|
+ [string]$KeystorePass = "Pr5S0ftw4r3!",
|
|
|
+ [string]$KeyPass = "Pr5S0ftw4r3!"
|
|
|
+)
|
|
|
+
|
|
|
+$ErrorActionPreference = "Stop"
|
|
|
+
|
|
|
+Write-Host "=== Android AAB publish for $ProjectPath ===`n"
|
|
|
+
|
|
|
+# 1. Tools check
|
|
|
+function Test-Cmd($cmd) {
|
|
|
+ $null -ne (Get-Command $cmd -ErrorAction SilentlyContinue)
|
|
|
+}
|
|
|
+
|
|
|
+if (-not (Test-Cmd "dotnet")) {
|
|
|
+ throw "dotnet not found on PATH. Install .NET 9 SDK."
|
|
|
+}
|
|
|
+
|
|
|
+# keytool and jarsigner come with a JDK
|
|
|
+$HasKeytool = Test-Cmd "keytool"
|
|
|
+$HasJarsigner = Test-Cmd "jarsigner"
|
|
|
+
|
|
|
+if (-not $HasKeytool) {
|
|
|
+ Write-Warning "keytool not found on PATH. Install a JDK and reopen your shell. Will continue if keystore already exists."
|
|
|
+}
|
|
|
+
|
|
|
+# 2. Workload check
|
|
|
+#$workloads = & dotnet workload list
|
|
|
+#if ($workloads -notmatch '^\s*android\s') {
|
|
|
+# Write-Host "Installing .NET Android workload..."
|
|
|
+# & dotnet workload install android
|
|
|
+#}
|
|
|
+
|
|
|
+# 3. Project and directories
|
|
|
+if (-not (Test-Path $ProjectPath)) {
|
|
|
+ throw "Project not found at $ProjectPath"
|
|
|
+}
|
|
|
+
|
|
|
+$ProjectDir = Split-Path -Parent (Resolve-Path $ProjectPath)
|
|
|
+
|
|
|
+# 4. Keystore presence or creation
|
|
|
+#if (-not (Test-Path $KeystorePath)) {
|
|
|
+# if (-not $HasKeytool) {
|
|
|
+# throw "Keystore missing and keytool not available to create one. Install a JDK or create the keystore manually."
|
|
|
+# }
|
|
|
+# Write-Host "Keystore not found. Creating a new upload keystore at $KeystorePath"
|
|
|
+# New-Item -ItemType Directory -Force -Path (Split-Path -Parent $KeystorePath) | Out-Null
|
|
|
+#
|
|
|
+# if (-not $KeystorePass) {
|
|
|
+# $KeystorePass = Read-Host -AsSecureString "Enter NEW keystore password"
|
|
|
+# $KeystorePassPlain = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($KeystorePass))
|
|
|
+# } else {
|
|
|
+# $KeystorePassPlain = $KeystorePass
|
|
|
+# }
|
|
|
+#
|
|
|
+# if (-not $KeyPass) { $KeyPass = $KeystorePassPlain }
|
|
|
+# $KeyPassPlain = $KeyPass
|
|
|
+#
|
|
|
+# & keytool -genkeypair -v `
|
|
|
+# -keystore "$KeystorePath" `
|
|
|
+# -storepass "$KeystorePassPlain" `
|
|
|
+# -alias "$KeyAlias" `
|
|
|
+# -keypass "$KeyPassPlain" `
|
|
|
+# -keyalg RSA -keysize 2048 -validity 36500 `
|
|
|
+# -dname "CN=Upload, OU=Dev, O=YourOrg, L=City, S=State, C=AU"
|
|
|
+
|
|
|
+# Write-Host "Keystore created."
|
|
|
+#} else {
|
|
|
+ if (-not $KeystorePass) {
|
|
|
+ $sec = Read-Host -AsSecureString "Enter keystore password"
|
|
|
+ $KeystorePass = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($sec))
|
|
|
+ }
|
|
|
+ if (-not $KeyPass) {
|
|
|
+ $sec2 = Read-Host -AsSecureString "Enter key password (press Enter to reuse keystore password)"
|
|
|
+ if ($sec2.Length -gt 0) {
|
|
|
+ $KeyPass = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($sec2))
|
|
|
+ } else {
|
|
|
+ $KeyPass = $KeystorePass
|
|
|
+ }
|
|
|
+ }
|
|
|
+#}
|
|
|
+
|
|
|
+# 5. Restore and Publish to AAB
|
|
|
+#Write-Host "`nRestoring..."
|
|
|
+#& dotnet restore "$ProjectPath"
|
|
|
+
|
|
|
+Write-Host "Publishing signed .aab..."
|
|
|
+& dotnet publish "$ProjectPath" `
|
|
|
+ -c "$Configuration" `
|
|
|
+ -f "$Framework" `
|
|
|
+ /p:AndroidKeyStore=true `
|
|
|
+ /p:AndroidSdkDirectory="$AndroidSDK" `
|
|
|
+ /p:AndroidSigningKeyStore="$KeystorePath" `
|
|
|
+ /p:AndroidSigningStorePass="$KeystorePass" `
|
|
|
+ /p:AndroidSigningKeyAlias="$KeyAlias" `
|
|
|
+ /p:AndroidSigningKeyPass="$KeyPass" `
|
|
|
+ /p:AndroidPackageFormat=aab `
|
|
|
+ /p:ApplicationId="$AppId" `
|
|
|
+ /p:VersionCode="$VersionCode" `
|
|
|
+ /p:VersionName="$VersionName"
|
|
|
+
|
|
|
+# 6. Find the newest AAB under the expected bin folder
|
|
|
+$binRoot = Join-Path $ProjectDir "bin\$Configuration\$Framework"
|
|
|
+$aab = Get-ChildItem -Path $binRoot -Recurs
|