From 09aa65c52a9d5d24b72f0527683580295ccc8275 Mon Sep 17 00:00:00 2001 From: DarkSky Date: Sun, 15 Feb 2026 14:53:35 +0800 Subject: [PATCH] feat: improve ci --- .github/workflows/release-desktop.yml | 78 ++++++++++++++++++++++++--- .github/workflows/windows-signer.yml | 40 ++++++++++++-- 2 files changed, 105 insertions(+), 13 deletions(-) diff --git a/.github/workflows/release-desktop.yml b/.github/workflows/release-desktop.yml index 63a9dc51db..275265b1b3 100644 --- a/.github/workflows/release-desktop.yml +++ b/.github/workflows/release-desktop.yml @@ -201,13 +201,44 @@ jobs: nmHoistingLimits: workspaces env: npm_config_arch: ${{ matrix.spec.arch }} - - name: Download and overwrite packaged artifacts + - name: Download packaged artifacts + uses: actions/download-artifact@v4 + with: + name: packaged-${{ matrix.spec.platform }}-${{ matrix.spec.arch }} + path: packaged-unsigned + - name: unzip packaged artifacts + run: Expand-Archive -Path packaged-unsigned/archive.zip -DestinationPath packages/frontend/apps/electron/out + - name: Download signed packaged file diff uses: actions/download-artifact@v4 with: name: signed-packaged-${{ matrix.spec.platform }}-${{ matrix.spec.arch }} - path: . - - name: unzip file - run: Expand-Archive -Path signed.zip -DestinationPath packages/frontend/apps/electron/out + path: signed-packaged-diff + - name: Apply signed packaged file diff + shell: pwsh + run: | + $DiffRoot = 'signed-packaged-diff/files' + $TargetRoot = 'packages/frontend/apps/electron/out' + if (!(Test-Path -LiteralPath $DiffRoot)) { + throw "Signed diff directory not found: $DiffRoot" + } + + Copy-Item -Path (Join-Path $DiffRoot '*') -Destination $TargetRoot -Recurse -Force + + $ManifestPath = 'signed-packaged-diff/manifest.json' + if (Test-Path -LiteralPath $ManifestPath) { + $ManifestEntries = @(Get-Content -LiteralPath $ManifestPath | ConvertFrom-Json) + foreach ($Entry in $ManifestEntries) { + $TargetPath = Join-Path $TargetRoot $Entry.path + if (!(Test-Path -LiteralPath $TargetPath -PathType Leaf)) { + throw "Applied signed file not found: $($Entry.path)" + } + + $TargetHash = (Get-FileHash -Algorithm SHA256 -LiteralPath $TargetPath).Hash + if ($TargetHash -ne $Entry.sha256) { + throw "Signed file hash mismatch: $($Entry.path)" + } + } + } - name: Make squirrel.windows installer run: yarn affine @affine/electron make-squirrel --platform=${{ matrix.spec.platform }} --arch=${{ matrix.spec.arch }} @@ -267,13 +298,44 @@ jobs: arch: arm64 runs-on: ${{ matrix.spec.runner }} steps: - - name: Download and overwrite installer artifacts + - name: Download installer artifacts + uses: actions/download-artifact@v4 + with: + name: installer-${{ matrix.spec.platform }}-${{ matrix.spec.arch }} + path: installer-unsigned + - name: unzip installer artifacts + run: Expand-Archive -Path installer-unsigned/archive.zip -DestinationPath packages/frontend/apps/electron/out/${{ env.BUILD_TYPE }}/make + - name: Download signed installer file diff uses: actions/download-artifact@v4 with: name: signed-installer-${{ matrix.spec.platform }}-${{ matrix.spec.arch }} - path: . - - name: unzip file - run: Expand-Archive -Path signed.zip -DestinationPath packages/frontend/apps/electron/out/${{ env.BUILD_TYPE }}/make + path: signed-installer-diff + - name: Apply signed installer file diff + shell: pwsh + run: | + $DiffRoot = 'signed-installer-diff/files' + $TargetRoot = 'packages/frontend/apps/electron/out/${{ env.BUILD_TYPE }}/make' + if (!(Test-Path -LiteralPath $DiffRoot)) { + throw "Signed diff directory not found: $DiffRoot" + } + + Copy-Item -Path (Join-Path $DiffRoot '*') -Destination $TargetRoot -Recurse -Force + + $ManifestPath = 'signed-installer-diff/manifest.json' + if (Test-Path -LiteralPath $ManifestPath) { + $ManifestEntries = @(Get-Content -LiteralPath $ManifestPath | ConvertFrom-Json) + foreach ($Entry in $ManifestEntries) { + $TargetPath = Join-Path $TargetRoot $Entry.path + if (!(Test-Path -LiteralPath $TargetPath -PathType Leaf)) { + throw "Applied signed file not found: $($Entry.path)" + } + + $TargetHash = (Get-FileHash -Algorithm SHA256 -LiteralPath $TargetPath).Hash + if ($TargetHash -ne $Entry.sha256) { + throw "Signed file hash mismatch: $($Entry.path)" + } + } + } - name: Save artifacts run: | diff --git a/.github/workflows/windows-signer.yml b/.github/workflows/windows-signer.yml index becad7d46d..e00aa4a1e9 100644 --- a/.github/workflows/windows-signer.yml +++ b/.github/workflows/windows-signer.yml @@ -30,13 +30,43 @@ jobs: run: | cd ${{ env.ARCHIVE_DIR }}/out signtool sign /tr http://timestamp.globalsign.com/tsa/r6advanced1 /td sha256 /fd sha256 /a ${{ inputs.files }} - - name: zip file - shell: cmd + - name: collect signed file diff + shell: powershell run: | - cd ${{ env.ARCHIVE_DIR }} - 7za a signed.zip .\out\* + $OutDir = Join-Path '${{ env.ARCHIVE_DIR }}' 'out' + $DiffDir = Join-Path '${{ env.ARCHIVE_DIR }}' 'signed-diff' + $FilesDir = Join-Path $DiffDir 'files' + New-Item -ItemType Directory -Path $FilesDir -Force | Out-Null + + $SignedFiles = [regex]::Matches('${{ inputs.files }}', '"([^"]+)"') | ForEach-Object { $_.Groups[1].Value } + if ($SignedFiles.Count -eq 0) { + throw 'No files to sign were provided.' + } + + $Manifest = @() + foreach ($RelativePath in $SignedFiles) { + $SourcePath = Join-Path $OutDir $RelativePath + if (!(Test-Path -LiteralPath $SourcePath -PathType Leaf)) { + throw "Signed file not found: $RelativePath" + } + + $TargetPath = Join-Path $FilesDir $RelativePath + $TargetDir = Split-Path -Parent $TargetPath + if ($TargetDir) { + New-Item -ItemType Directory -Path $TargetDir -Force | Out-Null + } + + Copy-Item -LiteralPath $SourcePath -Destination $TargetPath -Force + $Manifest += [PSCustomObject]@{ + path = $RelativePath + sha256 = (Get-FileHash -Algorithm SHA256 -LiteralPath $TargetPath).Hash + } + } + + $Manifest | ConvertTo-Json -Depth 4 | Out-File -FilePath (Join-Path $DiffDir 'manifest.json') -Encoding utf8 + Write-Host "Collected $($SignedFiles.Count) signed files." - name: upload uses: actions/upload-artifact@v4 with: name: signed-${{ inputs.artifact-name }} - path: ${{ env.ARCHIVE_DIR }}/signed.zip + path: ${{ env.ARCHIVE_DIR }}/signed-diff