fix(desktop): bridge workflow modes for older sources

This commit is contained in:
winewill
2026-11-04 13:57:19 +08:00
parent d65fd521b5
commit e0e2c63a9c
13 changed files with 21 additions and 16 deletions
+2 -1
View File
@@ -75,7 +75,8 @@ jobs:
PACKAGE_MACOS_ZIP_COMPRESSION_LEVEL: ${{ inputs.compression_level }}
PACKAGE_SKIP_NOTARIZATION: ${{ inputs.skip_notarization }}
PACKAGE_SOURCE_REF: ${{ inputs.source_ref }}
PACKAGE_VERSION_MODE: ${{ inputs.version_mode }}
# TODO: Remove this legacy source_ref mode mapping on 2027-01-04 with the parser aliases.
PACKAGE_VERSION_MODE: ${{ inputs.version_mode == 'follow-dsh' && 'product' || inputs.version_mode == 'build-number' && 'auto' || inputs.version_mode }}
DSH_DESKTOP_UPDATE_CHANNEL: ${{ inputs.update_channel }}
DSH_TELEMETRY_DISABLED: '1'
DSH_PACKAGING_PRESET: ${{ inputs.preset }}
+2 -1
View File
@@ -75,7 +75,8 @@ jobs:
PACKAGE_MACOS_ZIP_COMPRESSION_LEVEL: ${{ inputs.compression_level }}
PACKAGE_SKIP_NOTARIZATION: ${{ inputs.skip_notarization }}
PACKAGE_SOURCE_REF: ${{ inputs.source_ref }}
PACKAGE_VERSION_MODE: ${{ inputs.version_mode }}
# TODO: Remove this legacy source_ref mode mapping on 2027-01-04 with the parser aliases.
PACKAGE_VERSION_MODE: ${{ inputs.version_mode == 'follow-dsh' && 'product' || inputs.version_mode == 'build-number' && 'auto' || inputs.version_mode }}
DSH_DESKTOP_UPDATE_CHANNEL: ${{ inputs.update_channel }}
DSH_TELEMETRY_DISABLED: '1'
DSH_PACKAGING_PRESET: ${{ inputs.preset }}
+2 -1
View File
@@ -77,7 +77,8 @@ jobs:
shell: pwsh
env:
PACKAGE_SOURCE_REF: ${{ inputs.source_ref }}
PACKAGE_VERSION_MODE: ${{ inputs.version_mode }}
# TODO: Remove this legacy source_ref mode mapping on 2027-01-04 with the parser aliases.
PACKAGE_VERSION_MODE: ${{ inputs.version_mode == 'follow-dsh' && 'product' || inputs.version_mode == 'build-number' && 'auto' || inputs.version_mode }}
DSH_DESKTOP_UPDATE_CHANNEL: ${{ inputs.update_channel }}
DSH_TELEMETRY_DISABLED: '1'
DSH_PACKAGING_PRESET: ${{ inputs.preset }}
+2 -2
View File
@@ -24,8 +24,8 @@
en: 5b4f0f80a117f202
zh: ff05be196c181087
/desktop-packaging/windows-actions-packaging:
en: 83706649764cd891
zh: 05a7d0e853747cd6
en: 1ddc3a9c9f2d3b5c
zh: 032c0f2c740fdfdd
/desktop-packaging/macos-self-hosted-packaging:
en: 3bd14c640893b192
zh: 7c236cbe46be4a47
+1 -1
View File
@@ -111,7 +111,7 @@ For supervised runner startup and recovery, follow [Windows runner machine setup
The `Package Desktop · Windows · x64` [manual workflow](../../../.github/workflows/windows-package.yml) selects the dedicated Windows x64 runner label `dsh-win-package-trial` and the machine preset `test` or `production`. Choose `signed` (default) or `unsigned`; signed mode uses the existing EV token preflight, signature cache and failure interlock. It does not publish or upload a release. `version_mode` defaults to `default` (product version for production, build numbering for test); `build-number` uses the CI identifier in [Release versions](#release-versions); an explicit value may be the checkout's product version or an extended build version such as `0.2.1-alpha.1.20261009.1` for product `0.2.1-alpha.1`. The version prefix must match the selected checkout; validation errors show its current example. Manifests remain unchanged.
Select the workflow in Actions, choose the source branch, preset, signing mode and version, then click Run workflow. Before merging input changes, test the pushed branch with `gh workflow run windows-package.yml --ref <branch> -f preset=test -f signing=unsigned -f version_mode=build-number`; verify the web form after merging. There is no push or PR trigger. Logs and successful EXEs are retained for 14 days. Inspect the retained logs and installer before relying on packaging; installation is separate. Before checkout, Node removes the runner-owned source directory without following dependency junctions; the workflow validates its location and rejects linked ancestors. Never point it at a development checkout. Runs share one concurrency group without cancelling an active build; only one run remains pending, and a newer dispatch replaces it. Diagnostics upload requires a successful clean checkout. Machine settings stay outside the checkout and are never uploaded as artifacts.
Select the workflow in Actions, choose the source branch, preset, signing mode and version, then click Run workflow. Before merging input changes, test the pushed branch with `gh workflow run windows-package.yml --ref <branch> -f source_ref=<branch> -f preset=test -f signing=unsigned -f version_mode=build-number`; verify the web form after merging. There is no push or PR trigger. Logs and successful EXEs are retained for 14 days. Inspect the retained logs and installer before relying on packaging; installation is separate. Before checkout, Node removes the runner-owned source directory without following dependency junctions; the workflow validates its location and rejects linked ancestors. Never point it at a development checkout. Runs share one concurrency group without cancelling an active build; only one run remains pending, and a newer dispatch replaces it. Diagnostics upload requires a successful clean checkout. Machine settings stay outside the checkout and are never uploaded as artifacts.
All Windows packaging modes, including test and unsigned, require the repository variable `DESKTOP_PUBLISH_RUNNERS`; configure the [original-machine route](../publishing/ci/README.md#machine-setup) before dispatch.
+1 -1
View File
@@ -111,7 +111,7 @@ runner 的受监督启动和恢复见 [Windows runner 机器准备](../windows-s
`Package Desktop · Windows · x64` [手动工作流](../../../.github/workflows/windows-package.yml) 选择专用 Windows x64 runner 标签 `dsh-win-package-trial`,并使用机器 preset `test` 或 `production`。选择 `signed`(默认)或 `unsigned`;签名模式复用现有 EV token 预检、签名缓存与失败 interlock,不发布或上传 release。`version_mode` 默认为 `default`(production 使用产品版本,test 追加构建编号);`build-number` 使用[发布版本](#release-versions)中的 CI 标识;显式值可以是源码产品版本,或扩展构建版本,例如产品 `0.2.1-alpha.1` 对应 `0.2.1-alpha.1.20261009.1`。版本前缀必须匹配所选源码;校验错误显示其当前示例。manifest 保持不变。
在 Actions 选择工作流、源码分支、preset、签名模式和版本,再点击 Run workflow。输入变更合并前,用 `gh workflow run windows-package.yml --ref <branch> -f preset=test -f signing=unsigned -f version_mode=build-number` 测试已推送分支;合并后验证网页表单。它不监听 push 或 PR。日志和成功生成的 EXE 保留 14 天。依赖打包流程前检查日志和安装包;安装是独立操作。检出前,Node 删除 runner 专用源码目录,不跟随依赖 junction;工作流校验目标位置并拒绝链接祖先目录。不得指向日常开发目录。运行共享一个并发组,不取消正在进行的构建;最多保留一个待运行任务,新触发会替换它。仅在成功完成干净检出后上传诊断。机器配置位于 checkout 之外,不作为产物上传。
在 Actions 选择工作流、源码分支、preset、签名模式和版本,再点击 Run workflow。输入变更合并前,用 `gh workflow run windows-package.yml --ref <branch> -f source_ref=<branch> -f preset=test -f signing=unsigned -f version_mode=build-number` 测试已推送分支;合并后验证网页表单。它不监听 push 或 PR。日志和成功生成的 EXE 保留 14 天。依赖打包流程前检查日志和安装包;安装是独立操作。检出前,Node 删除 runner 专用源码目录,不跟随依赖 junction;工作流校验目标位置并拒绝链接祖先目录。不得指向日常开发目录。运行共享一个并发组,不取消正在进行的构建;最多保留一个待运行任务,新触发会替换它。仅在成功完成干净检出后上传诊断。机器配置位于 checkout 之外,不作为产物上传。
所有 Windows 打包模式(含 test 和 unsigned)都要求仓库变量 `DESKTOP_PUBLISH_RUNNERS`;触发前配置[原机器路由](../publishing/ci/README.zh.md#machine-setup)。
+2 -2
View File
@@ -24,8 +24,8 @@
en: 0f43f2e193e95043
zh: 1c1efb062c06f7b8
/desktop-ci-publication/package-and-publish:
en: dd0a0020cb4e911d
zh: 9521d4ba2e3ef31b
en: f0f7817a03b9feb4
zh: e8756c06bc688162
/desktop-ci-publication/recovery-and-records:
en: 266afba2adeeadef
zh: 063114103585dae8
+1 -1
View File
@@ -70,7 +70,7 @@ Environment approval gates this workflow, not arbitrary code running under the s
For publication to either test or production, choose Windows `signing=signed` or leave macOS **Skip notarization** unchecked. Unsigned and unnotarized packages are only for internal debugging; they cannot publish or provide automatic updates. Before installing dependencies, the hosted routing job rejects debugging artifacts identified by the selected run and attempt. An archive-only rerun retains the original build attempt in artifact names, so this early check can miss it; local manifest qualification still rejects debugging builds before publication. Missing artifact metadata does not establish eligibility: the original machine still validates its retained manifest and signatures. A debugging-package rejection requires a new signed/notarized package and its run ID / attempt; retrying publication cannot qualify the existing bytes.
Select the platform's `Package Desktop` workflow, preset, source, channel and version mode. `source_ref` accepts repository branch names (for example `feature/desktop-update`) or `dsh-v*` tags for test; production accepts only `master` or `dsh-v*` tags. Names matching `dsh-v` followed by a digit and letters, digits, dots or hyphens are treated as tags, even if a branch has that name. Tags must match the selected product version. We recommend dispatching the packaging workflow from `master` and enter the source separately; raw commit SHAs, PR refs and fork repositories are not supported. The selected source must contain the CI adapters, so older sources fail before dependency installation. Only select trusted branches: their build code runs on the signing machine. This is an operating convention, not enforced workflow-origin or credential isolation. Publication uses the recorded commit and requires it to remain in the selected branch history; normal branch advances are allowed, deletion or a diverging force-push rejects. Tag publication requires the tag to still resolve to the recorded commit. Dispatch the publisher from `master`; its hosted routing job rejects other refs before scheduling the original machine. The packaged source commit is recorded separately. `version_mode=default` selects follow-dsh for production and build-number for test; follow-dsh preserves the selected checkout’s dsh version, build-number appends date/run/attempt in either environment, and manual requires `build_version`. Existing dispatch commands using `-f version_mode=auto` must use `-f version_mode=build-number`, and `-f version_mode=product` becomes `-f version_mode=follow-dsh`; the local CLI option `--build-version auto` is unchanged. The operator-selected channel accepts any supported build version, including alpha and RC versions; it does not change version precedence or permit client downgrades. The optional `test_release_id` is the test URL prefix: blank retains the machine default, successive upgrade tests on that platform need the same value, and defaults should be rotated periodically. It is not a GitHub run ID. See [packaging configuration](../../packaging/README.md#configuration-and-local-builds) for its validation and rotation limits.
Select the platform's `Package Desktop` workflow, preset, source, channel and version mode. `source_ref` accepts repository branch names (for example `feature/desktop-update`) or `dsh-v*` tags for test; production accepts only `master` or `dsh-v*` tags. Names matching `dsh-v` followed by a digit and letters, digits, dots or hyphens are treated as tags, even if a branch has that name. Tags must match the selected product version. We recommend dispatching the packaging workflow from `master` and enter the source separately; raw commit SHAs, PR refs and fork repositories are not supported. The selected source must contain the CI adapters, so older sources fail before dependency installation. Only select trusted branches: their build code runs on the signing machine. This is an operating convention, not enforced workflow-origin or credential isolation. Publication uses the recorded commit and requires it to remain in the selected branch history; normal branch advances are allowed, deletion or a diverging force-push rejects. Tag publication requires the tag to still resolve to the recorded commit. Dispatch the publisher from `master`; its hosted routing job rejects other refs before scheduling the original machine. The packaged source commit is recorded separately. `version_mode=default` selects follow-dsh for production and build-number for test; follow-dsh preserves the selected checkout’s dsh version, build-number appends date/run/attempt in either environment, and manual requires `build_version`. Existing dispatch commands using `-f version_mode=auto` must use `-f version_mode=build-number`, and `-f version_mode=product` becomes `-f version_mode=follow-dsh`; the local CLI option `--build-version auto` is unchanged. Until 2027-01-04, workflows pass legacy mode names to support older selected sources, and current parsers accept both names. The operator-selected channel accepts any supported build version, including alpha and RC versions; it does not change version precedence or permit client downgrades. The optional `test_release_id` is the test URL prefix: blank retains the machine default, successive upgrade tests on that platform need the same value, and defaults should be rotated periodically. It is not a GitHub run ID. See [packaging configuration](../../packaging/README.md#configuration-and-local-builds) for its validation and rotation limits.
Packaging only retains files. After success, open **Publish Desktop · COS → Run workflow** on `master`, enter `package_run_id` from the packaging run URL, and optionally enter `package_run_attempt`. Blank selects the latest attempt and its successful package job. An archival-only retry retains the original build attempt; a failed newer package job never falls back to an older success. An explicit attempt selects that build even when its separate GitHub archival failed. Windows must be signed; macOS must finish notarization and stapling. GitHub job evidence selects the original runner; its local manifest supplies the preset, version, source and channel before approval. No installer or request artifact is downloaded. Retained packages with the old `publishRequested=false` flag remain eligible; missing or changed local files stop publication.
+1 -1
View File
@@ -70,7 +70,7 @@ Environment 审批限制此工作流,不限制同一机器账户运行的任
发布到 test 或 production 都必须在 Windows 选择 `signing=signed`,或在 macOS 不勾选**跳过公证**。无签名、无公证的包仅限内部调试,不能发布或用于自动更新。托管路由 job 会在安装依赖前,依据所选 run 和 attempt 对应的 artifact 名称拒绝已标明的调试包。仅重跑归档时,artifact 名称保留原构建 attempt,早期检查可能未识别该包;本地清单资格校验仍会在发布前拒绝调试包。缺少 artifact 元数据不代表允许发布:原机器仍会验证留存清单和签名。遇到调试包拒绝提示时,需重新完成签名或公证,再使用新包的 run ID / attempt 发布;重跑发布不能使现有产物获得发布资格。
选择对应平台的 `Package Desktop` 工作流、preset、源码、通道和版本模式。test 的 `source_ref` 接受仓库内分支名(如 `feature/desktop-update`)或 `dsh-v*` tag;production 仅接受 `master` 或 `dsh-v*` tag。符合 `dsh-v` 后接数字、其余为字母、数字、点或连字符的名称按 tag 处理,即使存在同名分支。tag 必须与所选产品版本一致。建议从 `master` 启动打包工作流,再单独填写打包源码;不支持直接填写 commit SHA、PR ref 或 fork 仓库。源码必须包含 CI 适配脚本,旧源码会在安装依赖前失败。仅选择可信分支:其构建代码将在签名机器上执行。这是操作约定,不提供工作流来源强制限制或凭据隔离。发布使用记录的 commit,并要求该提交仍在所选分支历史中;正常追加提交不影响发布,删除分支或导致历史分叉的强推会拒绝。tag 发布要求 tag 仍指向记录的提交。从 `master` 发起发布;托管路由 job 会在派发到原机器前拒绝其他 ref。实际打包源码提交单独记录。`version_mode=default` 对 production 选择 follow-dsh,对 test 选择 build-number;follow-dsh 跟随所选源码的 dsh 包版本号,build-number 在任一环境均追加日期/run/attempt,manual 要求填写 `build_version`。已有派发命令中的 `-f version_mode=auto` 须改为 `-f version_mode=build-number`,`-f version_mode=product` 改为 `-f version_mode=follow-dsh`;本地 CLI 的 `--build-version auto` 不变。操作人员选择的渠道接受任意受支持的构建版本,包括 alpha 和 RC 版本;渠道不改变版本优先级,也不允许客户端降级。可选 `test_release_id` 是测试 URL 前缀:留空沿用机器默认值,同一平台连续升级测试需保持相同值,并应定期轮换默认值。它不是 GitHub run ID。格式校验和轮换限制见[打包配置](../../packaging/README.zh.md#configuration-and-local-builds)。
选择对应平台的 `Package Desktop` 工作流、preset、源码、通道和版本模式。test 的 `source_ref` 接受仓库内分支名(如 `feature/desktop-update`)或 `dsh-v*` tag;production 仅接受 `master` 或 `dsh-v*` tag。符合 `dsh-v` 后接数字、其余为字母、数字、点或连字符的名称按 tag 处理,即使存在同名分支。tag 必须与所选产品版本一致。建议从 `master` 启动打包工作流,再单独填写打包源码;不支持直接填写 commit SHA、PR ref 或 fork 仓库。源码必须包含 CI 适配脚本,旧源码会在安装依赖前失败。仅选择可信分支:其构建代码将在签名机器上执行。这是操作约定,不提供工作流来源强制限制或凭据隔离。发布使用记录的 commit,并要求该提交仍在所选分支历史中;正常追加提交不影响发布,删除分支或导致历史分叉的强推会拒绝。tag 发布要求 tag 仍指向记录的提交。从 `master` 发起发布;托管路由 job 会在派发到原机器前拒绝其他 ref。实际打包源码提交单独记录。`version_mode=default` 对 production 选择 follow-dsh,对 test 选择 build-number;follow-dsh 跟随所选源码的 dsh 包版本号,build-number 在任一环境均追加日期/run/attempt,manual 要求填写 `build_version`。已有派发命令中的 `-f version_mode=auto` 须改为 `-f version_mode=build-number`,`-f version_mode=product` 改为 `-f version_mode=follow-dsh`;本地 CLI 的 `--build-version auto` 不变。截至 2027-01-04,工作流向所选源码传递旧模式名以兼容旧源码,当前解析器同时接受新旧名称。操作人员选择的渠道接受任意受支持的构建版本,包括 alpha 和 RC 版本;渠道不改变版本优先级,也不允许客户端降级。可选 `test_release_id` 是测试 URL 前缀:留空沿用机器默认值,同一平台连续升级测试需保持相同值,并应定期轮换默认值。它不是 GitHub run ID。格式校验和轮换限制见[打包配置](../../packaging/README.zh.md#configuration-and-local-builds)。
打包只保留文件。成功后,在 `master` 上打开 **Publish Desktop · COS → Run workflow**,填写打包运行 URL 中的 `package_run_id`,并可填写 `package_run_attempt`。留空选择最新尝试及其成功的 package job;归档重跑继续使用原始构建 attempt,新的构建失败时不回退到较早成功构建。显式填写则选择对应构建,独立的 GitHub 归档失败不取消其资格。Windows 必须完成签名,macOS 必须完成公证和 stapling。GitHub job 证据确定原 runner,本机清单在审批前提供 preset、版本、源码和通道。不会下载安装包或请求 artifact。旧清单的 `publishRequested=false` 不影响发布资格;本机文件缺失或变化会停止发布。
+3 -1
View File
@@ -9,7 +9,9 @@ import { desktopBuildVersionPrefix, validateDesktopBuildVersion } from './deskto
* @returns {string} Validated build version.
*/
export function desktopCiVersion(environment, productVersion, now = new Date()) {
const mode = environment.PACKAGE_VERSION_MODE
const input = environment.PACKAGE_VERSION_MODE
// TODO: Remove legacy mode aliases on 2027-01-04 with the workflow source_ref mapping.
const mode = input === 'product' ? 'follow-dsh' : input === 'auto' ? 'build-number' : input
const selected = mode === 'default' ? (environment.DSH_PACKAGING_PRESET === 'production' ? 'follow-dsh' : 'build-number') : mode
if (selected !== undefined && !['follow-dsh', 'build-number', 'manual'].includes(selected)) throw new Error('Invalid version mode')
const requested = selected === 'follow-dsh' ? productVersion : selected === 'build-number' ? 'auto' : environment.PACKAGE_BUILD_VERSION?.trim()
@@ -13,9 +13,8 @@ it.each(['nightly', 'stable'] as const)('resolves every CI version mode independ
for (const preset of ['test', 'production']) {
expect(desktopCiVersion({ ...env, DSH_PACKAGING_PRESET: preset, PACKAGE_VERSION_MODE: 'build-number' }, version, now)).toBe(generated)
}
for (const oldMode of ['auto', 'product']) {
expect(() => desktopCiVersion({ ...env, PACKAGE_VERSION_MODE: oldMode }, version, now)).toThrow('Invalid version mode')
}
expect(desktopCiVersion({ ...env, PACKAGE_VERSION_MODE: 'product' }, version, now)).toBe(version)
expect(desktopCiVersion({ ...env, PACKAGE_VERSION_MODE: 'auto' }, version, now)).toBe(generated)
expect(desktopCiVersion({ ...env, PACKAGE_VERSION_MODE: 'manual', PACKAGE_BUILD_VERSION: generated }, version, now)).toBe(generated)
expect(desktopCiVersion({ ...env, PACKAGE_VERSION_MODE: 'default', DSH_PACKAGING_PRESET: 'production' }, version, now)).toBe(version)
expect(desktopCiVersion({ ...env, PACKAGE_VERSION_MODE: 'default', DSH_PACKAGING_PRESET: 'test' }, version, now)).toBe(generated)
+1
View File
@@ -33,6 +33,7 @@ describe.each(['arm64', 'x64'])('macOS %s packaging', (arch) => {
it('confines signed Mac packaging to manual dispatch and a dedicated Apple Silicon runner', () => {
expect(Object.keys(workflow.on)).toEqual(['workflow_dispatch'])
expect(workflow.jobs.package!.env.PACKAGE_VERSION_MODE).toBe("${{ inputs.version_mode == 'follow-dsh' && 'product' || inputs.version_mode == 'build-number' && 'auto' || inputs.version_mode }}")
expect(workflow.on.workflow_dispatch).toMatchObject({ inputs: { version_mode: { default: 'default', options: ['default', 'follow-dsh', 'build-number', 'manual'] } } })
expect(workflow.jobs.package).not.toHaveProperty('name')
expect(workflow.on.workflow_dispatch).toMatchObject({ inputs: { test_release_id: { type: 'string', default: '', required: false } } })
+1 -1
View File
@@ -80,7 +80,7 @@ it('routes manual packaging to the dedicated runner with explicit preset and sig
expect(workflow.on.workflow_dispatch!.inputs.version_mode!.default).toBe('default')
expect(workflow.on.workflow_dispatch!.inputs.source_ref!.default).toBe('master')
expect(workflow.on.workflow_dispatch!.inputs.update_channel!.default).toBe('nightly')
expect(job.env.PACKAGE_VERSION_MODE).toBe('${{ inputs.version_mode }}')
expect(job.env.PACKAGE_VERSION_MODE).toBe("${{ inputs.version_mode == 'follow-dsh' && 'product' || inputs.version_mode == 'build-number' && 'auto' || inputs.version_mode }}")
expect(job.env.PACKAGE_SOURCE_REF).toBe('${{ inputs.source_ref }}')
expect(job.env.DSH_DESKTOP_UPDATE_CHANNEL).toBe('${{ inputs.update_channel }}')
expect(job.env.DSH_PACKAGING_PRESET).toBe('${{ inputs.preset }}')