215 lines
6.0 KiB
PowerShell
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)."
|