mirror of
https://github.com/dream-pep/koring-launcher.git
synced 2026-09-12 05:45:18 +08:00
build(签名流程): 优化签名流程以减少SignPath配额使用,添加相关控制
- 配置electron-builder仅使用SHA256算法签名,避免双签名以减半配额消耗 - 为签名脚本添加配额耗尽处理,超出后跳过后续签名任务 - 新增仅签名主安装包选项和发布工作流签名开关 - 在发布笔记中添加签名状态展示 - 更新自动更新文档,补充SignPath配额问题及解决方案
This commit is contained in:
@@ -46,6 +46,11 @@ on:
|
|||||||
description: '基础版本号,如 1.2.0'
|
description: '基础版本号,如 1.2.0'
|
||||||
required: true
|
required: true
|
||||||
default: '1.2.0'
|
default: '1.2.0'
|
||||||
|
sign:
|
||||||
|
description: '是否使用 SignPath 签名(配额不足时自动跳过)'
|
||||||
|
required: true
|
||||||
|
type: boolean
|
||||||
|
default: true
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
@@ -56,11 +61,15 @@ jobs:
|
|||||||
# 声明使用 Environment "BUILDER",才能读取其中的环境 Secret SIGNPATH_API_TOKEN
|
# 声明使用 Environment "BUILDER",才能读取其中的环境 Secret SIGNPATH_API_TOKEN
|
||||||
environment: BUILDER
|
environment: BUILDER
|
||||||
env:
|
env:
|
||||||
SIGNPATH_API_TOKEN: ${{ secrets.SIGNPATH_API_TOKEN }}
|
# 勾选 sign 才注入 token 走 SignPath 签名;不勾选则 token 为空,模块自动跳过签名
|
||||||
|
SIGNPATH_API_TOKEN: ${{ inputs.sign && secrets.SIGNPATH_API_TOKEN || '' }}
|
||||||
SIGNPATH_ORG_ID: 31ecd033-d59e-492b-a70b-b00a54bbc7c2
|
SIGNPATH_ORG_ID: 31ecd033-d59e-492b-a70b-b00a54bbc7c2
|
||||||
SIGNPATH_PROJECT_SLUG: Koring_Launcher
|
SIGNPATH_PROJECT_SLUG: Koring_Launcher
|
||||||
SIGNPATH_SIGNING_POLICY_SLUG: Koring_Launcher_Dev_builder
|
SIGNPATH_SIGNING_POLICY_SLUG: Koring_Launcher_Dev_builder
|
||||||
SIGNPATH_ARTIFACT_CONFIG_SLUG: ${{ secrets.SIGNPATH_ARTIFACT_CONFIG_SLUG }}
|
SIGNPATH_ARTIFACT_CONFIG_SLUG: ${{ secrets.SIGNPATH_ARTIFACT_CONFIG_SLUG }}
|
||||||
|
# 内部测试阶段:SignPath 年度配额(约 500MB)耗尽时跳过签名、照常发布(产物未签名)。
|
||||||
|
# ⚠️ 正式发布请删除此行并升级 SignPath 套餐(同时建议 SIGNPATH_ONLY_INSTALLER=false 全量签名)。
|
||||||
|
SIGNPATH_SKIP_ON_QUOTA: 'true'
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
@@ -113,6 +122,7 @@ jobs:
|
|||||||
-BaseVersion "${{ inputs.version }}" `
|
-BaseVersion "${{ inputs.version }}" `
|
||||||
-FullVersion "${{ steps.version.outputs.full }}" `
|
-FullVersion "${{ steps.version.outputs.full }}" `
|
||||||
-Mode "${{ inputs.mode }}" `
|
-Mode "${{ inputs.mode }}" `
|
||||||
|
-SigningStatus "${{ inputs.sign && '已签名' || '未签名' }}" `
|
||||||
-OutputPath release-notes.md
|
-OutputPath release-notes.md
|
||||||
|
|
||||||
- name: Publish GitHub Release
|
- name: Publish GitHub Release
|
||||||
|
|||||||
@@ -269,11 +269,22 @@ src/
|
|||||||
SigningPolicySlug / ArtifactConfigurationSlug? / Description / 文件部件 **Artifact**)→
|
SigningPolicySlug / ArtifactConfigurationSlug? / Description / 文件部件 **Artifact**)→
|
||||||
响应 **Location 头** = 请求 URL → 轮询 `status`/`isFinalStatus` → 完成后取 **signedArtifactLink** 下载;
|
响应 **Location 头** = 请求 URL → 轮询 `status`/`isFinalStatus` → 完成后取 **signedArtifactLink** 下载;
|
||||||
认证 `Authorization: Bearer <token>`。
|
认证 `Authorization: Bearer <token>`。
|
||||||
- ✅ 98.3MB setup.exe 提交成功(无大小限制问题);自动批准生效(InProgress → Completed 无人工介入)
|
- ✅ 98.3MB setup.exe 提交成功;自动批准生效(InProgress → Completed 无人工介入)
|
||||||
- ✅ 小文件端到端签名成功,`signtool verify` 显示签名链 **Issued to: Lingke Network**
|
- ✅ 小文件端到端签名成功,`signtool verify` 显示签名链 **Issued to: Lingke Network**
|
||||||
- ⚠️ 本机到 SignPath 下载 100MB+ 产物极慢(20min+),CI(GitHub Actions)网络环境不受影响;
|
- ⚠️ 本机到 SignPath 下载 100MB+ 产物极慢(20min+),CI(GitHub Actions)网络环境不受影响;
|
||||||
模块已加下载重试(3 次)+ 临时文件替换
|
模块已加下载重试(3 次)+ 临时文件替换
|
||||||
|
|
||||||
|
**2026-08-28 CI 首跑教训(配额)**:
|
||||||
|
- ⚠️ **SignPath 年度配额 ≈ 500MB**("Yearly quota for artifact size has been exceeded"),
|
||||||
|
一次全量签名构建(sha1+sha256 双签)即消耗 ~458MB,直接耗尽配额,发布失败。
|
||||||
|
- 修复(已落地):`win.signtoolOptions.signingHashAlgorithms: [sha256]` —— 只按 SHA256 单签,
|
||||||
|
每个文件只签一次,配额减半(全量构建 ~278MB);
|
||||||
|
可选 `SIGNPATH_ONLY_INSTALLER=true` 只签 setup.exe(~97MB/构建)。
|
||||||
|
- **内部测试策略(已落地)**:workflow 设置 `SIGNPATH_SKIP_ON_QUOTA=true` —— 配额耗尽时
|
||||||
|
跳过签名、照常发布(产物未签名,electron-updater 发布者校验自动跳过);首次命中后记住状态,
|
||||||
|
后续文件不再重复提交。⚠️ 正式发布务必移除该开关。
|
||||||
|
- **治本仍需升级 SignPath 套餐**或等待年度配额重置;正式发布(run)建议全量签名 + 生产证书。
|
||||||
|
|
||||||
**验证点(首次 CI 运行)**:确认 SignPath 请求全部 Completed、`latest.yml` 的 sha512
|
**验证点(首次 CI 运行)**:确认 SignPath 请求全部 Completed、`latest.yml` 的 sha512
|
||||||
与上传的 signed setup.exe 一致、签名链显示 "Lingke Network"。
|
与上传的 signed setup.exe 一致、签名链显示 "Lingke Network"。
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -19,7 +19,12 @@ win:
|
|||||||
requestedExecutionLevel: asInvoker
|
requestedExecutionLevel: asInvoker
|
||||||
# SignPath 远程签名:scripts/signpath-sign.js
|
# SignPath 远程签名:scripts/signpath-sign.js
|
||||||
# 无 SIGNPATH_API_TOKEN 时自动跳过(本地构建不受影响)
|
# 无 SIGNPATH_API_TOKEN 时自动跳过(本地构建不受影响)
|
||||||
sign: scripts/signpath-sign.js
|
# signingHashAlgorithms 只保留 sha256:避免 electron-builder 对每个文件
|
||||||
|
# 按 sha1+sha256 双算法各签一次(远程签名会重复消耗 SignPath 配额)
|
||||||
|
signtoolOptions:
|
||||||
|
signingHashAlgorithms:
|
||||||
|
- sha256
|
||||||
|
sign: scripts/signpath-sign.js
|
||||||
mac:
|
mac:
|
||||||
target: dmg
|
target: dmg
|
||||||
icon: build/icon.png
|
icon: build/icon.png
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ param(
|
|||||||
[Parameter(Mandatory = $true)][string] $BaseVersion,
|
[Parameter(Mandatory = $true)][string] $BaseVersion,
|
||||||
[Parameter(Mandatory = $true)][string] $FullVersion,
|
[Parameter(Mandatory = $true)][string] $FullVersion,
|
||||||
[Parameter(Mandatory = $true)][string] $Mode,
|
[Parameter(Mandatory = $true)][string] $Mode,
|
||||||
|
[string] $SigningStatus = "已签名",
|
||||||
[string] $OutputPath = "release-notes.md"
|
[string] $OutputPath = "release-notes.md"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -66,6 +67,7 @@ $content = @"
|
|||||||
## 版本信息
|
## 版本信息
|
||||||
当前版本 $FullVersion
|
当前版本 $FullVersion
|
||||||
编译状态:$status
|
编译状态:$status
|
||||||
|
签名状态:$SigningStatus
|
||||||
|
|
||||||
## 更新了什么内容
|
## 更新了什么内容
|
||||||
$commitsSection
|
$commitsSection
|
||||||
|
|||||||
@@ -147,11 +147,36 @@ async function downloadWithRetry(downloadUrl, headers) {
|
|||||||
/**
|
/**
|
||||||
* electron-builder 自定义签名入口。
|
* electron-builder 自定义签名入口。
|
||||||
* configuration.path 为待签名文件绝对路径;无 token 时跳过(本地开发构建)。
|
* configuration.path 为待签名文件绝对路径;无 token 时跳过(本地开发构建)。
|
||||||
|
*
|
||||||
|
* SIGNPATH_SKIP_ON_QUOTA=true(内部测试用):
|
||||||
|
* SignPath 年度配额耗尽时跳过签名并继续构建(产物为未签名),
|
||||||
|
* 首次命中配额错误后记住状态,后续文件不再尝试提交。
|
||||||
|
* 正式发布请移除该开关并升级 SignPath 套餐。
|
||||||
*/
|
*/
|
||||||
|
let quotaExhausted = false;
|
||||||
|
|
||||||
module.exports = async function signPathSign(configuration) {
|
module.exports = async function signPathSign(configuration) {
|
||||||
if (!process.env.SIGNPATH_API_TOKEN || !process.env.SIGNPATH_ORG_ID) {
|
if (!process.env.SIGNPATH_API_TOKEN || !process.env.SIGNPATH_ORG_ID) {
|
||||||
console.log(`[signpath-sign] no SignPath credentials, skip signing: ${configuration.name}`);
|
console.log(`[signpath-sign] no SignPath credentials, skip signing: ${configuration.name}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await signWithSignPath(configuration.path);
|
if (quotaExhausted) {
|
||||||
|
console.warn(`[signpath-sign] quota exhausted — SKIP signing (UNSIGNED): ${configuration.name}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 配额省用模式:只签最终安装包(isNsis=true),跳过内部 exe / 卸载器
|
||||||
|
if (process.env.SIGNPATH_ONLY_INSTALLER === 'true' && !configuration.isNsis) {
|
||||||
|
console.log(`[signpath-sign] SIGNPATH_ONLY_INSTALLER, skip inner file: ${configuration.name}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await signWithSignPath(configuration.path);
|
||||||
|
} catch (err) {
|
||||||
|
if (process.env.SIGNPATH_SKIP_ON_QUOTA === 'true' && /quota/i.test(err.message)) {
|
||||||
|
quotaExhausted = true;
|
||||||
|
console.warn(`[signpath-sign] SignPath quota exceeded — skip remaining files, artifact will be UNSIGNED: ${err.message}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user