param( [string]$KeystorePath = 'signing/argus-upload.jks', [string]$PropertiesPath = 'argus-signing.local.properties', [string]$KeyAlias = 'argus-upload', [switch]$Force ) $ErrorActionPreference = 'Stop' function New-Secret { $value = ((1..3 | ForEach-Object { [Guid]::NewGuid().ToString('N') }) -join '') return $value.Substring(0, 32) } function Resolve-JavaHome { $candidates = @( $env:JAVA_HOME, 'C:\Program Files\Android\Android Studio\jbr', 'C:\Program Files\Android\openjdk\jdk-21.0.8' ) | Where-Object { -not [string]::IsNullOrWhiteSpace($_) } foreach ($candidate in $candidates) { $keytool = Join-Path $candidate 'bin\keytool.exe' if (Test-Path $keytool) { return $candidate } } throw 'keytool.exe was not found. Set JAVA_HOME to a JDK path.' } $repoRoot = Split-Path -Parent $PSScriptRoot $resolvedKeystorePath = if ([System.IO.Path]::IsPathRooted($KeystorePath)) { $KeystorePath } else { Join-Path $repoRoot $KeystorePath } $resolvedPropertiesPath = if ([System.IO.Path]::IsPathRooted($PropertiesPath)) { $PropertiesPath } else { Join-Path $repoRoot $PropertiesPath } if ((Test-Path $resolvedKeystorePath) -and (Test-Path $resolvedPropertiesPath) -and -not $Force) { Write-Output 'Keystore and properties already exist.' Write-Output "Keystore: $resolvedKeystorePath" Write-Output "Properties: $resolvedPropertiesPath" exit 0 } if (((Test-Path $resolvedKeystorePath) -xor (Test-Path $resolvedPropertiesPath)) -and -not $Force) { throw 'Keystore and properties are in a partial state. Use -Force to recreate the pair.' } $keystoreDirectory = Split-Path -Parent $resolvedKeystorePath if (-not (Test-Path $keystoreDirectory)) { New-Item -ItemType Directory -Path $keystoreDirectory | Out-Null } $storePassword = New-Secret $keyPassword = $storePassword $javaHome = Resolve-JavaHome $keytoolPath = Join-Path $javaHome 'bin\keytool.exe' if (Test-Path $resolvedKeystorePath) { Remove-Item $resolvedKeystorePath -Force } & $keytoolPath ` -genkeypair ` -keystore $resolvedKeystorePath ` -storetype PKCS12 ` -storepass $storePassword ` -keypass $keyPassword ` -alias $KeyAlias ` -keyalg RSA ` -keysize 4096 ` -validity 10000 ` -dname 'CN=QSfera Argus Upload, O=QSfera, C=RU' | Out-Null if ($LASTEXITCODE -ne 0) { throw "keytool failed with exit code $LASTEXITCODE." } $propertiesContent = @( "QSFERA_RELEASE_KEYSTORE=$resolvedKeystorePath" "QSFERA_RELEASE_KEYSTORE_PASSWORD=$storePassword" "QSFERA_RELEASE_KEY_ALIAS=$KeyAlias" "QSFERA_RELEASE_KEY_PASSWORD=$keyPassword" ) -join [Environment]::NewLine [System.IO.File]::WriteAllText($resolvedPropertiesPath, $propertiesContent, [System.Text.Encoding]::ASCII) Write-Output 'Created QSfera Argus upload keystore.' Write-Output "Keystore: $resolvedKeystorePath" Write-Output "Properties: $resolvedPropertiesPath"