diff --git a/.github/workflows/release-desktop.yml b/.github/workflows/release-desktop.yml index 810bb644ba..e747605322 100644 --- a/.github/workflows/release-desktop.yml +++ b/.github/workflows/release-desktop.yml @@ -551,7 +551,7 @@ jobs: - name: Install trusted-signing-cli if: matrix.platform == 'windows-latest' run: | - cargo install trusted-signing-cli --version 0.9.0 --locked + cargo install trusted-signing-cli --version 0.10.0 --locked echo "$env:USERPROFILE\.cargo\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append # ── Windows: verify signing CLI is accessible ── diff --git a/studio/src-tauri/src/desktop_backend_owner.rs b/studio/src-tauri/src/desktop_backend_owner.rs index 1d08708741..ed4b5f7fd9 100644 --- a/studio/src-tauri/src/desktop_backend_owner.rs +++ b/studio/src-tauri/src/desktop_backend_owner.rs @@ -746,14 +746,16 @@ fn process_liveness(pid: u32) -> PreviousAppPidStatus { #[cfg(windows)] fn process_liveness(pid: u32) -> PreviousAppPidStatus { - use windows_sys::Win32::Foundation::{CloseHandle, GetLastError, ERROR_INVALID_PARAMETER}; + use windows_sys::Win32::Foundation::{ + CloseHandle, GetLastError, ERROR_INVALID_PARAMETER, WAIT_OBJECT_0, WAIT_TIMEOUT, + }; use windows_sys::Win32::System::Threading::{ - OpenProcess, WaitForSingleObject, SYNCHRONIZE, WAIT_OBJECT_0, WAIT_TIMEOUT, + OpenProcess, WaitForSingleObject, PROCESS_SYNCHRONIZE, }; unsafe { - let handle = OpenProcess(SYNCHRONIZE, 0, pid); - if handle == 0 { + let handle = OpenProcess(PROCESS_SYNCHRONIZE, 0, pid); + if handle.is_null() { return if GetLastError() == ERROR_INVALID_PARAMETER { PreviousAppPidStatus::Dead } else { diff --git a/studio/src-tauri/tauri.windows.conf.json b/studio/src-tauri/tauri.windows.conf.json index 83f685cda4..1619edd923 100644 --- a/studio/src-tauri/tauri.windows.conf.json +++ b/studio/src-tauri/tauri.windows.conf.json @@ -2,8 +2,15 @@ "bundle": { "windows": { "signCommand": { - "cmd": "trusted-signing-cli", - "args": ["-e", "https://eus.codesigning.azure.net", "-d", "Unsloth Studio (Desktop)", "%1"] + "cmd": "powershell", + "args": [ + "-NoProfile", + "-ExecutionPolicy", + "Bypass", + "-File", + "windows/sign-with-trusted-signing.ps1", + "%1" + ] } } } diff --git a/studio/src-tauri/windows/sign-with-trusted-signing.ps1 b/studio/src-tauri/windows/sign-with-trusted-signing.ps1 new file mode 100644 index 0000000000..405caefc50 --- /dev/null +++ b/studio/src-tauri/windows/sign-with-trusted-signing.ps1 @@ -0,0 +1,54 @@ +param( + [Parameter(Mandatory = $true)] + [string] $Path +) + +$ErrorActionPreference = "Continue" + +$maxAttempts = 3 +$retryPatterns = @( + "No subscriptions found", + "login via azure cli", + "az\.cmd.*exited with code 1" +) +$trustedSigningArgs = @( + "-e", + "https://eus.codesigning.azure.net", + "-d", + "Unsloth Studio (Desktop)", + $Path +) + +for ($attempt = 1; $attempt -le $maxAttempts; $attempt++) { + $output = & trusted-signing-cli @trustedSigningArgs 2>&1 + $exitCode = $LASTEXITCODE + if ($null -eq $exitCode) { + $exitCode = 1 + } + $text = $output | Out-String + + foreach ($line in $output) { + Write-Output $line + } + + if ($exitCode -eq 0) { + exit 0 + } + + $isRetryable = $false + foreach ($pattern in $retryPatterns) { + if ($text -match $pattern) { + $isRetryable = $true + break + } + } + + if (-not $isRetryable -or $attempt -eq $maxAttempts) { + exit $exitCode + } + + Write-Warning "trusted-signing-cli failed with transient Azure auth error; retrying." + Start-Sleep -Seconds (5 * $attempt) +} + +exit 1