From f4d765f0dbea5d900501e802026ee44581103aef Mon Sep 17 00:00:00 2001 From: paisley <8197966+su8su@users.noreply.github.com> Date: Tue, 17 Mar 2026 16:58:56 +0800 Subject: [PATCH] fix(ci): recalculate sha512 in latest.yml after Windows code signing --- .github/workflows/release.yml | 66 +++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7b44800..3abc1a8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -140,6 +140,72 @@ jobs: } Write-Host "Signed executables copied to release/ ($($finalExeFiles.Count) file(s))" + # Code signing changes the .exe binary, invalidating the sha512 hash that + # electron-builder wrote into latest.yml during the initial build. + # Recalculate the hash for each signed .exe and patch the yml files so + # electron-updater can verify the download successfully. + # + # Actual latest.yml structure (from electron-builder NSIS): + # files: + # - url: ClawX-0.2.4-win-x64.exe ← files[] entries have url/sha512/size + # sha512: + # size: 430775882 + # path: ClawX-0.2.4-win-arm64.exe ← top-level has path/sha512 (no size!) + # sha512: + # releaseDate: '...' + - name: Update latest.yml sha512 after code signing + if: matrix.platform == 'win' + shell: pwsh + run: | + $ymlFiles = Get-ChildItem -Path "release" -Filter "*.yml" -File | Where-Object { $_.Name -ne "builder-debug.yml" } + $exeFiles = Get-ChildItem -Path "release" -Filter "*.exe" -File + + foreach ($yml in $ymlFiles) { + $content = Get-Content $yml.FullName -Raw + $modified = $false + + foreach ($exe in $exeFiles) { + # Compute new sha512 (base64) for the signed exe + $hash = Get-FileHash -Path $exe.FullName -Algorithm SHA512 + $hashBytes = [byte[]]::new($hash.Hash.Length / 2) + for ($i = 0; $i -lt $hashBytes.Length; $i++) { + $hashBytes[$i] = [Convert]::ToByte($hash.Hash.Substring($i * 2, 2), 16) + } + $newSha512 = [Convert]::ToBase64String($hashBytes) + $newSize = (Get-Item $exe.FullName).Length + $escapedName = [Regex]::Escape($exe.Name) + + # 1) files[] entries: url: \n sha512: \n size: + $urlPattern = "(?m)(url:\s*${escapedName}\s*\r?\n\s*sha512:\s*)(\S+)(\s*\r?\n\s*size:\s*)(\d+)" + if ($content -match $urlPattern) { + $content = $content -replace $urlPattern, "`${1}${newSha512}`${3}${newSize}" + $modified = $true + Write-Host "Updated $($yml.Name) files[]: $($exe.Name) sha512=$newSha512 size=$newSize" + } + + # 2) Top-level entry: path: \nsha512: \n (no size field) + $pathPattern = "(?m)(path:\s*${escapedName}\s*\r?\n)sha512:\s*\S+" + if ($content -match $pathPattern) { + $content = $content -replace $pathPattern, "`${1}sha512: ${newSha512}" + $modified = $true + Write-Host "Updated $($yml.Name) top-level: $($exe.Name) sha512=$newSha512" + } + } + + if ($modified) { + Set-Content -Path $yml.FullName -Value $content -NoNewline + Write-Host "Saved updated $($yml.Name)" + } + } + + Write-Host "" + Write-Host "=== Final yml contents ===" + foreach ($yml in $ymlFiles) { + Write-Host "--- $($yml.Name) ---" + Get-Content $yml.FullName + Write-Host "" + } + # Linux specific steps - name: Build Linux if: matrix.platform == 'linux'