资讯动态

Easydict 发布实现聚合重构:将 Release 能力统一收敛到 release-easydict Skill

发布时间:2026/9/23 3:41:05 来源:尧图企业网站定制
Easydict 发布实现聚合重构将 Release 能力统一收敛到 release-easydict Skill【免费下载链接】Easydict一个简洁优雅的词典翻译 macOS App。开箱即用支持离线 OCR 识别支持有道词典 苹果系统词典 苹果系统翻译OpenAIGeminiDeepLGoogleBing腾讯百度阿里小牛彩云和火山翻译。A concise and elegant Dictionary and Translator macOS App for looking up words and translating text.项目地址: https://gitcode.com/gh_mirrors/ea/EasydictEasydict 曾在scripts/release/与.agents/skills/release-easydict/两处目录中分散维护发布实现通过硬编码路径和 Python 导入互相依赖。本篇以仓库内执行计划 2026-09-20-consolidate-release-skill.md 为骨架结合聚合后的实际目录与脚本源码完整讲解这次发布实现 Skill 化重构的目标、设计决策、动作路由、工作流编排、状态隔离与验证体系。读完你可以掌握 Easydict 当前发布能力的权威目录结构、release-easydictSkill 的动作语义以及asc workflow可恢复发布模型下的单入口用法。背景发布能力为何需要聚合在本次重构之前Easydict 的发布能力被拆散在两个位置scripts/release/一批发布 shell/Python 脚本、测试和说明.agents/skills/release-easydict/项目专属 Skill承载 Agent 的发布指令。两者之间存在三类耦合问题硬编码路径互相依赖两处代码通过写死的路径互相引用移动任一目录都会破坏另一方Python 导入跨目录Skill helper 依赖对旧发布目录的sys.path注入模块边界不清维护入口分散发布入口、工作流、测试和说明需要跨目录同步维护容易产生事实漂移。用户明确要求把发布实现全部聚合到项目专属 Skill并删除不再需要的 legacy 脚本与流程图。这一决定的直接结果是仓库不再保留scripts/release/发布相关的入口、工作流、脚本、静态配置与测试统一收敛到.agents/skills/release-easydict/。目标、范围与验收标准重构的目标结果定义得很干脆发布入口、工作流、脚本、静态配置和测试统一位于.agents/skills/release-easydict/仓库不再保留scripts/release/。允许修改的路径被严格圈定为以下范围避免迁移过程中越界改动无关模块路径角色.agents/skills/release-easydict/聚合后的权威 Skill 目录scripts/release/待删除的 legacy 发布目录.gitignore忽略运行状态临时目录changelog/README.mdchangelog 与发布关系说明docs/releases/easydict.md公开发布用户指南docs/design-docs/application-architecture.md应用架构说明本执行计划及同任务 history归档记录重构同时划定了明确的非目标不执行真实的 Archive、公证、Git push、GitHub Release 或 Issue 写入不改写历史计划和 history 中对旧路径的事实记录。这意味着本次迁移只动代码与文档的组织方式不改变任何远程发布行为。验收标准有四条全部指向迁移后的一致性现行代码和文档均使用 Skill 内路径发布测试和静态检查通过scripts/release/被删除运行状态写入仓库临时目录.tmp/而非 Skill 源码目录。同任务的执行历史记录在 docs/histories/2026-09/2026-09-20-consolidate-release-skill.md其中记载了本次变更的具体内容与验证结论可作为审计入口。聚合后的 Skill 目录结构从当前仓库实际内容看聚合完成后.agents/skills/release-easydict/呈现如下结构.agents/skills/release-easydict/ ├── SKILL.md # 动作路由、授权边界、默认值与完成条件 ├── assets/ │ └── export-options.plist # Developer ID 导出配置 ├── references/ │ ├── release-workflow.md # Release 生命周期执行契约 │ ├── issue-followup.md # 发布后 Issue 跟进流程 │ └── issue-followup-policy.md # Issue 关联与解决决策策略 ├── scripts/ │ ├── asc-workflow.json # asc 工作流图与检查点 │ ├── release-easydict.sh # 稳定命令行入口 │ ├── release-common.sh # 路径、发布配置与安全辅助函数 │ ├── release-preflight.sh # 环境、凭据与发布状态检查 │ ├── release-branch-sync.sh # worktree、临时分支与 Tag 同步 │ ├── release-publish-git.sh # Publish 合并预检与 lease 推送 │ ├── release-redraft.sh / release-redraft-git.sh # 同版本 Draft 安全替换 │ ├── release-build.sh # 版本更新、归档、导出与 build cache │ ├── release-package.sh # 公证、ZIP、DMG 与校验和 │ ├── release-appcast.sh / release-appcast.py # Sparkle 生成与严格校验 │ ├── release_notes.py # changelog 校验、快照、确定性渲染 │ ├── release-notes-sync.py # 已发布日志的预览/同步 │ ├── release_content.py # Draft 标题验证与更新不编辑正文 │ ├── release_issues.py / release_pr_policy.py # Issue 跟进与 PR 过滤 │ ├── release-github.sh # 幂等 Draft/正式发布与资产验证 │ ├── release-verify.sh # 本地产物与远程状态验证 │ └── requirements.txt # 固定 Markdown 渲染器依赖Markdown3.8.1 └── tests/ # 正文、appcast、Git 流程、Draft 替换、Issue 等测试SKILL.md 的 front matter 声明了它的职责边界name: release-easydict description: 编排 Easydict macOS 的 draft、publish、release 和 resume 整理英文 GitHub Release 内容并处理发布后的 Issue 跟进。这套结构把Agent 指令SKILL.md references、可执行实现scripts、静态资源assets、行为测试tests四类资产完整收拢到一个目录是本次聚合的最终形态。关键设计决策单权威目录、单入口不保留 wrapper 或符号链接迁移刻意不保留 wrapper 或符号链接避免形成双入口。设计意图在 history 中写得很明确发布实现只保留一个权威目录和一个入口迁移后的路径变化会同步更新所有现行引用。也就是说不存在旧的scripts/release/留一个壳指向新位置这种过渡方案删除就是彻底删除。路径解析基于脚本位置与仓库根而非 cwd发布脚本会在临时 worktree中继续运行因此路径定位必须基于脚本位置和明确的仓库根而不是依赖调用时的当前工作目录。以入口脚本 release-easydict.sh 为例开头就完成了自定位SCRIPT_DIR$(cd $(dirname ${BASH_SOURCE[0]}) pwd) ROOT_DIR$(cd $SCRIPT_DIR/../../../.. pwd) WORKFLOW_SOURCE_PATH$SCRIPT_DIR/asc-workflow.json WORKFLOW_RUNTIME_DIR$ROOT_DIR/.tmp/release/ascrelease-common.sh 同样以BASH_SOURCE推导RELEASE_SKILL_ROOT与RELEASE_SOURCE_ROOT并暴露一批可被环境变量覆盖的默认配置远程名origin、仓库tisfeng/Easydict、分支dev/main、Team ID45Z6V4YD5U、签名身份、Sparkle Keychain accounted25519等。这消除了 Skill helper 对旧发布目录的sys.path依赖让脚本在任意 cwd 下都能正确定位仓库根、workflow 与 plist。运行状态与源码目录隔离.tmp/release/asc/runs/asc工具固定把状态写到 workflow 文件旁的runs/目录。为避免污染 Skill 源码目录入口脚本会把 workflow 的运行时副本放到仓库临时目录WORKFLOW_RUNTIME_DIR$ROOT_DIR/.tmp/release/asc WORKFLOW_PATH$WORKFLOW_RUNTIME_DIR/asc-workflow.json WORKFLOW_RUNS_DIR$WORKFLOW_RUNTIME_DIR/runs因此asc的原始运行状态落在.tmp/release/asc/runs/而非 Skill 源码目录。.gitignore中已有.tmp/忽略规则运行状态属于仓库临时数据不进版本控制。文档分工Skill reference 与公开用户指南原scripts/release/README.md改为 Skill reference承载 Agent 执行细节公开用户指南继续由docs/releases/easydict.md维护面向发布维护者changelog/README.md说明 changelog 与 GitHub Release 正文、Sparkle appcast 的发布关系docs/design-docs/application-architecture.md同步更新架构描述。发布动作路由SKILL.md 定义的生命周期聚合后的 Skill 以 SKILL.md 为动作总纲Release 生命周期包含五个动作动作语义完成边界draft version创建或恢复经过验证的 Draft整理英文正文和重点标题后停止Draft、Tag、临时发布分支、changelog 和正文哈希全部验证后才算完成不发布也不处理 Issuedraft version --replace-draft从已同步并提交的本地dev安全重建最新且匹配的未发布 Draft废弃旧 Draft 并以新构建替换publish version整理已有且经过验证的 Draft发布并验证然后运行内部 Issue 跟进Release、appcast、Git 引用和 Issue 跟进全部最终核验后才算完成release version依次执行 Skill 的draft和publish不直接调用仓库脚本的一次性release动作resume version-or-run-id使用现有 skill 和 asc 状态只继续未完成的 Release 生命周期阶段不启动新的替换或发布已发布版本的日志修订走独立的sync-notes version动作默认只预览仅在显式--execute时同步已发布 GitHub Release 正文、远程main/dev的 appcast 以及本地分支。该动作不重建产物、不改 Tag/附件/版本号也不替代resume。发布后的 Issue 跟进有独立的三个动作issue-followup plan version生成本地计划不评论/关闭 Issue、issue-followup apply version执行通知与关闭、issue-followup resume version恢复中断的 Issue 动作。注意区分issue-followup resume恢复 Issue 跟进resume恢复 Release 生命周期。授权边界SKILL.md 对 Agent 的写权限做了精细约束普通规划、解释、检查保持只读issue-followup plan只查询 GitHub 并写入.tmp/release/version/state/issue-followup/下被忽略的本地状态不评论或关闭 Issue只有用户针对具体版本或运行明确请求draft、publish、release、Releaseresume、sync-notes --execute、issue-followup apply/resume时才执行远程修改用户明确请求publish或release后同一版本通过远程发布验证时同时授权其内部issue-followup apply阶段。默认值与完成条件默认使用betachannel除非用户明确要求stable所有底层命令沿用同一 channelpublish/release只有在 Release、appcast、Git 引用和 Issue 跟进都得到最终核验后才完成Issue 阶段失败时不回滚已发布的 Release 或已完成动作而是报告可恢复状态最终报告必须包含 Release URL、标题、channel、notes 路径、Issue 摘要、底层 run ID 和可恢复状态路径失败时说明准确阶段和已经发生的外部变更。Release 生命周期执行契约执行draft、publish、release或 Releaseresume时Agent 必须遵守 references/release-workflow.md 定义的契约。Git 与状态边界draft生成、验证并提交 appcast然后只推送指向 appcast 提交的release/sync-version临时分支和指向版本提交的版本 Tag不得把 Draft 提交直接推送到origin/dev或origin/mainpublish在 GitHub Release 公开前完成 merge 预检公开后用 Draft 阶段冻结的 appcast 提交安全更新本地dev再原子更新远程dev、main和临时发布分支远程验证通过后删除临时发布分支版本 Tag 停留在版本元数据提交main停留在 appcast 提交dev停留在包含最新开发提交和 appcast 提交的集成结果Publish 失败时使用 asc run ID 恢复不手工 rebase 或强推这些引用。Release 内容状态保存在.tmp/release/version/state/release-notes.json冻结版本、Markdown SHA-256、渲染器标识和 HTML SHA-256。Issue 状态只使用.tmp/release/version/state/issue-followup/的 schema v2直接存放在state/下的 schema-v1 文件保留为审计数据不自动复用、迁移或删除。工作流 8 步验证请求版本、channel、当前 GitHub Release、.tmp/release/version/状态和关联 asc run ID创建新 Draft 前根据上一个版本以来的已合并 PR 创建或更新changelog/version.md应用统一 bot PR 过滤策略提交到本地dev后运行验证 changelog运行创建 DraftDraft 已存在则验证并复用只有用户明确要求时才替换 DraftDraft 直接使用冻结的 changelog创建后重新获取正文做一致性验证根据真实 PR 选择重点并生成英文标题先预览再用--execute执行helper 不编辑正文draft报告经过验证的 Draft、changelog 路径和正文哈希后停止publish/release运行发布 Draft先做 merge 预检校验冻结 appcast 后安全更新本地dev用 lease 原子更新远程引用发布、appcast 安装和远程验证全部成功前不继续执行issue-followup apply version在修改前创建新计划不依赖此前独立运行的plan报告 Release URL、标题、channel、notes 路径、Issue 和无关联 PR 摘要、底层 run ID 和可恢复状态路径。内容决策changelog 只翻译每个变更条目中由人编写的 PR 标题部分保持英文标题简洁作者、PR 链接、贡献者和比较范围保持不变按以下顺序选择重点安全/数据丢失/崩溃修复 → 重要用户可见功能 → 重要用户可见修复 → 较小产品改进只有不存在产品变更时才选择维护项标题格式为version emoji type: concise English summary通常采用✨ feat、 fix、 security、 perf或 chore存在用户可见功能或修复时不选择文档、生成资源、依赖升级或内部重构作为重点。已发布日志的独立同步发布完成后人工修改了changelog/version.md时不要重新运行resume、draft或publish——这些动作分别用于恢复中断的 ASC 工作流、重建 Draft 和发布 Draft不会把发布后的日志修订当作新的构建发布。正确做法是先预览./.agents/skills/release-easydict/scripts/release-easydict.sh sync-notes version确认预览内容后才执行远程同步./.agents/skills/release-easydict/scripts/release-easydict.sh sync-notes version --execute可选参数包括--repo owner/repo、--notes-file path和--state path。该动作要求 Release 已公开且 Tag 与版本一致--execute要求当前 worktree 干净更新 Release 时使用 ETag更新分支时使用 branch head 和 Git push lease 做乐观并发校验。状态摘要保存在.tmp/release/version/state/notes-sync.json部分成功后再次执行会重新读取远程状态并跳过已经一致的目标。asc workflow 编排可恢复的检查点发布引擎的核心是 scripts/asc-workflow.json它把构建、公证、打包、GitHub 和 Sparkle 拆成可恢复的检查点。文件顶部声明了五个环境变量作为动作参数变量默认值含义VERSION空目标版本号x.y.zCHANNELbetaSparkle 渠道可选beta/stableBUILD_NUMBER空覆盖下一个构建号DRAFT_MODEnormal普通 Draft 或replace替换模式FORCE_CLEAN0是否强制 clean Archive顶层声明before_all/after_all/error钩子输出开始、完成与失败日志失败提示语明确要求用 asc 打印的 run ID 恢复。四个公开工作流组合两个私有步骤组prepare仅prepare_stepsdraftprepare_stepsdraft_stepspublish仅publish_stepsreleaseprepare_stepsdraft_stepspublish_steps。prepare_steps本地产物准备按顺序执行 14 个步骤preflight_environment→snapshot_draft_replacement→archive_replaced_local_state仅替换模式→sync_local_dev→prepare_release_worktree→preflight_release→update_version→archive_application→export_application→notarize_application→create_sparkle_zip→create_notarized_dmg→generate_appcast_candidate→verify_local_release。即先做环境与凭据检查、同步分支并准备隔离 worktree再更新版本号、用asc xcode archive归档、xcodebuild导出、提交 App 公证并 staple、生成 Sparkle ZIP 和 DMG、对 DMG 二次公证、生成候选 appcast最后完成本地验证。prepare阶段只写 Apple 公证请求不写 Git/GitHub。draft_steps创建 GitHub Draft8 个步骤revalidate_draft_replacement→prepare_channel_transition→install_appcast→push_draft_refs→delete_replaced_github_draft→create_github_draft→verify_github_draft→cleanup_draft_replacement。Draft 阶段冻结并提交候选 appcast原子推送临时发布分支和版本 Tag创建并验证 GitHub Draft但不会公开 Release、更新主分支也不评论或关闭 Issue。publish_steps公开与推广9 个步骤preflight_publish→prepare_publish_git→publish_github_release→verify_github_release→push_published_refs→promote_previous_github_release→verify_remote_release→cleanup_remote_release_branch→cleanup_release_worktree。公开 Release 前完成 merge 预检公开后用 lease 原子更新dev/main与临时分支对 beta 发布把上一 GitHub prerelease 提升为 stable远程验证两代 Release、引用、资产和公开 Sparkle feed 后再清理临时分支与 worktree。命令行入口底层脚本的统一入口是./.agents/skills/release-easydict/scripts/release-easydict.sh action version [options]常用参数与约束源码中均有校验逻辑--channel beta|stableSparkle 渠道默认beta分阶段执行时draft和publish必须一致--build-number value指定构建号必须是正整数且高于公开 appcast 的最新构建号--replace-draft仅用于明确替换当前最新 Draft不能与--build-number同用--force-clean仅prepare、draft、release支持强制 clean Archive--dry-run只预览asc workflow不执行步骤resume run-id只接受 run ID从 run 文件中解析版本并推断 workflow 名称不支持其他参数。入口脚本会把asc的机器可读 stdout JSON 保存为logs/workflow-run-id.json同时通过命名管道把人类可读的 stderr 输出到终端和logs/workflow-run-id.log并在终端打印格式化摘要工作流状态、失败步骤、错误、run ID、Draft/Publish 的 Git 引用、实际步骤耗时。状态、日志与恢复位置所有运行状态都隔离在.tmp/下已被.gitignore忽略主要位置路径内容.tmp/release/version/state/版本、正文、构建、Draft、Publish 和恢复状态.tmp/release/version/state/publish-git.envPublish 的 Git 集成状态.tmp/release/version/state/issue-followup/Issue 候选、决策、计划、汇总和动作状态.tmp/release/version/logs/workflow-run-id.jsonasc机器可读结果.tmp/release/version/logs/workflow-run-id.log完整工作流日志.tmp/release/asc/runs/asc原始运行状态.tmp/release/cache/worktree只用于本地 Archive 的长期构建 worktree失败时先保存终端给出的 run ID 和路径不要手工 rebase、强推或删除现场修复根因后执行./.agents/skills/release-easydict/scripts/release-easydict.sh resume run-id长期构建 worktree 使用带 fingerprint 的 Release DerivedData兼容缓存会被复用增量 Archive 失败时只清理当前 fingerprint 并自动回退一次 clean Archive缓存命中不降低签名、公证、stapling、appcast 或远程验证要求。验证与测试矩阵本次迁移的验证覆盖了结构、行为、语法、配置和静态检查多个层面全部通过检查命令结果Skill 结构quick_validate.py .agents/skills/release-easydict通过行为测试python3 -m unittest discover -s .agents/skills/release-easydict/tests -p test_*.py通过71 tests passed覆盖非仓库 cwd、运行时 workflow 路径和 dry-run 参数路由Shell 语法bash -n .agents/skills/release-easydict/scripts/*.sh通过Python 编译python3 -m py_compile ...通过工作流 JSONjq -e . .agents/skills/release-easydict/scripts/asc-workflow.json通过导出配置plutil -lint .agents/skills/release-easydict/assets/export-options.plist通过链接与旧路径相对 Markdown 链接与旧现行路径扫描通过差异检查git diff --check通过Review基于初始 HEAD91aa7a6f5be8cfc4dca86f9a1117418d76802a4f审查变更无 findings需要特别说明的验证边界执行环境没有安装asc因此未运行真实的asc workflow validate而是通过jq校验、workflow 行为测试和 fake-ASC 路由测试覆盖迁移契约按任务范围也未执行 Archive、公证或任何远程写入。作为后续事项在安装asc的发布机器上、下一次真实发布前应运行asc workflow validate --file .agents/skills/release-easydict/scripts/asc-workflow.json --pretty对发布维护者的影响聚合完成后Easydict 的发布维护入口与文档分工如下标准入口release-easydictSkill在支持 Skills 的 Agent 中调用日常 draft/publish/release/resume/sync-notes/issue-followup 全部由此进入公开指南docs/releases/easydict.md仍是发布维护者的唯一开发者指南覆盖本地环境、Apple 账号与签名凭据、Git/GitHub 配置、发布模型、主要命令、恢复和工具维护且不保存真实密钥changelog 约定changelog/README.md 明确了version.md文件名约定、UTF-8/LF 要求、正文与 GitHub Release 及 Sparkle appcast description 的发布关系以及冻结后漂移即失败的哈希校验机制架构说明docs/design-docs/application-architecture.md同步更新了发布模块的架构描述。修改发布 Skill、脚本或 helper 后至少运行单元测试、bash -n和git diff --check做回归验证xcodebuild、Archive、公证及远程 GitHub 写入必须按具体任务单独授权和验证——文档与单元测试通过不等于真实发布通过。完成条件回顾本次聚合以如下状态收尾Skill 结构和全部现行引用完成迁移legacy 资产与scripts/release/已删除风险匹配的测试、静态检查、dry-run 和 Review 通过history 已创建docs/histories/2026-09/2026-09-20-consolidate-release-skill.md计划已归档变更已创建本地提交。至此Easydict 的发布能力拥有了单一权威目录、单一入口和完全可恢复的asc workflow检查点模型发布自动化与 Agent 指令、静态配置、测试同处一处运行状态与源码彻底隔离后续任何发布路径的演进都只需要在一个目录内完成。【免费下载链接】Easydict一个简洁优雅的词典翻译 macOS App。开箱即用支持离线 OCR 识别支持有道词典 苹果系统词典 苹果系统翻译OpenAIGeminiDeepLGoogleBing腾讯百度阿里小牛彩云和火山翻译。A concise and elegant Dictionary and Translator macOS App for looking up words and translating text.项目地址: https://gitcode.com/gh_mirrors/ea/Easydict创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价