mirror of
https://github.com/YACReader/yacreader
synced 2025-11-22 10:32:49 -05:00
Try to sign executables and uninstaller
Some checks failed
Build / Initialization (push) Has been cancelled
Build / Code Format Validation (push) Has been cancelled
Build / Linux (Qt5) (push) Has been cancelled
Build / Linux (Qt6) (push) Has been cancelled
Build / Linux (Qt6 + 7zip) (push) Has been cancelled
Build / macOS (Qt6 Universal) (push) Has been cancelled
Build / macOS (Qt5) (push) Has been cancelled
Build / Windows x64 (Qt5) (push) Has been cancelled
Build / Windows x64 (Qt6) (push) Has been cancelled
Build / Windows x86 (Qt5) (push) Has been cancelled
Build / Docker amd64 Image (push) Has been cancelled
Build / Docker arm64 Image (push) Has been cancelled
Build / Publish Dev Builds (push) Has been cancelled
Build / Publish Release (push) Has been cancelled
Some checks failed
Build / Initialization (push) Has been cancelled
Build / Code Format Validation (push) Has been cancelled
Build / Linux (Qt5) (push) Has been cancelled
Build / Linux (Qt6) (push) Has been cancelled
Build / Linux (Qt6 + 7zip) (push) Has been cancelled
Build / macOS (Qt6 Universal) (push) Has been cancelled
Build / macOS (Qt5) (push) Has been cancelled
Build / Windows x64 (Qt5) (push) Has been cancelled
Build / Windows x64 (Qt6) (push) Has been cancelled
Build / Windows x86 (Qt5) (push) Has been cancelled
Build / Docker amd64 Image (push) Has been cancelled
Build / Docker arm64 Image (push) Has been cancelled
Build / Publish Dev Builds (push) Has been cancelled
Build / Publish Release (push) Has been cancelled
This commit is contained in:
@ -15,6 +15,7 @@ SetupIconFile=setup.ico
|
||||
UninstallDisplayIcon=uninstall.ico
|
||||
ArchitecturesInstallIn64BitMode=x64
|
||||
ArchitecturesAllowed=x64
|
||||
SignTool=custom_signtool
|
||||
|
||||
[Registry]
|
||||
Root: HKCR; SubKey: .cbz; ValueType: string; ValueData: Comic Book (zip); Flags: uninsdeletekey; Tasks: File_association
|
||||
|
||||
@ -15,6 +15,7 @@ SetupIconFile=setup.ico
|
||||
UninstallDisplayIcon=uninstall.ico
|
||||
ArchitecturesInstallIn64BitMode=x64
|
||||
ArchitecturesAllowed=x64
|
||||
SignTool=custom_signtool
|
||||
|
||||
[Registry]
|
||||
Root: HKCR; SubKey: .cbz; ValueType: string; ValueData: Comic Book (zip); Flags: uninsdeletekey; Tasks: File_association
|
||||
|
||||
@ -59,9 +59,9 @@ if "%1"=="x86" (
|
||||
|
||||
echo "iscc start"
|
||||
if "%4"=="qt6" (
|
||||
iscc /DVERSION=%VERSION% /DPLATFORM=%1 /DCOMPRESSED_ARCHIVE_BACKEND=%2 /DBUILD_NUMBER=%3 build_installer_qt6.iss || exit /b
|
||||
iscc /DVERSION=%VERSION% /DPLATFORM=%1 /DCOMPRESSED_ARCHIVE_BACKEND=%2 /DBUILD_NUMBER=%3 /Scustom_signtool="powershell.exe -ExecutionPolicy Bypass -File sign_tool.ps1 $f" build_installer_qt6.iss || exit /b
|
||||
) else (
|
||||
iscc /DVERSION=%VERSION% /DPLATFORM=%1 /DCOMPRESSED_ARCHIVE_BACKEND=%2 /DBUILD_NUMBER=%3 build_installer.iss || exit /b
|
||||
iscc /DVERSION=%VERSION% /DPLATFORM=%1 /DCOMPRESSED_ARCHIVE_BACKEND=%2 /DBUILD_NUMBER=%3 /Scustom_signtool="powershell.exe -ExecutionPolicy Bypass -File sign_tool.ps1 $f" build_installer.iss || exit /b
|
||||
)
|
||||
echo "iscc done!"
|
||||
|
||||
|
||||
181
ci/win/sign_tool.ps1
Normal file
181
ci/win/sign_tool.ps1
Normal file
@ -0,0 +1,181 @@
|
||||
# PowerShell script for signing uninstaller during Inno Setup process
|
||||
param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$FilePath
|
||||
)
|
||||
|
||||
# Get the filename from the full path
|
||||
$fileName = Split-Path $FilePath -Leaf
|
||||
Write-Host "SignTool called for file: $fileName"
|
||||
Write-Host "Full file path: $FilePath"
|
||||
|
||||
# Validate the file exists
|
||||
if (-not (Test-Path $FilePath)) {
|
||||
Write-Error "File not found: $FilePath"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Only sign the uninstaller - all other executables are pre-signed
|
||||
if ($fileName -eq "unins000.exe") {
|
||||
Write-Host "Signing uninstaller: $fileName"
|
||||
|
||||
# Check if we're in a CI environment (GitHub Actions)
|
||||
$isCI = $env:GITHUB_ACTIONS -eq "true"
|
||||
|
||||
if ($isCI) {
|
||||
Write-Host "Running in CI environment - calling SignPath API"
|
||||
Write-Host "File path: $FilePath"
|
||||
Write-Host "File size: $((Get-Item $FilePath).Length) bytes"
|
||||
|
||||
# Get required environment variables (these should be set as GitHub secrets)
|
||||
$organizationId = $env:SIGNPATH_ORGANIZATION_ID
|
||||
$projectSlug = $env:SIGNPATH_PROJECT_SLUG
|
||||
$signingPolicySlug = $env:SIGNPATH_SIGNING_POLICY_SLUG
|
||||
$apiToken = $env:SIGNPATH_API_TOKEN
|
||||
|
||||
# Validate required environment variables are set
|
||||
if (-not $organizationId) {
|
||||
Write-Error "SIGNPATH_ORGANIZATION_ID environment variable not set"
|
||||
exit 1
|
||||
}
|
||||
if (-not $projectSlug) {
|
||||
Write-Error "SIGNPATH_PROJECT_SLUG environment variable not set"
|
||||
exit 1
|
||||
}
|
||||
if (-not $signingPolicySlug) {
|
||||
Write-Error "SIGNPATH_SIGNING_POLICY_SLUG environment variable not set"
|
||||
exit 1
|
||||
}
|
||||
if (-not $apiToken) {
|
||||
Write-Error "SIGNPATH_API_TOKEN environment variable not set"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Initialize temp directory variable for proper cleanup
|
||||
$tempDir = $null
|
||||
|
||||
try {
|
||||
# Create a temporary directory for the signing process
|
||||
$tempDir = New-Item -ItemType Directory -Path (Join-Path $env:TEMP "signpath_$(Get-Random)") -Force
|
||||
$tempFile = Join-Path $tempDir "unins000.exe"
|
||||
|
||||
Write-Host "Created temp directory: $tempDir"
|
||||
|
||||
# Copy file to temp location with error handling
|
||||
Copy-Item $FilePath $tempFile -Force
|
||||
Write-Host "Copied file to temp location: $tempFile"
|
||||
Write-Host "Copied file to temp location: $tempFile"
|
||||
|
||||
Write-Host "Uploading uninstaller to SignPath for signing..."
|
||||
|
||||
# Create the API request
|
||||
$uri = "https://app.signpath.io/api/v1/$organizationId/SigningRequests"
|
||||
|
||||
# Prepare the form data
|
||||
$form = @{
|
||||
'ProjectSlug' = $projectSlug
|
||||
'SigningPolicySlug' = $signingPolicySlug
|
||||
'ArtifactConfigurationSlug' = 'executable-file'
|
||||
'Description' = "Signing uninstaller for YACReader build $(Get-Date -Format 'yyyy-MM-dd HH:mm')"
|
||||
}
|
||||
|
||||
# Prepare headers (API token should never be logged)
|
||||
$headers = @{
|
||||
'Authorization' = "Bearer $apiToken"
|
||||
}
|
||||
|
||||
# Upload and sign with error handling
|
||||
Write-Host "Submitting signing request..."
|
||||
$response = Invoke-RestMethod -Uri $uri -Method Post -Form $form -InFile $tempFile -Headers $headers
|
||||
|
||||
# Validate response has required fields
|
||||
if (-not $response.signingRequestId) {
|
||||
Write-Error "SignPath API response missing signingRequestId field"
|
||||
exit 1
|
||||
}
|
||||
|
||||
$signingRequestId = $response.signingRequestId
|
||||
Write-Host "Signing request submitted with ID: $signingRequestId"
|
||||
|
||||
# Poll for completion
|
||||
$statusUri = "https://app.signpath.io/api/v1/$organizationId/SigningRequests/$signingRequestId"
|
||||
$maxWaitTime = 300 # 5 minutes max
|
||||
$waitTime = 0
|
||||
$pollInterval = 10
|
||||
|
||||
do {
|
||||
Start-Sleep $pollInterval
|
||||
$waitTime += $pollInterval
|
||||
|
||||
Write-Host "Checking signing status... ($waitTime/$maxWaitTime seconds)"
|
||||
$status = Invoke-RestMethod -Uri $statusUri -Headers $headers
|
||||
|
||||
# Validate status response
|
||||
if (-not $status.status) {
|
||||
Write-Error "SignPath status response missing status field"
|
||||
exit 1
|
||||
}
|
||||
|
||||
if ($status.status -eq "Completed") {
|
||||
Write-Host "Signing completed successfully!"
|
||||
break
|
||||
} elseif ($status.status -eq "Failed") {
|
||||
$description = if ($status.description) { $status.description } else { "Unknown error" }
|
||||
Write-Error "Signing failed: $description"
|
||||
exit 1
|
||||
} elseif ($status.status -eq "Denied") {
|
||||
$description = if ($status.description) { $status.description } else { "Request denied" }
|
||||
Write-Error "Signing was denied: $description"
|
||||
exit 1
|
||||
}
|
||||
|
||||
} while ($waitTime -lt $maxWaitTime)
|
||||
|
||||
if ($waitTime -ge $maxWaitTime) {
|
||||
Write-Error "Signing timed out after $maxWaitTime seconds"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Download the signed file
|
||||
Write-Host "Downloading signed uninstaller..."
|
||||
$downloadUri = "https://app.signpath.io/api/v1/$organizationId/SigningRequests/$signingRequestId/SignedArtifact"
|
||||
|
||||
# Download to temp location first, then replace original
|
||||
$signedTempFile = Join-Path $tempDir "unins000_signed.exe"
|
||||
Invoke-RestMethod -Uri $downloadUri -Headers $headers -OutFile $signedTempFile
|
||||
|
||||
# Verify the signed file exists and has content
|
||||
if (-not (Test-Path $signedTempFile) -or (Get-Item $signedTempFile).Length -eq 0) {
|
||||
Write-Error "Downloaded signed file is missing or empty"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Replace the original file with the signed version
|
||||
Copy-Item $signedTempFile $FilePath -Force
|
||||
Write-Host "Uninstaller signed successfully and replaced at: $FilePath"
|
||||
|
||||
# Clean up temp directory
|
||||
Remove-Item $tempDir -Recurse -Force -ErrorAction SilentlyContinue
|
||||
Write-Host "Cleaned up temporary files"
|
||||
|
||||
} catch {
|
||||
Write-Error "SignPath API call failed: $($_.Exception.Message)"
|
||||
Write-Host "Error details: $($_.Exception.ToString())"
|
||||
|
||||
# Clean up temp directory on error
|
||||
if ($tempDir -and (Test-Path $tempDir)) {
|
||||
Remove-Item $tempDir -Recurse -Force -ErrorAction SilentlyContinue
|
||||
Write-Host "Cleaned up temp directory after error"
|
||||
}
|
||||
exit 1
|
||||
}
|
||||
|
||||
} else {
|
||||
Write-Host "Running locally - skipping uninstaller signing"
|
||||
Write-Host "Set GITHUB_ACTIONS=true to enable SignPath integration"
|
||||
exit 0
|
||||
}
|
||||
} else {
|
||||
Write-Host "Skipping file: $fileName (not the uninstaller)"
|
||||
exit 0
|
||||
}
|
||||
Reference in New Issue
Block a user