chore: 保存工作副本——客户端授权新契约(双端点/验签/令牌/周检)与桌面会话可靠性改进
This commit is contained in:
1 parent
f71eef0eba
commit
ae6093c9b3
163 files changed
+4911
-2494
No files matched your search
+85
-37
@@ -1,5 +1,34 @@
|
||||
# 发布指南
|
||||
|
||||
<a id="macos-next-steps"></a>
|
||||
|
||||
## 当前你要做的操作(v2.1.1 macOS)
|
||||
|
||||
本机已打出 **Tauri 窗口布局** 的 Developer ID 签名 DMG(不是手搓 `hdiutil`,Finder 里是大图标 + 拖到 Applications):
|
||||
|
||||
```text
|
||||
release/v2.1.1/macos-arm64/OpsXShell_2.1.1_aarch64.dmg
|
||||
```
|
||||
|
||||
这份包**还没公证、没 staple**。别人下载后仍可能被 Gatekeeper 拦。你这边只差公证:
|
||||
|
||||
1. Finder 里弹出 `/Volumes/OpsXShell`(挂载中无法 staple)。
|
||||
2. 开 Clash:`proxy-on`(公证走 HTTPS;时间戳构建阶段已经用 HTTP 回退签过了)。
|
||||
3. 不要把 App 专用密码发到聊天。终端执行其一:
|
||||
|
||||
```bash
|
||||
APPLE_ID='1024way@gmail.com' ./scripts/macos-notarize.sh
|
||||
# 或
|
||||
bash ~/Documents/apple签名/公证OpsXShell.sh
|
||||
```
|
||||
|
||||
4. 弹出框里填 **App 专用密码**(appleid.apple.com → 登录与安全 → App 专用密码,标签如 `app notary`)。
|
||||
5. 脚本会 `notarytool submit --wait --timeout 15m`。第一次可能很久;`--wait` 卡住时等它超时,再跑同一条命令——**已 Accepted 的不会重新上传,只会 staple**。不要对同一份未变化的 DMG 连续第三次 `submit`。
|
||||
6. 成功标志:`xcrun stapler validate` 通过,且 `codesign -dv` 能看到钉票。把 **这一份** DMG 发出去(尽量不要走微信,隔离属性会更烦)。
|
||||
7. 改代码后再 `./scripts/build.sh mac-arm64 --quick` 会得到新哈希,必须重新公证。
|
||||
|
||||
Windows Authenticode、自动更新仍未做,不要对外写「已公证」直到第 6 步完成。
|
||||
|
||||
## 构建命令
|
||||
|
||||
```bash
|
||||
@@ -9,6 +38,10 @@
|
||||
# macOS Apple Silicon 指定版本
|
||||
./scripts/build.sh v2.1.1 mac-arm64
|
||||
|
||||
# 构建完成后公证并钉票(新 DMG 必须再跑;已 staple 会直接退出)
|
||||
proxy-on # 本机 Clash;codesign 时间戳另见下文 HTTP 回退
|
||||
APPLE_ID='你的开发者邮箱' ./scripts/macos-notarize.sh
|
||||
|
||||
# Windows x86_64(推荐在 Windows CMD/PowerShell 中执行)
|
||||
scripts\build.bat v2.1.1 win-x64
|
||||
|
||||
@@ -87,64 +120,79 @@ lsof +D /Volumes/<临时卷名>
|
||||
|
||||
先正常退出该 OpsXShell 进程,再卸载对应的临时卷并重新构建。不要在应用仍从卷内运行时直接删除 `rw.*.dmg`。
|
||||
|
||||
## 签名、公证和自动更新(未完成)
|
||||
<a id="签名公证和自动更新未完成"></a>
|
||||
|
||||
**当前状态:没有签名凭据,公开包是 ad-hoc / 未签名,未公证,没有自动更新。**
|
||||
没有 `APPLE_*` / Authenticode 证书、minisign 私钥和 HTTPS 更新源之前,不得在 README、界面、Release 说明或 CI 绿勾上写「已签名」「已公证」「支持自动更新」。`tauri.conf.json` 的 `signingIdentity` 现在是 `"-"`;`plugins` 只有 deep-link,没有 updater。
|
||||
## 签名、公证和自动更新
|
||||
|
||||
现有门禁只做「有凭据才验、没凭据就标明开发包」:
|
||||
申请账号和 Developer ID、导入钥匙串的完整步骤见 [download/Apple开发者签名.md](../download/Apple开发者签名.md)。
|
||||
|
||||
**当前状态(本机可签 macOS;这份 DMG 待公证;自动更新仍未做):**
|
||||
|
||||
- 仓库 `tauri.conf.json` 的 `signingIdentity` 仍是 `"-"`,没证书的环境还能打 ad-hoc 开发包。
|
||||
- 本机若已导入 **Developer ID Application**,把身份写进 **gitignore** 的 `src-tauri/tauri.signing.conf.json`。`./scripts/build.sh` 发现该文件就会按 Developer ID 签名。
|
||||
- DMG 必须走 Tauri bundler(`bundle.macOS.dmg`:窗口 720×440,应用图标与 Applications 分列)。不要用手搓 `hdiutil create`,Finder 图标会变小。
|
||||
- `timestamp.apple.com:443` 不通时,构建会用 `scripts/macos-codesign-wrapper.sh` 走 HTTP 时间戳。可设 `CODESIGN_USE_SYSTEM_TIMESTAMP=1` 关闭。
|
||||
- **每次新打的 DMG 都必须再公证并 staple**:`APPLE_ID='…' ./scripts/macos-notarize.sh`。已钉票会直接退出。`--wait` 卡住时脚本会超时后尝试 staple。
|
||||
- 证书、CSR、私钥放本机文稿 `~/Documents/apple签名/`,不要进 git。Team 内其他 Mac 桌面应用可复用同一张 Developer ID。
|
||||
- Windows Authenticode、minisign 自动更新仍未接线。没有凭据、或尚未 staple 时,不得在 README / 界面 / CI 上写「已签名」「已公证」「支持自动更新」。
|
||||
|
||||
门禁:
|
||||
|
||||
- `REQUIRE_SIGNING=true` 时,`scripts/release-preflight.mjs` 检查环境变量齐全,`scripts/verify-release.mjs` 拒绝 macOS ad-hoc、要求 Windows Authenticode `Valid`。
|
||||
- 未设该变量时,`./scripts/build.sh` 仍可打开发包,验证只检查架构和体积。
|
||||
- CI 工作流 `.github/workflows/tauri-release.yml` 已能在 Secrets 齐全时写入 `src-tauri/tauri.signing.conf.json` 再构建;**本地 `build.sh` 还不会生成这份配置**,所以本机即使导出了同样的环境变量,也不会走出 ad-hoc。
|
||||
- 全仓库没有 `notarytool` / `staple`。Developer ID 签过但未公证的 `.app`,用户机器上仍会被 Gatekeeper 拦。
|
||||
- `scripts/release.py` 仍提示「右键打开」——这是 ad-hoc 包的权宜说明,正式公证后必须删掉。
|
||||
- 未设该变量时,`./scripts/build.sh` 仍可打开发包;若存在 `tauri.signing.conf.json` 则会签 Developer ID。
|
||||
- CI `.github/workflows/tauri-release.yml` 在 Secrets 齐全时写入 `tauri.signing.conf.json`。本机用同一文件名即可,不要提交。
|
||||
|
||||
下面是有凭据之后的做法。没齐之前不要改 `signingIdentity`、不要接 updater 插件、不要在设置里放「检查更新」。
|
||||
### 1. 凭据
|
||||
|
||||
### 1. 凭据(先买/申请,再接线)
|
||||
| 平台 | 要什么 | 放到哪里 |
|
||||
| -------- | --------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| macOS | Apple Developer Program;**Developer ID Application**(不是 Development);App 专用密码 | 本机钥匙串 + gitignore 的 `tauri.signing.conf.json`;CI Secrets:`APPLE_CERTIFICATE`(p12 的 base64)、`APPLE_CERTIFICATE_PASSWORD`、`APPLE_SIGNING_IDENTITY`、`APPLE_ID`、`APPLE_PASSWORD`、`APPLE_TEAM_ID` |
|
||||
| Windows | 代码签名证书(OV/EV PFX) | `WINDOWS_CERTIFICATE_BASE64`、`WINDOWS_CERTIFICATE_PASSWORD` |
|
||||
| 自动更新 | 单独的 **minisign** 密钥对,与 Apple/Authenticode 不是同一把 | 私钥只进 CI Secrets;**公钥**写进仓库的 updater 配置 |
|
||||
|
||||
| 平台 | 要什么 | 放到哪里 |
|
||||
| -------- | ---------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| macOS | Apple Developer Program;**Developer ID Application** 证书(`.p12`);App 专用密码 | 本机环境变量 + GitHub/Gitee Secrets:`APPLE_CERTIFICATE`(p12 的 base64)、`APPLE_CERTIFICATE_PASSWORD`、`APPLE_SIGNING_IDENTITY`(如 `Developer ID Application: …`)、`APPLE_ID`、`APPLE_PASSWORD`、`APPLE_TEAM_ID` |
|
||||
| Windows | 代码签名证书(OV/EV PFX) | `WINDOWS_CERTIFICATE_BASE64`、`WINDOWS_CERTIFICATE_PASSWORD` |
|
||||
| 自动更新 | 单独的 **minisign** 密钥对,与 Apple/Authenticode 不是同一把 | 私钥只进 CI Secrets;**公钥**写进仓库的 updater 配置 |
|
||||
`src-tauri/tauri.signing.conf.json` 必须进 `.gitignore`,不得提交。macOS 示例:
|
||||
|
||||
Linux 安装包(deb/rpm/AppImage)不走 Apple/Authenticode。自动更新的 `.sig` 是另一套签名,三平台都要。
|
||||
|
||||
`src-tauri/tauri.signing.conf.json` 由脚本现场生成,必须进 `.gitignore`,不得提交。
|
||||
```json
|
||||
{
|
||||
"bundle": {
|
||||
"macOS": {
|
||||
"signingIdentity": "Developer ID Application: Logan Li (B8DVUUUF6W)"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 本地与 CI 同源签名
|
||||
|
||||
目标:本机 `REQUIRE_SIGNING=true ./scripts/build.sh` 与 CI 走同一条路径,都能复现同一类签名产物。
|
||||
|
||||
1. `build.sh` / `build.bat` 在签名变量齐全时,生成 `tauri.signing.conf.json`(macOS 写 `bundle.macOS.signingIdentity`;Windows 写 thumbprint / sha256 / timestamp),再 `npx tauri build --config src-tauri/tauri.signing.conf.json`。
|
||||
2. 不要改仓库里的 `tauri.conf.json` 默认 `"-"`——没凭据的开发机构必须还能打 ad-hoc。
|
||||
3. `REQUIRE_SIGNING=true` 时 `verify-release.mjs` 必须失败于 ad-hoc / 无效 Authenticode;不要为了绿而关校验。
|
||||
4. 正式标签才设 `REQUIRE_SIGNING=true`。日常 PR 构建保持未签名。
|
||||
1. 不要改仓库里的 `tauri.conf.json` 默认 `"-"`。
|
||||
2. `REQUIRE_SIGNING=true` 时 `verify-release.mjs` 必须失败于 ad-hoc。
|
||||
3. 正式标签才设 `REQUIRE_SIGNING=true`。日常 PR 保持未签名。
|
||||
|
||||
### 3. macOS 公证(notarytool + staple)
|
||||
|
||||
签名成功 ≠ 用户能打开。必须公证并钉票:
|
||||
签名成功 ≠ 用户能打开。必须公证并钉票。不要对同一份未变化的 DMG 连续多次 `submit`。
|
||||
|
||||
```bash
|
||||
# 构建并 Developer ID 签名之后
|
||||
xcrun notarytool submit "$DMG" \
|
||||
--apple-id "$APPLE_ID" --password "$APPLE_PASSWORD" --team-id "$APPLE_TEAM_ID" \
|
||||
--wait
|
||||
xcrun stapler staple "$DMG"
|
||||
# 若 staple 的是 .app,再重新打 DMG,或对 DMG 再 staple
|
||||
spctl --assess --type install --verbose "$DMG"
|
||||
# 先弹出已挂载的安装盘,再:
|
||||
APPLE_ID='开发者邮箱' ./scripts/macos-notarize.sh
|
||||
# 可选:指定 DMG 路径
|
||||
APPLE_ID='开发者邮箱' ./scripts/macos-notarize.sh release/v2.1.1/macos-arm64/OpsXShell_2.1.1_aarch64.dmg
|
||||
```
|
||||
|
||||
验收(必须在**另一台未关 SIP、未关 Gatekeeper 的 Mac**上,不要只在构建机看 `spctl`):
|
||||
脚本会:已 staple 则退出;否则先 staple;没有票据才要 App 专用密码并 `notarytool submit --wait --timeout 15m`,超时仍 staple。开发者后台网页没有这份 DMG 的进度页,用终端或:
|
||||
|
||||
1. 下载 DMG,双击打开,拖到「应用程序」,**不要**右键「打开」、不要 `xattr -d`。
|
||||
```bash
|
||||
xcrun notarytool info <submission-id> --apple-id "$APPLE_ID" --team-id "$APPLE_TEAM_ID"
|
||||
xcrun notarytool log <submission-id> --apple-id "$APPLE_ID" --team-id "$APPLE_TEAM_ID"
|
||||
```
|
||||
|
||||
验收(必须在**另一台未关 SIP、未关 Gatekeeper 的 Mac**上):
|
||||
|
||||
1. 下载 **staple 之后** 的 DMG,双击打开,拖到「应用程序」,不要右键「打开」、不要 `xattr -d`。
|
||||
2. 能启动、能连 SSH,菜单里没有 DevTools。
|
||||
3. `codesign --verify --deep --strict` 且 `codesign -dv` 不是 `Signature=adhoc`。
|
||||
4. 删掉 Release 说明和 `release.py` 里的「右键绕过 Gatekeeper」。
|
||||
3. `codesign --verify --deep --strict` 且 `codesign -dv` 含 `Notarization Ticket=stapled`,不是 `Signature=adhoc`。
|
||||
|
||||
没做完 staple 之前,文档继续写「未公证」。
|
||||
没做完 staple 之前,对外说明不要写「已公证」。
|
||||
|
||||
### 4. Windows Authenticode
|
||||
|
||||
|
||||
Reference in new issue
Block a user