桌面应用 —— 构建、签名与下载渠道(运维)¶
用于构建、签名并发布到 /download/ 的 macOS 与 Windows 桌面客户端基础设施。
代码概览:macOS desktop、Windows desktop。
构建基础设施 —— 自托管 runner¶
WinUI/MSIX 无法在 macOS 上构建,Xcode 也无法在 Windows 上运行,因此每个平台 各自使用一台专用的自托管 GitHub Actions runner:
| Runner | 主机 | 标签 | 工作流 |
|---|---|---|---|
win11-build |
Windows 11 Pro(38.180.136.249) |
self-hosted, Windows, X64, windows-signing |
.github/workflows/windows-app.yml(selfhosted job) |
imacpro-macos |
iMac Pro(macOS 14,Intel) | self-hosted, macOS |
.github/workflows/macos-app.yml |
Runner 以服务方式运行(重启后自动启动),运行身份为 deploy 用户。
工具链(.NET 8、git、Xcode、xcodegen)安装在主机上;MSIX 所需的 makeappx/signtool
来自 NuGet(Microsoft.Windows.SDK.BuildTools[.MSIX]),因此无需安装系统级 Windows SDK。
Runner 离线
已派发的任务要求对应 runner 处于在线状态 —— 若离线,任务将进入排队。
查看 runner 状态:gh api repos/OWNER/REPO/actions/runners。
下载渠道 —— /download/¶
部署使用 forced-command SSH(仅允许执行 ci-deploy.sh),因此无法通过 scp 上传到服务器。
所以二进制文件只能经由 git 仓库(deploy/downloads/)送达服务器:
runner:构建 + 签名 → deploy/downloads/{eid-mongolia.dmg, eid-mongolia-setup.msix, *.cer}
→ git commit + push(main)
staging ci-deploy:git reset --hard origin/main → 强制重建 nginx
nginx(deploy/nginx/staging.conf,location ^~ /download/)→ /srv/download(挂载)
网站下载按钮:web/src/components/landing/DesktopAppSection.tsx、
web/src/app/solutions/page.tsx。
Git 体积
每次发布时 .msix(约 37MB)都会进入 git 历史。若发布频繁,请迁移到
Git LFS(.gitattributes:deploy/downloads/*.msix,*.dmg filter=lfs)。
服务器上必须安装 git-lfs(否则 nginx 只会返回指针文件)。
重新发布¶
Windows: GitHub → Actions →“Windows desktop”→ Run workflow(或
gh workflow run windows-app.yml)。selfhosted job 负责构建 + 签名 + 发布。
macOS: GitHub → Actions →“macOS desktop”→ Run workflow(或
gh workflow run macos-app.yml)。在 workflow_dispatch 时会发布 .dmg。
生产环境签名¶
当前状态:macOS .dmg 为 adhoc(未签名),Windows .msix 使用自签名开发证书。
两者均可安装,但系统会给出警告。若要面向公众进行“干净”的分发:
macOS —— Apple Developer ID + 公证¶
Apple Team:CQTHTD6YJQ(Gerege Systems LLC)—— 与 iOS 相同。添加以下
GitHub secrets 后,macos-app.yml 会自动完成签名与公证:
| Secret | 取值 |
|---|---|
MACOS_SIGN_IDENTITY |
Developer ID Application: Gerege Systems LLC (CQTHTD6YJQ) |
MACOS_CERT_P12_BASE64 |
Developer ID Application .p12 的 base64(base64 -i cert.p12) |
MACOS_CERT_PASSWORD |
.p12 密码 |
MACOS_NOTARY_KEY_BASE64 |
App Store Connect API 密钥 .p8 的 base64 |
MACOS_NOTARY_KEY_ID |
API 密钥 ID |
MACOS_NOTARY_ISSUER_ID |
Issuer ID |
获取证书:developer.apple.com → Certificates → Developer ID Application →
从钥匙串导出 .p12。API 密钥:App Store Connect → Users and Access → Keys。
Windows —— EV/OV 代码签名证书¶
将 tools/pack-msix.ps1 的 -PfxPath 指向真实证书(或改用 Azure Trusted Signing),
并替换 windows-app.yml 中的 New-DevCert 步骤。证书的 subject DN 必须与
Package.appxmanifest 中的 Publisher 完全一致
(CN=Gerege Systems LLC, O=Gerege Systems LLC, C=MN)。自 2023 年起证书必须存放于
硬件令牌 / HSM,因此对 CI 而言 Azure Trusted Signing(约 10 美元/月)是最合适的选择。
自动更新(尚未配置)¶
- macOS:Sparkle(
SUFeedURL: e-id.mn/download/appcast.xml)—— 需要scripts/gen_appcast.sh与一把 EdDSA 密钥(SPARKLE_ED_PRIVATE_KEY)。 - Windows:
.appinstaller(tools/publish-appinstaller.ps1)—— 将已签名的.msix与.appinstaller一并放入/download/。