diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b46f664 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +# Python 缓存 +__pycache__/ +*.py[cod] +*.egg-info/ +.venv/ +venv/ + +# 系统/编辑器 +.DS_Store +Thumbs.db +.idea/ +.vscode/ diff --git a/SKILL.md b/SKILL.md index dde92ef..85725a9 100644 --- a/SKILL.md +++ b/SKILL.md @@ -29,7 +29,7 @@ description: 自动化克隆、初始化、品牌化、Docker 部署并提交项 源码包与演示交付包应分开管理。 7. 本规则约束对外呈现口径,不替代、不免除任何第三方许可证或法律规定的合规义务。 -## 20 步工作流 +## 21 步工作流 | 步骤 | 名称 | 必做/跳过 | 要求 | |---:|---|---|---| @@ -53,8 +53,10 @@ description: 自动化克隆、初始化、品牌化、Docker 部署并提交项 | 17 | 产品截图与全功能录屏 | 必做 | 在最终健康版本上重新采集全套高清界面截图和录屏;逐张核对 README 引用;监控页必须验证真实视频帧、时间轴增长和画面能量,禁止空画面/旧图复用 | | 18 | 标准化 README 与版本归档 | 必做 | 按当前产品口径编写 README;不主动出现来源/致谢/版本对比;按授权决定是否提交 | | 19 | 交付物核查 | 必做 | 运行交付物阻断式核查,7 项交付物齐备并生成交付 manifest | +| 20 | 上传交付树双存档 | 授权推送时必做 | 克隆交付树仓库,**同时上传交付 zip 与同名解压目录**(README/截图/录屏/文档),放行 mp4、更新 registry/sidecar/交付登记/README,推送后比对 HEAD 并用 Gitea API 验证解压内容已在远程 | 非 Docker 项目跳过步骤 5、12–14,其余步骤仍有效;步骤 3–4 产物仅内部留存,不对外交付。 +步骤 20 仅在用户**明确授权推送**到交付树仓库时执行;未授权时只在本地 `.Codex/delivery` 产出交付包,沿用“不推送代码”约束。 ## 素材采集时序(内部核对 + 对外素材) @@ -255,6 +257,62 @@ python scripts/deliverables_check.py \ 退出码为 0 才算交付物齐备。 禁止伪造截图/录屏/网盘链接,禁止把 README 写成与实际不符的宣传稿。 +### 上传交付树双存档(步骤 20) + +交付核查通过后,把交付物归档到统一的**交付树仓库**(默认 `https://code.xinmi.cloud/depei/panel-delivery-tree`,分支 `main`)。 +该仓库既是标准目录树模板,也是交付登记中心;真实源码以 git submodule 挂在 `项目源码/` 并固定到交付提交。 + +**强制双存档**:除了正式交付 zip,必须同时上传该 zip 的**同名解压目录**,做到「压缩包 + 解压内容」并存—— +zip 便于整包下载交付,解压目录(README、截图、录屏 mp4、文档)便于在 Gitea 网页直接浏览与增量检索,不必下载解压。 + +操作流程: + +1. 克隆/更新交付树仓库(浅克隆即可),确认 `git status` 干净且与 `origin/main` 同步;若尚未挂源码子模块, + 用 `git submodule add -b main <源码仓库git> 项目源码/`,再 `git -C 项目源码/ checkout <交付提交>` 固定版本。 +2. 复制 zip 到 `交付包/-delivery-.zip`;再把 zip 的解压目录**保持包内根结构**整体复制到 + `交付包/-delivery-/`(`README.md`、`docs/screenshots/`、`截图/界面截图/`、`录屏/*.mp4`、`文档/` 等)。 + - 含中文路径的递归复制/删除优先用 Python `shutil`(PowerShell 管道处理中文文件名易乱码,删除操作也可能被安全策略拦截)。 +3. 在 `.gitignore` 放行交付目录下被全局忽略的二进制(录屏等),`交付包模板/` 仍保持排除: + + ```gitignore + *.mp4 + *.ts + *.m3u8 + *.zip + !交付包/ + !交付包/**/ + !交付包/**/*.zip + !交付包/**/*.mp4 + ``` + + 复制后执行 `git check-ignore -v "交付包//录屏/x.mp4"`,确认命中的是 `!交付包/**/*.mp4` 取反规则(即已不再被忽略)。 +4. 更新登记引用,人类可读与机器可读都要改,且数值与实际一致: + - sidecar `交付包/-delivery-.json` 与根 `registry.json`:在该交付项补充/核对 + `package`、`packageSizeBytes`、`packageSizeMB`、`sha256`、`git`(primary/web/upstream/submodulePath/pinnedCommit/branch)、 + `deploy`、`manifest`,以及 **`extractedDir`、`extractedFileCount`、`extractedSizeBytes`、`extractedSizeMB`、`archiveForm`**; + - `交付登记.md`:登记总表增加「解压内容」列,项目小节同时链接 zip 与解压目录;「新增交付项目时」流程写明双存档为必需步骤; + - `交付包/README.md` 与根 `README.md`:说明「压缩包 + 同名解压目录双存档」,给出解压内容结构树与 mp4 放行说明。 +5. 数据必须实测:解压文件数/字节数用脚本统计,MB 保留两位;SHA256 用 + `Get-FileHash -Algorithm SHA256` 现算,禁止照抄历史值。 +6. `git add -A` 后核对 `git status`:解压目录内 png/md/mp4 为新增、登记文件为修改; + 两个 JSON 用 `python -m json.tool` 校验合法。 +7. 用具体中文业务信息写提交说明(不出现“工作流”),例如 + `交付包补充解压内容双存档:README/截图x12/录屏/文档,更新登记与.gitignore放行mp4`,然后 `git push origin main`。 +8. 推送后**双重验证**: + - `git rev-parse HEAD` 与 `git ls-remote origin refs/heads/main` 必须完全一致; + - 用 Gitea Contents API 列目录,确认解压内容(尤其录屏 mp4)已在远程。中文路径必须**逐段 URL 编码并保留斜杠**, + 不能对整段路径 `EscapeDataString`(会把 `/` 编成 `%2F`,导致 404): + + ```powershell + function EscPath($p){ ($p -split '/' | ForEach-Object { [uri]::EscapeDataString($_) }) -join '/' } + $h = @{ Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(':')) } + $u = "https:///api/v1/repos///contents/$(EscPath '交付包//录屏')?ref=main" + Invoke-RestMethod -Uri $u -Headers $h + ``` + +> 授权前提:向交付树/源码仓库推送必须有用户明确授权;未授权项目沿用“不推送代码”,只在本地产出交付包。 +> 双存档会让仓库同时保存 zip 与解压目录内的 mp4(体积约为二者之和),这是换取在线可浏览性的预期取舍。 + ## 状态管理 状态统一放在目标项目的 `.Codex` 目录: @@ -322,4 +380,5 @@ python scripts/workflow_manager.py report - 标准化 README 覆盖全部必备内容,以当前产品口径编写,图文结合、架构图准确、部署教程可落地,且不作虚假权属表述。 - 7 项交付物齐备,`.Codex/delivery/manifest.md` 完整;`deliverables_check.py` 退出码为 0。 - 保密与知识产权要求已遵守:成果不私用/不外传,交付材料与验收记录可溯源。 +- 经授权推送时,交付物已双存档到交付树:zip 与同名解压目录(README/截图/录屏/文档)均已推送,`registry.json`、sidecar、交付登记与各 README 中的 `extractedDir`、文件数、体积、SHA256、Git 地址与锁定提交一致,本地与远程 HEAD 相同,且 Gitea API 能列出解压目录中的录屏文件。 - 最终 Git 提交信息描述具体业务变化,不出现“工作流”。 \ No newline at end of file diff --git a/references/delivery-contract.md b/references/delivery-contract.md index 721db19..1415d48 100644 --- a/references/delivery-contract.md +++ b/references/delivery-contract.md @@ -29,7 +29,7 @@ → [此后才允许改代码] 品牌/界面/AI/标识规范(6-11) → 产品构建启动(15) → 健康验证(16) → 产品界面截图 + 全功能录屏(17) - → README/版本归档(18) → 交付核查(19) + → README/版本归档(18) → 交付核查(19) → 交付树双存档(20,授权推送时) ``` - 内部基线截图必须是代码零改动状态下的真实画面,仅用于内部核对,任何情况下不进入交付物。 @@ -106,6 +106,24 @@ docs/screenshots/ # README 引用的全部配图,相对路径完整, 4. 包内不出现内部工具、执行过程、外部项目线索及版本对比信息,命名使用甲方可读的中性名称。 5. 交付清单列出每项交付物的包内路径/链接、默认账号、验收记录与售后说明。 +### 4.2 交付树仓库双存档(授权推送时,强制) + +用户明确授权推送到交付树仓库(默认 `https://code.xinmi.cloud/depei/panel-delivery-tree`)时,必须做到: + +1. **压缩包 + 解压内容双存档**:`交付包/-delivery-.zip` 与同名解压目录 + `交付包/-delivery-/`(README、`docs/screenshots/`、`截图/界面截图/`、`录屏/*.mp4`、`文档/`)同时入库; + 前者用于整包下载,后者用于在 Gitea 网页直接浏览,内容必须与 zip 一致。 +2. 真实源码以 git submodule 挂到 `项目源码/` 并固定到交付提交;登记 Git 主地址、上游来源、分支与锁定 commit。 +3. 录屏等被全局 `.gitignore` 忽略的二进制,须在 `交付包/**` 下显式取反放行(`!交付包/**/*.mp4` 等), + 并用 `git check-ignore -v` 确认实际命中取反规则;`交付包模板/` 仍不入库二进制。 +4. 机器与人工登记一致:sidecar JSON 与 `registry.json` 记录 `package`、字节数、`sha256`、 + `git`、`deploy`、`extractedDir`、`extractedFileCount`、`extractedSizeBytes/MB`、`archiveForm`; + `交付登记.md`、`交付包/README.md`、根 `README.md` 同步链接 zip 与解压目录。文件数、体积、SHA256 必须实测,禁止照抄。 +5. 推送后双重验证:`git rev-parse HEAD` 与 `git ls-remote origin refs/heads/main` 一致; + 用 Gitea Contents API 分段编码中文路径(保留 `/`)确认解压目录与录屏 mp4 已在远程。 +6. 含中文路径的批量复制/删除优先用 Python `shutil`,避免 PowerShell 管道中文乱码与删除策略拦截。 +7. 未获推送授权时不推送任何仓库,只在项目内 `.Codex/delivery` 本地留档,沿用“不推送代码”约束。 + ## 5. 验收标准(7 条,全部达标方可验收) 1. **运行**:正常启动、稳定运行;所有功能可正常操作,无报错、失效、页面错乱或接口异常。 diff --git a/scripts/workflow_manager.py b/scripts/workflow_manager.py index 4fe487f..969dcc7 100644 --- a/scripts/workflow_manager.py +++ b/scripts/workflow_manager.py @@ -75,12 +75,12 @@ class Step: class WorkflowManager: """工作流管理器""" - # 完整的20个核心步骤 + # 完整的21个核心步骤 ALL_TYPES = [ProjectType.DOCKER_WEB, ProjectType.DOCKER_API, ProjectType.DOCKER_MICROSERVICES, ProjectType.DESKTOP, ProjectType.MOBILE, ProjectType.CLI] DOCKER_TYPES = [ProjectType.DOCKER_WEB, ProjectType.DOCKER_API, ProjectType.DOCKER_MICROSERVICES] # 关键时序:初始基线启动(3,内部) → 初始界面截图(4,内部) → 面板改造(6-11) → 产品构建启动(15) - # → 健康验证(16) → 产品截图与录屏(17) → README/归档(18) → 交付核查(19) + # → 健康验证(16) → 产品截图与录屏(17) → README/归档(18) → 交付核查(19) → 交付树双存档(20,授权推送时) CORE_STEPS = [ Step(0, "克隆项目", "从Git仓库克隆项目到本地,不修改任何业务代码", ALL_TYPES), Step(1, "项目完整度评估", "评估项目完整度、依赖情况与可运行性", ALL_TYPES), @@ -102,6 +102,7 @@ class WorkflowManager: Step(17, "产品截图与全功能录屏", "采集当前产品全套高清界面截图(中性文件名)和全功能演示录屏;内部基线素材不进入交付物", ALL_TYPES), Step(18, "标准化README与版本归档", "编写标准化 README(引用最终素材、含架构图与部署教程);不主动写来源/致谢宣传,并按授权决定是否提交", ALL_TYPES), Step(19, "交付物核查", "按7项交付物清单与7条验收标准做交付前阻断式核查", ALL_TYPES), + Step(20, "上传交付树双存档", "经用户授权后克隆交付树仓库,同时上传交付zip与同名解压目录(README/截图/录屏/文档),放行mp4、更新registry/sidecar/交付登记/README,推送并做本地远程HEAD比对与Gitea API双重验证", ALL_TYPES), ] # 旧版本步骤名 → 新版本步骤名(用于历史状态迁移)