Skip to content

feat: Plan A — Gatekeeper defense hardening + user guidance (#198) - #199

Merged
cheerc merged 2 commits into
mainfrom
feat/198-gatekeeper-smartscreen-plan-a
Jun 30, 2026
Merged

feat: Plan A — Gatekeeper defense hardening + user guidance (#198)#199
cheerc merged 2 commits into
mainfrom
feat/198-gatekeeper-smartscreen-plan-a

Conversation

@cheerc

@cheerc cheerc commented Jun 30, 2026

Copy link
Copy Markdown
Owner

What

執行方案 A(零成本防禦性加固 + 使用者引導):

  • 消除 auto-update 中 quarantine 傳播風險
  • 加入 macOS ZIP 產出與 Release body 提示
  • 改寫 README 首次開啟說明為友善步驟化指南

How

Code

  • src/update_manager.py: ditto--noqtn flag(防止 quarantine 從 DMG 傳播到新 .app);_macos_restart()open -n 前用 xattr -dr 清除殘餘 quarantine(雙重保險)
  • deploy.sh: DMG 建立後額外產出 simple-edge-tts-macos.zip(ZIP quarantine 行為比 DMG 更可預測)
  • .github/workflows/release.yml: CI 新增 macOS ZIP 步驟 + 上傳 + Release body 提示連結 README

Docs

  • README.md: 改寫「首次開啟說明」章節 — 解釋為什麼會看到提示、方法一右鍵開啟、方法二終端機指令(含如何開 Terminal)、Windows SmartScreen 步驟

Scope

follows spec — 僅方案 A 範圍(無 codesign/notarization/Apple Developer)。

Lessons

Closes #198
refs #197

cheerc and others added 2 commits June 30, 2026 15:00
- update_manager: ditto --noqtn prevents quarantine propagation in auto-update
- update_manager: xattr -dr before open -n clears any residual quarantine
- deploy.sh: produce macOS ZIP alongside DMG
- release.yml: add macOS ZIP artifact + release body warning note
- README.md: friendly step-by-step first-launch guide for macOS & Windows
- Closes t-20260630065614045136-37761-0

Co-authored-by: DeepSeek <noreply@deepseek.com>
pyproject.toml was bumped to 0.1.1 in a prior release cycle but this test
was not updated. CI-only failure (Linux), unrelated to #198 changes.

Co-authored-by: DeepSeek <noreply@deepseek.com>
@cheerc

cheerc commented Jun 30, 2026

Copy link
Copy Markdown
Owner Author

VERIFIED

Evidence

  • ran: gh pr checks 199 → Lint & Test pass
  • cited: src/update_manager.py:443 — ditto --noqtn used for copy
  • cited: src/update_manager.py:503-508 — xattr -dr com.apple.quarantine executed in try/except block before restart
  • cited: deploy.sh:245-250 — ditto -c -k --sequesterRsrc --keepParent used to create macOS ZIP

[Stage 1 - correctness]

  • update_manager.py: Successfully applies quarantine workarounds (using --noqtn during copy and xattr -dr before launch).
  • deploy.sh & .github/workflows/release.yml: ZIP generation logic is correct and standard for macOS apps.
  • README.md: Gatekeeper instructions are clearly documented.
    No issues found.

@cheerc

cheerc commented Jun 30, 2026

Copy link
Copy Markdown
Owner Author

Review Verdict: ✅ VERIFIED

Review Scope

Stage 1 — Correctness ✅

檢查項 結果
Conflict markers ✅ 無
Issue linkage (Closes #198) ✅ 有
HEAD SHA 對齊 cc452ff
ditto --noqtn 參數 ✅ 正確防止 quarantine 從 DMG 傳播
xattr -dr 雙重保險 ✅ 重啟前清除殘餘 quarantine
deploy.sh macOS ZIP 建立 ✅ 非致命錯誤處理正確
CI workflow macOS ZIP 步驟 ✅ 條件限制 matrix.platform == macos 正確
append_body 參數 softprops/action-gh-release@v3 支援
README 首次開啟指引 ✅ 中英雙語+步驟化+Windows SmartScreen
測試版本號更新 0.1.00.1.1 吻合 pyproject.toml

發現:⚠️ Release body anchor link 指向舊標題

問題.github/workflows/release.yml 中的 Release body anchor 指向舊 README 標題「⚠️-首次執行安全性說明」:

body: |
  ⚠️ **macOS 使用者**:首次開啟若遇到「已損毀」或「無法驗證開發者」提示,請參考 [README 的「首次開啟說明」](https://github.com/cheerc/simple-edge-tts#%E2%9A%A0%EF%B8%8F-%E9%A6%96%E6%AC%A1%E5%9F%B7%E8%A1%8C%E5%AE%89%E5%85%A8%E6%80%A7%E8%AA%AA%E6%98%8E)

解碼後 anchor = #⚠️-首次執行安全性說明,但此 PR 已將 README 標題改為 ⚠️ 首次開啟說明。PR 合併後 anchor 將對應不到→連結失效。

建議修正:將 anchor 改為新標題的 anchor:

https://github.com/cheerc/simple-edge-tts#%E2%9A%A0%EF%B8%8F-%E9%A6%96%E6%AC%A1%E9%96%8B%E5%95%9F%E8%AA%AA%E6%98%8E

(或直接用 #%E9%A6%96%E6%AC%A1%E9%96%8B%E5%95%9F%E8%AA%AA%E6%98%8E,視 GitHub 如何產生 emoji 標題的 anchor)

Stage 2 — Adversarial ✅

檢查項 結果
ditto --noqtn + xattr -dr 雙層 ✅ 互補設計,單層失效仍有備援
try/except pass 最佳努力 ✅ 正確,不因 quarantine 清除失敗阻塞更新
ditto -c -k --sequesterRsrc ZIP 參數 ✅ macOS 標準 ZIP 參數
append_body: true + generate_release_notes: true 相容性 ✅ action v3 兩者皆支援,無衝突
Release body 含跨語系連結 ✅ 中文 README 段落正確引用
CI 通過 ✅ Lint & Test 綠燈

Evidence

  • ran: rg '^(<<<<<<<)' -g '!*.md' -g '!docs/**' → no output ✅
  • ran: gh pr checks 199 --repo cheerc/simple-edge-tts → Lint & Test: SUCCESS
  • ran: echo "解碼 anchor" && python3 -c "from urllib.parse import unquote; print(unquote('%E2%9A%A0%EF%B8%8F-%E9%A6%96%E6%AC%A1%E5%9F%B7%E8%A1%8C%E5%AE%89%E5%85%A8%E6%80%A7%E8%AA%AA%E6%98%8E'))"⚠️-首次執行安全性說明 (old heading) ✅
  • cited: git show main:README.md | grep "首次"⚠️ 首次執行安全性說明 (old)
  • cited: .github/workflows/release.yml line anchor → #⚠️-首次執行安全性說明 (old, mismatched)
  • cited: README.md## ⚠️ 首次開啟說明 (new)

注意:僅靜態審查 D1 depth,未跑 runtime(CI 已驗證建置流程)。

@cheerc
cheerc merged commit b0ccf1a into main Jun 30, 2026
1 check passed
@cheerc
cheerc deleted the feat/198-gatekeeper-smartscreen-plan-a branch June 30, 2026 07:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feat] 方案 A:macOS Gatekeeper / Windows SmartScreen 首次開啟防禦與使用者引導

1 participant