feat: 添加 skill 发布功能和混淆构建优化
- build.py: 移除 --obfuscate 参数,默认混淆模式;从 git config 读取 author,动态注入 SKILL.md - publish.py: 新增发布脚本,自动 clone 目标仓库、同步 build/ 内容、git commit+push - publish.sh: 新增一键构建+发布脚本 - skill-publishing spec: 新增发布规范 - skill-packaging spec: 更新构建规范
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
系统 SHALL 提供 build.py 脚本,运行后完成 skill 的完整打包流程。
|
||||
|
||||
#### Scenario: 运行 build.py 成功
|
||||
- **WHEN** 用户执行 `uv run python build.py`
|
||||
- **WHEN** 用户执行 `uv run --with pyarmor python build.py`
|
||||
- **THEN** 脚本完成所有打包步骤并输出成功信息
|
||||
|
||||
### Requirement: 构建目录清理重建
|
||||
@@ -18,26 +18,31 @@
|
||||
- **WHEN** 构建开始
|
||||
- **THEN** 脚本删除整个 build 目录(如有),然后创建新的空 build 目录
|
||||
|
||||
### Requirement: SKILL.md 复制
|
||||
系统 SHALL 将 skill/SKILL.md 直接复制到 build/SKILL.md,不保留 skill 这一级目录。
|
||||
### Requirement: SKILL.md 动态生成
|
||||
系统 SHALL 读取 SKILL.md 模板,动态注入 version 和 author 字段后写入 build/SKILL.md。
|
||||
|
||||
#### Scenario: SKILL.md 成功复制
|
||||
#### Scenario: SKILL.md 包含动态元数据
|
||||
- **WHEN** 构建执行
|
||||
- **THEN** build/SKILL.md 文件存在且内容与 skill/SKILL.md 一致
|
||||
- **THEN** build/SKILL.md 的 metadata 包含 version 和 author 字段
|
||||
|
||||
### Requirement: scripts 目录复制
|
||||
系统 SHALL 将 scripts/ 目录完整复制到 build/scripts/,保持目录结构。
|
||||
#### Scenario: version 是时间戳
|
||||
- **WHEN** 构建在 2026年3月11日 14点30分22秒执行
|
||||
- **THEN** build/SKILL.md 中 `metadata.version` 值为 "20260311_143022"
|
||||
|
||||
#### Scenario: scripts 目录结构保留
|
||||
- **WHEN** 构建执行
|
||||
- **THEN** build/scripts/ 下的子目录结构与原 scripts/ 一致
|
||||
#### Scenario: author 来自 git 配置
|
||||
- **WHEN** git config user.name 是 "Your Name",git config user.email 是 "your@email.com"
|
||||
- **THEN** build/SKILL.md 中 `metadata.author` 值为 "Your Name <your@email.com>"
|
||||
|
||||
### Requirement: 仅复制 Python 文件
|
||||
系统 SHALL 只复制 .py 扩展名的文件,其他文件类型自然被过滤。
|
||||
### Requirement: git 配置读取
|
||||
系统 SHALL 从 git config 读取 user.name 和 user.email。
|
||||
|
||||
#### Scenario: 只保留 py 文件
|
||||
- **WHEN** 原目录包含多种文件类型
|
||||
- **THEN** build/scripts/ 中只存在 .py 文件
|
||||
#### Scenario: git config 读取成功
|
||||
- **WHEN** git config 已设置 user.name 和 user.email
|
||||
- **THEN** 系统读取到正确的值
|
||||
|
||||
#### Scenario: git config 未设置
|
||||
- **WHEN** git config user.name 或 user.email 未设置
|
||||
- **THEN** 系统显示错误信息并退出
|
||||
|
||||
### Requirement: 时间戳版本号
|
||||
系统 SHALL 生成 YYYYMMDD_HHMMSS 格式的时间戳作为构建版本标识。
|
||||
@@ -51,47 +56,43 @@
|
||||
|
||||
#### Scenario: 显示构建信息
|
||||
- **WHEN** 构建成功完成
|
||||
- **THEN** 控制台输出版本号和构建文件清单
|
||||
- **THEN** 控制台输出版本号和作者信息
|
||||
|
||||
### Requirement: --obfuscate 参数支持
|
||||
系统 SHALL 支持 `--obfuscate` 命令行参数,用于启用代码混淆功能。
|
||||
### Requirement: 仅混淆构建
|
||||
系统 SHALL 仅提供混淆构建模式,移除非混淆选项。
|
||||
|
||||
#### Scenario: 使用 --obfuscate 参数
|
||||
- **WHEN** 用户执行 `uv run --with pyarmor python build.py --obfuscate`
|
||||
- **THEN** 系统使用 PyArmor 对 scripts 目录代码进行混淆
|
||||
#### Scenario: build.py 始终混淆
|
||||
- **WHEN** 用户执行 `uv run --with pyarmor python build.py`
|
||||
- **THEN** 系统使用 PyArmor 混淆 scripts 目录代码
|
||||
|
||||
#### Scenario: 不使用 --obfuscate 参数
|
||||
- **WHEN** 用户执行 `uv run python build.py`(不带 --obfuscate)
|
||||
- **THEN** 系统执行原有的复制行为,不进行混淆
|
||||
#### Scenario: 无 --obfuscate 参数
|
||||
- **WHEN** 用户运行 build.py
|
||||
- **THEN** 系统不需要 --obfuscate 参数,直接执行混淆构建
|
||||
|
||||
### Requirement: PyArmor 混淆执行
|
||||
系统 SHALL 在 `--obfuscate` 模式下调用 PyArmor 工具对 scripts 目录进行混淆。
|
||||
系统 SHALL 调用 PyArmor 工具对 scripts 目录进行混淆。
|
||||
|
||||
#### Scenario: PyArmor 成功执行
|
||||
- **WHEN** 启用 --obfuscate 且 PyArmor 可用
|
||||
- **WHEN** PyArmor 可用
|
||||
- **THEN** 系统执行 pyarmor gen --recursive 命令
|
||||
|
||||
#### Scenario: 混淆后文件输出
|
||||
- **WHEN** PyArmor 混淆完成
|
||||
- **THEN** build/scripts/ 目录包含混淆后的文件
|
||||
|
||||
#### Scenario: pyarmor_runtime 包含
|
||||
- **WHEN** PyArmor 混淆完成
|
||||
- **THEN** build/scripts/ 目录包含 pyarmor_runtime_xxxxxx 子目录
|
||||
- **THEN** build/ 目录包含混淆后的文件和 pyarmor_runtime 子目录
|
||||
|
||||
### Requirement: PyArmor 未安装友好提示
|
||||
系统 SHALL 在 PyArmor 未安装时提供清晰的错误提示,引导用户正确使用 `uv run --with pyarmor`。
|
||||
|
||||
#### Scenario: PyArmor ImportError
|
||||
- **WHEN** 启用 --obfuscate 但未通过 --with pyarmor 加载
|
||||
- **WHEN** 未通过 --with pyarmor 加载
|
||||
- **THEN** 系统显示友好错误信息,提示正确命令
|
||||
|
||||
### Requirement: SKILL.md 保持明文
|
||||
系统 SHALL 在混淆模式下仍然将 SKILL.md 作为明文文件复制,不进行混淆。
|
||||
|
||||
#### Scenario: SKILL.md 保持明文
|
||||
- **WHEN** 启用 --obfuscate 执行构建
|
||||
- **THEN** build/SKILL.md 文件为明文,内容与原文件一致
|
||||
- **WHEN** 启用混淆执行构建
|
||||
- **THEN** build/SKILL.md 文件为明文,内容包含动态注入的元数据
|
||||
|
||||
### Requirement: 混淆错误处理
|
||||
系统 SHALL 在 PyArmor 混淆失败时捕获错误并显示详细信息。
|
||||
@@ -99,3 +100,10 @@
|
||||
#### Scenario: PyArmor 命令失败
|
||||
- **WHEN** pyarmor 命令执行返回非零退出码
|
||||
- **THEN** 系统显示退出码、标准输出和错误输出信息
|
||||
|
||||
### Requirement: 一键发布脚本
|
||||
系统 SHALL 提供 publish.sh 脚本,一键执行混淆构建并发布。
|
||||
|
||||
#### Scenario: publish.sh 执行成功
|
||||
- **WHEN** 用户执行 `./publish.sh`
|
||||
- **THEN** 系统依次执行混淆构建和发布
|
||||
|
||||
82
openspec/specs/skill-publishing/spec.md
Normal file
82
openspec/specs/skill-publishing/spec.md
Normal file
@@ -0,0 +1,82 @@
|
||||
## Purpose
|
||||
|
||||
提供 skill 发布到目标 GitHub 仓库的能力,自动化将 build/ 目录内容同步到 skills 仓库。
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement: publish.py 一键发布
|
||||
系统 SHALL 提供 publish.py 脚本,运行后将 build/ 目录内容发布到目标仓库。
|
||||
|
||||
#### Scenario: 运行 publish.py 成功
|
||||
- **WHEN** 用户执行 `uv run python publish.py`
|
||||
- **THEN** 脚本完成所有发布步骤并输出成功信息
|
||||
|
||||
### Requirement: 使用临时目录 clone
|
||||
系统 SHALL 在系统临时目录创建临时文件夹,用于 clone 目标仓库。
|
||||
|
||||
#### Scenario: 临时目录自动清理
|
||||
- **WHEN** 发布完成或失败
|
||||
- **THEN** 临时目录被自动清理
|
||||
|
||||
### Requirement: shallow clone
|
||||
系统 SHALL 使用 `--depth 1` 参数 clone 目标仓库,加快 clone 速度。
|
||||
|
||||
#### Scenario: clone 参数正确
|
||||
- **WHEN** 执行 git clone
|
||||
- **THEN** 命令包含 `--depth 1` 参数
|
||||
|
||||
### Requirement: 目标仓库配置
|
||||
系统 SHALL 硬编码目标仓库 URL 为 `https://github.com/lanyuanxiaoyao/skills.git`。
|
||||
|
||||
#### Scenario: 目标仓库正确
|
||||
- **WHEN** publish.py 执行 clone
|
||||
- **THEN** clone 的仓库地址是 `https://github.com/lanyuanxiaoyao/skills.git`
|
||||
|
||||
### Requirement: 目标路径配置
|
||||
系统 SHALL 将内容发布到目标仓库的 `skills/lyxy-document-reader/` 路径。
|
||||
|
||||
#### Scenario: 目标路径正确
|
||||
- **WHEN** 文件同步完成
|
||||
- **THEN** 文件位于 `skills/lyxy-document-reader/` 目录下
|
||||
|
||||
### Requirement: 清空目标路径
|
||||
系统 SHALL 在复制前清空 `skills/lyxy-document-reader/` 目录内容。
|
||||
|
||||
#### Scenario: 旧文件被清理
|
||||
- **WHEN** 开始同步文件
|
||||
- **THEN** 目标目录下的旧文件被删除
|
||||
|
||||
### Requirement: 从 SKILL.md 读取版本号
|
||||
系统 SHALL 解析 build/SKILL.md 的 YAML frontmatter 获取 version 字段。
|
||||
|
||||
#### Scenario: 版本号读取成功
|
||||
- **WHEN** build/SKILL.md 包含 `metadata.version: "20260311_143022"`
|
||||
- **THEN** publish.py 读取到版本号 "20260311_143022"
|
||||
|
||||
### Requirement: git 提交信息
|
||||
系统 SHALL 使用包含版本号的 commit message,格式为 `publish: lyxy-document-reader <version>`。
|
||||
|
||||
#### Scenario: commit message 正确
|
||||
- **WHEN** 版本号是 20260311_143022
|
||||
- **THEN** commit message 是 `publish: lyxy-document-reader 20260311_143022`
|
||||
|
||||
### Requirement: git 提交并推送
|
||||
系统 SHALL 执行 git add、git commit 和 git push 操作。
|
||||
|
||||
#### Scenario: git 操作成功
|
||||
- **WHEN** 文件同步完成
|
||||
- **THEN** 系统执行 git add .、git commit 和 git push
|
||||
|
||||
### Requirement: build 目录存在检查
|
||||
系统 SHALL 在开始前检查 build/ 目录是否存在,不存在则提示错误。
|
||||
|
||||
#### Scenario: build 目录不存在
|
||||
- **WHEN** build/ 目录不存在
|
||||
- **THEN** 脚本显示错误信息并退出
|
||||
|
||||
### Requirement: SKILL.md 存在检查
|
||||
系统 SHALL 检查 build/SKILL.md 是否存在,不存在则提示错误。
|
||||
|
||||
#### Scenario: build/SKILL.md 不存在
|
||||
- **WHEN** build/SKILL.md 不存在
|
||||
- **THEN** 脚本显示错误信息并退出
|
||||
Reference in New Issue
Block a user