Skip to content

Commit 4194ee9

Browse files
committed
fix(release): verify test signatures without interactive prompts
Trust test certificates temporarily in the CI machine store instead of the user root store, which displays a confirmation dialog on Windows. Log certificate import and verification stages and bound their runtime. Add a Windows-only manual rehearsal for signing integration iterations. Keep desktop tests on both architectures and require the full test suite for tag releases and the default rehearsal.
1 parent bc64887 commit 4194ee9

3 files changed

Lines changed: 23 additions & 3 deletions

File tree

‎.github/scripts/verify-windows-signature.ps1‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,19 @@ try {
1919
if ($TestCertificate) {
2020
if ($env:GITHUB_ACTIONS -ne 'true') { throw 'Test certificate trust is only permitted on the CI runner' }
2121
if ($signer.Subject -ne $signer.Issuer) { throw 'Expected a self-signed test certificate' }
22-
# 只在临时 runner 上信任本次测试证书,再让 WinVerifyTrust 验证文件内容;不能把 NotTrusted 当通过。
23-
$store = [System.Security.Cryptography.X509Certificates.X509Store]::new('Root', 'CurrentUser')
22+
# CurrentUser 根存储会弹确认窗口;临时 runner 用机器存储,验证后移除。不能把 NotTrusted 当通过。
23+
$store = [System.Security.Cryptography.X509Certificates.X509Store]::new('Root', 'LocalMachine')
2424
$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
2525
$existing = $store.Certificates.Find('FindByThumbprint', $signer.Thumbprint, $false)
2626
if ($existing.Count -eq 0) {
27+
Write-Host "Temporarily trusting test certificate $($signer.Thumbprint) on the CI runner"
2728
$store.Add($signer)
2829
$added = $true
30+
Write-Host 'Test certificate added'
2931
}
3032
}
3133
foreach ($file in $Path) {
34+
Write-Host "Verifying Authenticode signature: $file"
3235
$signature = Get-AuthenticodeSignature -LiteralPath $file
3336
if ($signature.Status -ne 'Valid') { throw "Invalid signature on ${file}: $($signature.Status) $($signature.StatusMessage)" }
3437
if (-not $TestCertificate -and -not $signature.TimeStamperCertificate) { throw "Missing timestamp: $file" }

‎.github/workflows/release.yml‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ on:
3131
description: 演练用的版本号(MAJOR.MINOR.PATCH),不发布
3232
required: true
3333
default: '9.9.9'
34+
windows-only:
35+
description: 仅演练 Windows 签名(仍运行两个架构的桌面单测)
36+
type: boolean
37+
default: false
3438

3539
concurrency:
3640
group: release-${{ github.ref }}
@@ -70,13 +74,15 @@ jobs:
7074
# 发版前把全部测试在真机器上跑一遍:JVM 与各平台的单测,Android 模拟器、Windows 与 macOS 上的原生行为冒烟
7175
# (含全新安装与应用内更新),并行跑,全绿才开始打正式包。用已发布的 SDK,与下面的正式构建一致
7276
test:
77+
if: github.event_name != 'workflow_dispatch' || !inputs.windows-only
7378
uses: ./.github/workflows/test.yml
7479
with:
7580
desktop: true
7681
sdk-main: false
7782

7883
# 签名密钥只进这个 job,负责汇总发布的 release 不碰它。
7984
android:
85+
if: github.event_name != 'workflow_dispatch' || !inputs.windows-only
8086
needs: [version, test]
8187
runs-on: ubuntu-latest
8288
env:
@@ -141,6 +147,7 @@ jobs:
141147

142148
windows:
143149
needs: [version, test]
150+
if: ${{ !cancelled() && needs.version.result == 'success' && (needs.test.result == 'success' || (github.event_name == 'workflow_dispatch' && inputs.windows-only)) }}
144151
permissions:
145152
contents: read
146153
actions: read
@@ -227,6 +234,7 @@ jobs:
227234
output-artifact-directory: ${{ runner.temp }}/signed-launcher
228235

229236
- name: Stage signed application image
237+
timeout-minutes: 5
230238
shell: pwsh
231239
run: |
232240
$ErrorActionPreference = 'Stop'
@@ -282,6 +290,7 @@ jobs:
282290
output-artifact-directory: ${{ runner.temp }}/signed-msi
283291

284292
- name: Verify signed packages
293+
timeout-minutes: 10
285294
shell: pwsh
286295
run: |
287296
$ErrorActionPreference = 'Stop'
@@ -319,6 +328,7 @@ jobs:
319328

320329
# Apple 芯片。jpackage 不能交叉构建,Intel Mac 要另起 macos-15-intel runner,暂不出
321330
macos:
331+
if: github.event_name != 'workflow_dispatch' || !inputs.windows-only
322332
needs: [version, test]
323333
runs-on: macos-15
324334
env:
@@ -361,6 +371,7 @@ jobs:
361371
# x64 AppImage 与 app-image 的 tar.gz。MediaMP 的 mpv 运行库没有 linux-arm64,Linux 只出 x64。
362372
# 打包时的 AOT 训练要开窗,套一层 xvfb-run;appimagetool 与运行时的版本和摘要钉在 build-appimage.sh 里
363373
linux:
374+
if: github.event_name != 'workflow_dispatch' || !inputs.windows-only
364375
needs: [version, test]
365376
runs-on: ubuntu-24.04
366377
env:

‎docs/development/windows-signing.md‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,19 @@ Windows job 应显式配置 contents: read、actions: read。所有签名前置
5454
- x64 和 ARM64 分别在对应 GitHub runner 上验证。
5555

5656
verify-windows-signature.ps1 使用系统 Authenticode 验证签名,并要求 EXE、MSI 使用同一证书。
57-
测试证书只在 GitHub runner 的 CurrentUser 根证书存储中临时信任,验证完移除;正式签名
57+
测试证书只在 GitHub runner 的 LocalMachine 根证书存储中临时信任,验证完移除;CurrentUser
58+
根存储会弹出交互式确认窗口,不适合 CI。正式签名
5859
还要求时间戳。verify-windows-packages.ps1 检查清单与更新 ZIP,解开便携包并通过
5960
msiexec /a 解开 MSI,比对各处启动器的 SHA-256。
6061

6162
本机 Gradle 原生缓存需要沙箱外访问;此前 native-platform.dll 加载失败与此有关。
6263
首次演练完成后的真实签名结果以 Actions run 和 Step summary 中的 SignPath 请求链接为准。
6364

65+
首次完整演练的所有前置测试已通过,GitHub App 安装后两个架构的 EXE 均成功签名。
66+
调试后续签名步骤可用 `gh workflow run release.yml -f version=9.9.9 -f windows-only=true`,
67+
仅运行 Windows 构建和两个架构各自的桌面单测;Windows 产物保留在 workflow 中,不汇总
68+
其他平台、不创建 Release。默认完整演练与 tag 发布仍要求全部前置测试。
69+
6470
## 官方依据
6571

6672
- [GitHub integration](https://docs.signpath.io/trusted-build-systems/github)

0 commit comments

Comments
 (0)