Files
aza/AzA march 2026 - Kopie (14)/sign_release.ps1
2026-04-19 20:41:37 +02:00

215 lines
6.0 KiB
PowerShell

# sign_release.ps1
# Signiert alle relevanten Artefakte fuer eine Kundenauslieferung.
#
# VORAUSSETZUNGEN:
# - signtool.exe im PATH (Windows SDK) oder AZA_SIGNTOOL_PATH gesetzt
# - Zertifikat: AZA_SIGN_CERT_THUMBPRINT (SHA-1 Thumbprint) ODER
# AZA_SIGN_PFX_PATH + AZA_SIGN_PFX_PASSWORD
# - Optional: AZA_SIGN_TIMESTAMP_URL (Standard: http://timestamp.digicert.com)
#
# AUFRUF:
# .\sign_release.ps1 (signiert alle Artefakte)
# .\sign_release.ps1 -DryRun (nur pruefen, nichts signieren)
# .\sign_release.ps1 -SkipDllSigning (nur EXE + Installer signieren)
param(
[switch]$DryRun,
[switch]$SkipDllSigning
)
$ErrorActionPreference = "Stop"
$projectRoot = $PSScriptRoot
# --- Konfiguration ---
$timestampUrl = if ($env:AZA_SIGN_TIMESTAMP_URL) { $env:AZA_SIGN_TIMESTAMP_URL } else { "http://timestamp.digicert.com" }
$signToolPath = if ($env:AZA_SIGNTOOL_PATH) {
$env:AZA_SIGNTOOL_PATH
} else {
$found = Get-Command "signtool.exe" -ErrorAction SilentlyContinue
if ($found) { $found.Source } else { $null }
}
# --- Artefakt-Pfade ---
$desktopExe = Join-Path $projectRoot "dist\aza_desktop\aza_desktop.exe"
$installerExe = Join-Path $projectRoot "dist\installer\aza_desktop_setup.exe"
$internalDir = Join-Path $projectRoot "dist\aza_desktop\_internal"
# --- Hilfsfunktionen ---
function Get-SignableFiles {
param([string]$Directory)
$extensions = @("*.exe", "*.dll", "*.pyd")
$files = @()
foreach ($ext in $extensions) {
$files += Get-ChildItem -Path $Directory -Filter $ext -Recurse -File
}
return $files | Sort-Object FullName
}
function Test-FileSigned {
param([string]$FilePath)
try {
$sig = Get-AuthenticodeSignature -FilePath $FilePath
return ($sig.Status -eq "Valid")
} catch {
return $false
}
}
function Invoke-SignTool {
param([string]$FilePath)
if ($DryRun) {
Write-Host "[DRY RUN] Wuerde signieren: $FilePath"
return $true
}
$args = @("sign")
if ($env:AZA_SIGN_CERT_THUMBPRINT) {
$args += "/sha1", $env:AZA_SIGN_CERT_THUMBPRINT
} elseif ($env:AZA_SIGN_PFX_PATH) {
$args += "/f", $env:AZA_SIGN_PFX_PATH
if ($env:AZA_SIGN_PFX_PASSWORD) {
$args += "/p", $env:AZA_SIGN_PFX_PASSWORD
}
} else {
Write-Error "Kein Zertifikat konfiguriert. AZA_SIGN_CERT_THUMBPRINT oder AZA_SIGN_PFX_PATH setzen."
return $false
}
$args += "/fd", "sha256"
$args += "/tr", $timestampUrl
$args += "/td", "sha256"
$args += "/v"
$args += $FilePath
& $signToolPath @args
return ($LASTEXITCODE -eq 0)
}
# --- Hauptlogik ---
Write-Host "=== AZA Release Signing ==="
Write-Host ""
# 1. Voraussetzungen pruefen
if (-not $signToolPath) {
Write-Error @"
signtool.exe nicht gefunden.
Bitte Windows SDK installieren oder AZA_SIGNTOOL_PATH setzen.
Download: https://developer.microsoft.com/windows/downloads/windows-sdk/
"@
exit 1
}
Write-Host "SignTool: $signToolPath"
Write-Host "Timestamp: $timestampUrl"
if (-not $env:AZA_SIGN_CERT_THUMBPRINT -and -not $env:AZA_SIGN_PFX_PATH) {
Write-Error @"
Kein Signing-Zertifikat konfiguriert.
Setze eine der folgenden Umgebungsvariablen:
AZA_SIGN_CERT_THUMBPRINT (SHA-1 Thumbprint des Zertifikats im Windows Store)
AZA_SIGN_PFX_PATH (Pfad zur .pfx-Datei, optional mit AZA_SIGN_PFX_PASSWORD)
"@
exit 1
}
if (-not (Test-Path $desktopExe)) {
Write-Error "Desktop-EXE nicht gefunden: $desktopExe — Bitte zuerst build_exe.ps1 ausfuehren."
exit 1
}
# 2. DLLs / PYDs in _internal signieren (optional)
$signedCount = 0
$failedCount = 0
if (-not $SkipDllSigning -and (Test-Path $internalDir)) {
Write-Host ""
Write-Host "--- Schritt 1/3: DLLs und PYDs in _internal signieren ---"
$internalFiles = Get-SignableFiles -Directory $internalDir
foreach ($file in $internalFiles) {
if (Test-FileSigned -FilePath $file.FullName) {
Write-Host "[SKIP] Bereits signiert: $($file.Name)"
continue
}
$ok = Invoke-SignTool -FilePath $file.FullName
if ($ok) {
$signedCount++
} else {
$failedCount++
Write-Warning "Signierung fehlgeschlagen: $($file.FullName)"
}
}
Write-Host "DLL/PYD-Signierung: $signedCount signiert, $failedCount fehlgeschlagen"
} else {
Write-Host ""
Write-Host "--- Schritt 1/3: DLL-Signierung uebersprungen ---"
}
# 3. Haupt-EXE signieren
Write-Host ""
Write-Host "--- Schritt 2/3: Haupt-EXE signieren ---"
$ok = Invoke-SignTool -FilePath $desktopExe
if (-not $ok) {
Write-Error "Signierung der Haupt-EXE fehlgeschlagen: $desktopExe"
exit 1
}
$signedCount++
Write-Host "Haupt-EXE signiert: $desktopExe"
# 4. Installer signieren (muss nach Inno-Build, aber vor Publish erfolgen)
if (Test-Path $installerExe) {
Write-Host ""
Write-Host "--- Schritt 3/3: Installer signieren ---"
$ok = Invoke-SignTool -FilePath $installerExe
if (-not $ok) {
Write-Error "Signierung des Installers fehlgeschlagen: $installerExe"
exit 1
}
$signedCount++
Write-Host "Installer signiert: $installerExe"
} else {
Write-Host ""
Write-Host "[WARNUNG] Installer nicht gefunden: $installerExe"
Write-Host "Bitte build_installer.ps1 ausfuehren und dann erneut signieren."
}
# 5. Zusammenfassung
Write-Host ""
Write-Host "=== Signierung abgeschlossen ==="
Write-Host "Signiert: $signedCount Dateien"
if ($failedCount -gt 0) {
Write-Warning "Fehlgeschlagen: $failedCount Dateien"
exit 1
}
# 6. Verifikation
Write-Host ""
Write-Host "--- Verifikation ---"
foreach ($path in @($desktopExe, $installerExe)) {
if (Test-Path $path) {
$sig = Get-AuthenticodeSignature -FilePath $path
$status = if ($DryRun) { "(DRY RUN)" } else { $sig.Status }
Write-Host "$([System.IO.Path]::GetFileName($path)): $status"
}
}
Write-Host ""
Write-Host "Naechster Schritt: build_release_artifacts.ps1 ausfuehren (aktualisiert SHA256-Hashes)."