From a30f2238a466e036f3dbd385fe4129456c137c83 Mon Sep 17 00:00:00 2001 From: paisley <8197966+su8su@users.noreply.github.com> Date: Fri, 20 Mar 2026 10:37:14 +0800 Subject: [PATCH] v0.2.7 --- .github/workflows/release.yml | 260 +++++++++++++++++----------------- package.json | 2 +- 2 files changed, 131 insertions(+), 131 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index bb80ec1cb..82e728c6b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -83,147 +83,147 @@ jobs: if: matrix.platform == 'win' run: pnpm run package:win - # Detect release channel from tag to skip code signing for alpha/beta builds - - name: Detect Windows release channel - if: matrix.platform == 'win' - id: win-channel - shell: bash - run: | - if [[ "${{ github.ref }}" == refs/tags/v* ]]; then - TAG="${GITHUB_REF#refs/tags/v}" - else - TAG="${{ github.event.inputs.version }}" - fi - if [[ "$TAG" =~ (alpha|beta) ]]; then - echo "is_stable=false" >> $GITHUB_OUTPUT - echo "Channel: prerelease ($TAG) — skipping code signing" - else - echo "is_stable=true" >> $GITHUB_OUTPUT - echo "Channel: stable ($TAG) — will sign" - fi + # # Detect release channel from tag to skip code signing for alpha/beta builds + # - name: Detect Windows release channel + # if: matrix.platform == 'win' + # id: win-channel + # shell: bash + # run: | + # if [[ "${{ github.ref }}" == refs/tags/v* ]]; then + # TAG="${GITHUB_REF#refs/tags/v}" + # else + # TAG="${{ github.event.inputs.version }}" + # fi + # if [[ "$TAG" =~ (alpha|beta) ]]; then + # echo "is_stable=false" >> $GITHUB_OUTPUT + # echo "Channel: prerelease ($TAG) — skipping code signing" + # else + # echo "is_stable=true" >> $GITHUB_OUTPUT + # echo "Channel: stable ($TAG) — will sign" + # fi - - name: Validate unsigned Windows artifacts before SignPath - if: matrix.platform == 'win' && steps.win-channel.outputs.is_stable == 'true' - shell: pwsh - run: | - $unsignedExeFiles = Get-ChildItem -Path "release" -Filter *.exe -File - if (-not $unsignedExeFiles) { - throw "No unsigned .exe files found in release/ before SignPath upload" - } - $unsignedCount = $unsignedExeFiles.Count - "UNSIGNED_EXE_COUNT=$unsignedCount" | Out-File -FilePath $env:GITHUB_ENV -Append - Write-Host "Found $unsignedCount unsigned .exe file(s):" - $unsignedExeFiles | ForEach-Object { Write-Host " - $($_.Name)" } + # - name: Validate unsigned Windows artifacts before SignPath + # if: matrix.platform == 'win' && steps.win-channel.outputs.is_stable == 'true' + # shell: pwsh + # run: | + # $unsignedExeFiles = Get-ChildItem -Path "release" -Filter *.exe -File + # if (-not $unsignedExeFiles) { + # throw "No unsigned .exe files found in release/ before SignPath upload" + # } + # $unsignedCount = $unsignedExeFiles.Count + # "UNSIGNED_EXE_COUNT=$unsignedCount" | Out-File -FilePath $env:GITHUB_ENV -Append + # Write-Host "Found $unsignedCount unsigned .exe file(s):" + # $unsignedExeFiles | ForEach-Object { Write-Host " - $($_.Name)" } - - name: Upload unsigned Windows artifacts for SignPath - if: matrix.platform == 'win' && steps.win-channel.outputs.is_stable == 'true' - id: upload-unsigned-windows-artifact - uses: actions/upload-artifact@v4 - with: - name: unsigned-win-exe-${{ github.run_id }}-${{ github.run_attempt }} - path: release/*.exe - retention-days: 1 + # - name: Upload unsigned Windows artifacts for SignPath + # if: matrix.platform == 'win' && steps.win-channel.outputs.is_stable == 'true' + # id: upload-unsigned-windows-artifact + # uses: actions/upload-artifact@v4 + # with: + # name: unsigned-win-exe-${{ github.run_id }}-${{ github.run_attempt }} + # path: release/*.exe + # retention-days: 1 - - name: Sign Windows artifacts via SignPath - if: matrix.platform == 'win' && steps.win-channel.outputs.is_stable == 'true' - id: signpath-sign-windows - uses: signpath/github-action-submit-signing-request@v2 - with: - api-token: ${{ secrets.SIGNPATH_API_TOKEN }} - organization-id: "78e37079-23df-4800-b41c-33312ad7c1e3" - project-slug: "ValueCell" - signing-policy-slug: "ValueCell-sign" - github-artifact-id: ${{ steps.upload-unsigned-windows-artifact.outputs.artifact-id }} - wait-for-completion: true - output-artifact-directory: release/signed + # - name: Sign Windows artifacts via SignPath + # if: matrix.platform == 'win' && steps.win-channel.outputs.is_stable == 'true' + # id: signpath-sign-windows + # uses: signpath/github-action-submit-signing-request@v2 + # with: + # api-token: ${{ secrets.SIGNPATH_API_TOKEN }} + # organization-id: "78e37079-23df-4800-b41c-33312ad7c1e3" + # project-slug: "ValueCell" + # signing-policy-slug: "ValueCell-sign" + # github-artifact-id: ${{ steps.upload-unsigned-windows-artifact.outputs.artifact-id }} + # wait-for-completion: true + # output-artifact-directory: release/signed - - name: Replace unsigned executables with signed ones - if: matrix.platform == 'win' && steps.win-channel.outputs.is_stable == 'true' - shell: pwsh - run: | - Write-Host "SignPath GitHub artifact ID: ${{ steps.upload-unsigned-windows-artifact.outputs.artifact-id }}" - $signedExeFiles = Get-ChildItem -Path "release/signed" -Filter *.exe -File -Recurse - if (-not $signedExeFiles) { - throw "No signed .exe files found in release/signed" - } - $signedCount = $signedExeFiles.Count - if ($env:UNSIGNED_EXE_COUNT -and ($signedCount -ne [int]$env:UNSIGNED_EXE_COUNT)) { - throw "Signed .exe count ($signedCount) does not match unsigned count ($env:UNSIGNED_EXE_COUNT)" - } - foreach ($file in $signedExeFiles) { - Copy-Item -Path $file.FullName -Destination "release/$($file.Name)" -Force - } - $finalExeFiles = Get-ChildItem -Path "release" -Filter *.exe -File - if ($env:UNSIGNED_EXE_COUNT -and ($finalExeFiles.Count -ne [int]$env:UNSIGNED_EXE_COUNT)) { - throw "Final release .exe count ($($finalExeFiles.Count)) does not match unsigned count ($env:UNSIGNED_EXE_COUNT)" - } - Write-Host "Signed executables copied to release/ ($($finalExeFiles.Count) file(s))" + # - name: Replace unsigned executables with signed ones + # if: matrix.platform == 'win' && steps.win-channel.outputs.is_stable == 'true' + # shell: pwsh + # run: | + # Write-Host "SignPath GitHub artifact ID: ${{ steps.upload-unsigned-windows-artifact.outputs.artifact-id }}" + # $signedExeFiles = Get-ChildItem -Path "release/signed" -Filter *.exe -File -Recurse + # if (-not $signedExeFiles) { + # throw "No signed .exe files found in release/signed" + # } + # $signedCount = $signedExeFiles.Count + # if ($env:UNSIGNED_EXE_COUNT -and ($signedCount -ne [int]$env:UNSIGNED_EXE_COUNT)) { + # throw "Signed .exe count ($signedCount) does not match unsigned count ($env:UNSIGNED_EXE_COUNT)" + # } + # foreach ($file in $signedExeFiles) { + # Copy-Item -Path $file.FullName -Destination "release/$($file.Name)" -Force + # } + # $finalExeFiles = Get-ChildItem -Path "release" -Filter *.exe -File + # if ($env:UNSIGNED_EXE_COUNT -and ($finalExeFiles.Count -ne [int]$env:UNSIGNED_EXE_COUNT)) { + # throw "Final release .exe count ($($finalExeFiles.Count)) does not match unsigned count ($env:UNSIGNED_EXE_COUNT)" + # } + # 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' && steps.win-channel.outputs.is_stable == 'true' - 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 + # # 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' && steps.win-channel.outputs.is_stable == 'true' + # 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 ($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) + # 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" - } + # # 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" - } - } + # # 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)" - } - } + # 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 "" - } + # 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 diff --git a/package.json b/package.json index fd64ba039..911d4c833 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "clawx", - "version": "0.2.7-beta.0", + "version": "0.2.7", "pnpm": { "onlyBuiltDependencies": [ "@discordjs/opus",