ci: Windows 产物默认就编(平台开关从 vars 换成 inputs)
构建客户端 / 检查(类型 + 单元测试) (push) Successful in 2m42s
构建客户端 / macOS 通用(.app + .dmg) (push) Skipped
构建客户端 / Windows x64(NSIS 安装包) (push) Failing after 27s
构建客户端 / Linux x64(deb + AppImage) (push) Successful in 9m14s

现象:Windows runner 明明在线、job 也确实派给了 windows-runner-01(它自己的日志:
"Runner labels: windows-latest, windows-2025, windows-2022"),但每次运行里
Windows 产物都是 skipped。

原因在 job 级 if 上:
    (github.event_name != 'workflow_dispatch' && vars.ENABLE_WINDOWS == 'true')
Gitea 的 runner 在 job 级 if 里拿不到(或拿不对)vars 上下文,条件恒为假 —— 而这个
条件写反的代价是"静悄悄不编",不看 runner 日志根本看不出来。同一份文件里
`github.event.inputs.linux != 'false'` 这个形式在 runner 日志里能看到正常求值
(evaluating expression '...' evaluated to 'true'),所以三个平台统一成这种形式:

  Linux / Windows : github.event.inputs.<平台> != 'false'   → 默认跑
  macOS           : github.event.inputs.macos == 'true'     → 默认不跑(还没有机器)

同时把 workflow_dispatch 里 windows 的默认值改成 true,并更新文件头:写清三台
runner 各自声明的标签、为什么不能拿 Linux 交叉编 Windows/macOS、以及第 4 条——
平台开关不要用仓库变量(附上这次的证据)。

runs-on 里的 vars.RUNNER_* 保持不变(标签不匹配时用它们覆盖)。
This commit is contained in:
2026-10-15 21:58:02 +08:00
parent 03f7279b53
commit 76b96cc374
+39 -37
View File
@@ -2,38 +2,36 @@
# #
# 产物都挂在这次运行下面(Actions 页面直接下载),保留 14 天: # 产物都挂在这次运行下面(Actions 页面直接下载),保留 14 天:
# Linux x64 deb + AppImage cam-desktop_<版本>_amd64.deb / .AppImage ← 默认每次编 # Linux x64 deb + AppImage cam-desktop_<版本>_amd64.deb / .AppImage ← 默认每次编
# Windows x64 NSIS 安装包 cam-desktop_<版本>_x64-setup.exe ← 有 runner 才编 # Windows x64 NSIS 安装包 cam-desktop_<版本>_x64-setup.exe ← 默认每次编
# macOS 通用 .app + .dmg arm64 与 x86_64 合成一个包 ← 有 runner 才编 # macOS 通用 .app + .dmg arm64 与 x86_64 合成一个包 ← 还没有机器,手动勾选才编
# #
# ── 触发 ───────────────────────────────────────────────────────────────────── # ── 触发 ─────────────────────────────────────────────────────────────────────
# * push 到 main/master —— 只认 desktop/、protocol/ 与本文件的改动,改固件不会 # * push 到 main/master —— 只认 desktop/、protocol/ 与本文件的改动,改固件不会
# 白占 runner # 白占 runner
# * 打 v* tag、开 PR # * 打 v* tag、开 PR
# * 手动 Run workflow:逐个平台勾选,不进 paths 过滤("就想编一次"走它) # * 手动 Run workflow:逐个平台勾选,不进 paths 过滤("就想编一次"走它)
# Windows 与 macOS 两个 job 目前默认不跑,原因与打开方式见下面第 1 条。 # 平台开关一律看勾选框(理由见下面第 4 条)。
# #
# ── 跑在 Gitea 上要先对上的两件事 ──────────────────────────────────────────── # ── 跑在 Gitea 上要先对上的两件事 ────────────────────────────────────────────
# 1. runner 标签是注册 runner 时自己起的名字,猜不到,所以三个 job 都写成 # 1. runner 标签是注册 runner 时自己起的名字,猜不到,所以三个 job 都写成
# "仓库变量优先、常见标签兜底": # "仓库变量优先、常见标签兜底":
# runs-on: ${{ vars.RUNNER_LINUX || 'ubuntu-latest' }} # runs-on: ${{ vars.RUNNER_LINUX || 'ubuntu-latest' }}
# 标签对不上时 job 是**排队**而不是报错 —— 排队会一直占着这次运行不结束, # 标签对不上时 job 是**排队**而不是报错 —— 排队会一直占着这次运行不结束,
# 所以第一次跑之前先看一眼 runner 页面上那几行标签。 # 所以上线新平台前先看一眼 runner 页面上那几行标签。
# #
# 本仓库目前只有 Linux 的两个 runner 标签(ubuntu-latest / ubuntu-24.04 / # 2026-10-15 实测在线的(括号里是它们自己声明的标签):
# ubuntu-22.04),所以**默认只跑 Linux**:Windows 与 macOS 两个 job 要等 # * simba-runner-01 (ubuntu-latest / ubuntu-24.04 / ubuntu-22.04)
# 仓库变量 ENABLE_WINDOWS / ENABLE_MACOS 设成 true 才会跑(手动 Run workflow # * windows-runner-01 (windows-latest / windows-2025 / windows-2022)
# 时另看勾选框),机器的标签则用 RUNNER_WINDOWS / RUNNER_MACOS 指过去。 # * macOS:还没有
# 等那两台机器上的 runner 注册好再打开,否则每次 push 都会多出两个永远排队的 # 所以 Windows 默认就跑;macOS 的 job 写成"手动勾选才跑"。
# job。
# #
# 为什么不能拿 Linux runner 交叉编出来: # 为什么不能拿 Linux runner 交叉编出来:
# * Windows:Rust 侧用 mingw 交叉编还能出个裸 exe,但 tauri 的 NSIS 打包器 # * Windows:Rust 侧用 mingw 交叉编还能出个裸 exe,但 tauri 的 NSIS 打包器
# 本身只能在 Windows 上跑,出不了安装包; # 本身只能在 Windows 上跑,出不了安装包;
# * macOS:要 Apple SDK 与 codesign/lipo,只能在 macOS 上编。 # * macOS:要 Apple SDK 与 codesign/lipo,只能在 macOS 上编。
# 所以这两个平台的 job 留着是为了"机器到位那天直接开",不是摆设。 # Windows runner 上要预装好 MSVC Build Tools(link.exe)、WebView2 运行时与
# 那两台机器上要预装好:Windows 的 MSVC Build Tools(link.exe)、macOS 的 # rustup(dtolnay/rust-toolchain 靠它装工具链);macOS 上要 Xcode Command Line
# Xcode Command Line Tools,以及 rustup(dtolnay/rust-toolchain 靠它装工具链)。 # Tools + rustup。Linux 的 job 通常跑在容器里,没装 rustup 也没关系 —— 见兜底那步。
# Linux 的 job 通常跑在容器里,所以没装 rustup 也没关系 —— 见下面那步兜底。
# 2. 这个文件放在 .github/workflows/ 下就够:Gitea 的 [actions] WORKFLOW_DIRS # 2. 这个文件放在 .github/workflows/ 下就够:Gitea 的 [actions] WORKFLOW_DIRS
# 默认值就是 [".gitea/workflows", ".github/workflows"](源码里的默认值,且 # 默认值就是 [".gitea/workflows", ".github/workflows"](源码里的默认值,且
# .yml 与 .yaml 都认),所以两个目录都是原生支持的,不用挪。 # .yml 与 .yaml 都认),所以两个目录都是原生支持的,不用挪。
@@ -58,6 +56,19 @@
# ~/.cargo/git/db # ~/.cargo/git/db
# key: ${{ runner.os }}-cargo-registry-${{ hashFiles('protocol/Cargo.lock', 'desktop/core/Cargo.lock', 'desktop/src-tauri/Cargo.lock') }} # key: ${{ runner.os }}-cargo-registry-${{ hashFiles('protocol/Cargo.lock', 'desktop/core/Cargo.lock', 'desktop/src-tauri/Cargo.lock') }}
# restore-keys: ${{ runner.os }}-cargo-registry- # restore-keys: ${{ runner.os }}-cargo-registry-
# 4. 平台开关只用 github.event.inputs,**不用仓库变量**。2026-10-15 那次 Windows
# runner 明明在线、job 也确实派给了它(它自己的日志里写着
# "Runner labels: windows-latest, windows-2025, windows-2022"),产物却一直是
# skipped —— 卡在 job 级 if 的 `vars.ENABLE_WINDOWS == 'true'` 上:Gitea 的
# runner 在 job 级 if 里拿不到(或拿不对)vars 上下文,而这个条件写反的代价是
# "静悄悄不编",最难发现。同一份文件里 `github.event.inputs.linux != 'false'`
# 这个形式在 runner 日志里能看到正常求值(evaluating expression '...' evaluated
# to 'true'),所以平台开关统一成这种:
# * Linux / Windows:`github.event.inputs.<平台> != 'false'` → 默认跑,
# 手动触发时取消勾选就不跑
# * macOS:`github.event.inputs.macos == 'true'` → 默认不跑,等有机器了改成
# 上一种形式即可
# runs-on 里的 vars(RUNNER_*)不受影响,标签不匹配时用那个覆盖。
# #
# ── 三个平台都显式写 --target,这不是啰嗦 ──────────────────────────────────── # ── 三个平台都显式写 --target,这不是啰嗦 ────────────────────────────────────
# desktop/.cargo/config.toml 里钉着 `target = "aarch64-apple-darwin"`(本机开发用; # desktop/.cargo/config.toml 里钉着 `target = "aarch64-apple-darwin"`(本机开发用;
@@ -101,18 +112,18 @@ on:
- ".github/workflows/build-client.yml" - ".github/workflows/build-client.yml"
workflow_dispatch: workflow_dispatch:
inputs: inputs:
# Linux 的 runner 有,默认勾上;另两个平台目前没有 runner,默认不勾 —— # Linux 与 Windows 的 runner 都在线,默认勾上;macOS 还没有机器,默认不勾
# 勾了而没有对应 runner,那个 job 会一直排队。 # (勾了会一直排队)。开关为什么不用仓库变量见文件头第 4 条。
linux: linux:
description: "构建 Linux(deb + AppImage)" description: "构建 Linux(deb + AppImage)"
type: boolean type: boolean
default: true default: true
windows: windows:
description: "构建 Windows(NSIS 安装包)——需要 Windows runner" description: "构建 Windows(NSIS 安装包)"
type: boolean type: boolean
default: false default: true
macos: macos:
description: "构建 macOS(通用 dmg)——需要 macOS runner" description: "构建 macOS(通用 dmg)——还没有 macOS runner,勾了会排队"
type: boolean type: boolean
default: false default: false
@@ -312,16 +323,11 @@ jobs:
windows: windows:
name: Windows x64(NSIS 安装包) name: Windows x64(NSIS 安装包)
needs: checks needs: checks
# 默认不跑:本仓库目前没有 Windows runner,跑了只会一直排队。有了机器之后 # 默认就跑:windows-runner-01 在线(自报标签 windows-latest)。
# 在仓库变量里加 ENABLE_WINDOWS=true 就会跟着每次 push 自动跑;手动触发时 # 开关用 inputs 而不是仓库变量的原因见文件头第 4 条 —— 这个坑正是它踩出来的。
# 勾 "构建 Windows" 也能单独跑一次。标签用 RUNNER_WINDOWS 指。 if: ${{ github.event.inputs.windows != 'false' }}
if: >- # 这台机器上要预装:MSVC Build Tools(tauri 的 Rust 侧要 link.exe)、WebView2
${{ # 运行时(装了包的应用要它才能起窗口;打包本身不需要)与 rustup。
(github.event_name == 'workflow_dispatch' && github.event.inputs.windows == 'true')
|| (github.event_name != 'workflow_dispatch' && vars.ENABLE_WINDOWS == 'true')
}}
# 自建 Windows runner 上要有 MSVC Build Tools(tauri 的 Rust 侧要 link.exe)、
# WebView2 运行时(装了包的应用要它才能起窗口;打包本身不需要)与 rustup。
runs-on: ${{ vars.RUNNER_WINDOWS || 'windows-latest' }} runs-on: ${{ vars.RUNNER_WINDOWS || 'windows-latest' }}
timeout-minutes: 120 timeout-minutes: 120
env: env:
@@ -370,14 +376,10 @@ jobs:
macos: macos:
name: macOS 通用(.app + .dmg) name: macOS 通用(.app + .dmg)
needs: checks needs: checks
# 同 Windows:默认不跑,有机器之后设仓库变量 ENABLE_MACOS=true,标签用 # 还没有 macOS runner,所以只有"手动触发 + 勾上"才跑;等机器注册好,把这一行
# RUNNER_MACOS 指。 # 换成 `github.event.inputs.macos != 'false'` 就变成默认跑(同 Windows)。
if: >- if: ${{ github.event.inputs.macos == 'true' }}
${{ # 那台机器上要有 Xcode Command Line Tools(链接要它)与 rustup。
(github.event_name == 'workflow_dispatch' && github.event.inputs.macos == 'true')
|| (github.event_name != 'workflow_dispatch' && vars.ENABLE_MACOS == 'true')
}}
# 自建 macOS runner 上要有 Xcode Command Line Tools(链接要它)与 rustup。
runs-on: ${{ vars.RUNNER_MACOS || 'macos-latest' }} runs-on: ${{ vars.RUNNER_MACOS || 'macos-latest' }}
timeout-minutes: 150 timeout-minutes: 150
env: env: