✨ Feature: windows signature (#1386)

This commit is contained in:
PiEgg
2026-02-10 10:25:53 +08:00
committed by GitHub
parent 27464dcf29
commit 781cf30c55
2 changed files with 136 additions and 3 deletions
+57 -3
View File
@@ -26,11 +26,19 @@ on:
required: true
default: false
type: boolean
skip_notarize:
description: "Skip Notarization (true/false)"
skip_mac_notarize:
description: "Skip Mac Notarization (true/false)"
required: true
default: false
type: boolean
win_signing_mode:
description: "Windows Signing Mode: release-signing(default) or test-signing"
required: true
default: "release-signing"
type: choice
options:
- release-signing
- test-signing
env:
NODE_VERSION: 22.x
@@ -82,7 +90,7 @@ jobs:
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
SKIP_NOTARIZE: ${{ inputs.skip_notarize }}
SKIP_NOTARIZE: ${{ inputs.skip_mac_notarize }}
- name: Upload Artifact
uses: actions/upload-artifact@v4
@@ -138,11 +146,57 @@ jobs:
- name: Install dependencies
run: pnpm install --frozen-lockfile
# 1. Build (Unsigned)
- name: Build Windows App (${{ matrix.arch }})
run: pnpm run build && pnpm exec electron-builder --config electron-builder.config.ts --win ${{matrix.target}} ${{ matrix.build_arch }} --publish never
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
# 2. Upload Unsigned Artifact to SignPath (Intermediate Step)
- name: Upload Unsigned Artifact for Signing
id: upload-unsigned
uses: actions/upload-artifact@v4
with:
name: unsigned-${{ matrix.arch }}
path: dist/*.exe
retention-days: 1
if-no-files-found: error
# 3. Submit to SignPath and Wait
- name: Sign Artifact with SignPath
uses: signpath/github-action-submit-signing-request@v2
env:
SIGNPATH_SIGNING_POLICY_SLUG: |
${{ (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/v') || inputs.win_signing_mode == 'release-signing')
&& 'release-signing'
|| 'test-signing' }}
ARTIFACT_SLUG: |
${{ (matrix.arch == 'x64-ia32')
&& 'PicGo-Windows'
|| (matrix.arch == 'arm64')
&& 'PicGo-Windows-ARM64'
|| '' }}
with:
api-token: "${{ secrets.SIGNPATH_API_TOKEN }}"
organization-id: "${{ secrets.SIGNPATH_ORGANIZATION_ID }}"
project-slug: "${{ secrets.SIGNPATH_PROJECT_SLUG }}"
signing-policy-slug: "${{ env.SIGNPATH_SIGNING_POLICY_SLUG }}"
github-artifact-id: "${{ steps.upload-unsigned.outputs.artifact-id }}"
artifact-configuration-slug: "${{ env.ARTIFACT_SLUG }}"
wait-for-completion: true
output-artifact-directory: "signed-artifact"
# 4. Replace Unsigned with Signed & Fix Blockmap (Critical for Auto-Update)
- name: Replace Unsigned with Signed & Update latest.yml
shell: powershell
run: |
# Move signed artifacts to dist folder, overwriting existing ones
Move-Item -Path "signed-artifact\*.exe" -Destination "dist\" -Force
Write-Host "✅ Signed artifacts moved to dist folder."
# Run the Node.js script to update latest.yml
node scripts/update-win-yaml.js
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
+79
View File
@@ -0,0 +1,79 @@
const fs = require('fs')
const path = require('path')
const crypto = require('crypto')
const yaml = require('js-yaml')
const distDir = path.join(__dirname, '../dist')
const yamlPath = path.join(distDir, 'latest.yml')
if (!fs.existsSync(yamlPath)) {
console.log('⚠️ latest.yml not found in dist/. Skipping update.')
process.exit(0)
}
console.log(`Reading ${yamlPath}...`)
const yamlContent = fs.readFileSync(yamlPath, 'utf8')
let doc
try {
doc = yaml.load(yamlContent)
} catch (e) {
console.error('❌ Failed to parse latest.yml:', e)
process.exit(1)
}
// Get all .exe files in dist directory
const files = fs.readdirSync(distDir).filter(f => f.endsWith('.exe'))
if (files.length === 0) {
console.log('⚠️ No .exe files found in dist/.')
process.exit(0)
}
let updated = false
files.forEach(file => {
const filePath = path.join(distDir, file)
// 1. Calculate new Hash and Size
const buffer = fs.readFileSync(filePath)
const hash = crypto.createHash('sha512').update(buffer).digest('base64')
const size = fs.statSync(filePath).size
console.log(`Processing ${file}:`)
console.log(` -> New Hash: ${hash}`)
console.log(` -> New Size: ${size}`)
// 2. Update entries in 'files' list
if (Array.isArray(doc.files)) {
const fileEntry = doc.files.find(f => f.url === file)
if (fileEntry) {
fileEntry.sha512 = hash
fileEntry.size = size
updated = true
console.log(' -> Updated file entry in yaml object')
}
}
// 3. Update root path entry (if exists)
// electron-builder's latest.yml usually has root path, sha512, size
// corresponding to the main file of current build (usually x64 or current arch)
if (doc.path === file) {
doc.sha512 = hash
doc.size = size
updated = true
console.log(' -> Updated root path entry in yaml object')
}
})
if (updated) {
// 4. Dump back to file
// lineWidth: -1 prevents long strings from wrapping, keeping it clean
const newYamlContent = yaml.dump(doc, { lineWidth: -1 })
fs.writeFileSync(yamlPath, newYamlContent, 'utf8')
console.log('✅ latest.yml updated successfully.')
console.log('New yaml content:')
console.log(newYamlContent)
} else {
console.log('⚠️ No matching entries found in latest.yml to update.')
}