From c74fe71f0a9302ae32a2032b38db0afb72657f79 Mon Sep 17 00:00:00 2001 From: johnQ Date: Wed, 7 Oct 2026 17:06:36 +0800 Subject: [PATCH] =?UTF-8?q?feat(slark-dsh-cicd):=20=E6=96=B0=E5=A2=9E=20DS?= =?UTF-8?q?H/Slark=20=E5=8F=91=E5=B8=83=E5=AE=9E=E6=88=98=E6=8A=80?= =?UTF-8?q?=E8=83=BD=EF=BC=88REQ-20261007-0003=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新建 skills-dev/slark-dsh-cicd-plugin:plugin.json + skills/SKILL.md + skills/references/fork-release-and-post-checks.md - 覆盖两条发布线(DSH 插件 pack 双资产 / Slark 宿主重打包+签名)、权限与身份三连 (push:true 才可写,ls-remote 通 ≠ 能 push)、无上游写权限的 fork 发布且原仓库零改动、 干净单提交 + git diff --stat 树一致性 gate、改指向后必须重新 pack、 draft→publish 与「更新检查看不到新版」的因果、GitHub HTTPS/fetch 卡死/无 macOS timeout 的判死处置、发布后 SHA 逐项核对(verify-remote 仅 Windows)、app.asar 完整性约束、 ai-proj staging→released 与 /req done 证据要求及文档接口故障绕过 - 与 slark-cicd 明确分工并交叉引用,不重复 staging/生产/Desktop 细节 - update-plugin-meta.py PLUGIN_MAP 增加 slark-dsh-cicd-plugin (skill/dev) - generate-marketplace.py devops 分类补充 slark-dsh-cicd;marketplace.json 仅新增该条目 - 校验:claude plugin validate . 通过(警告为该仓库既有 install_name 字段提示)、git diff --check 干净 --- .claude-plugin/marketplace.json | 13 ++ generate-marketplace.py | 2 +- .../.claude-plugin/plugin.json | 11 + .../slark-dsh-cicd-plugin/skills/SKILL.md | 213 ++++++++++++++++++ .../fork-release-and-post-checks.md | 134 +++++++++++ update-plugin-meta.py | 1 + 6 files changed, 373 insertions(+), 1 deletion(-) create mode 100644 skills-dev/slark-dsh-cicd-plugin/.claude-plugin/plugin.json create mode 100644 skills-dev/slark-dsh-cicd-plugin/skills/SKILL.md create mode 100644 skills-dev/slark-dsh-cicd-plugin/skills/references/fork-release-and-post-checks.md diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 48d039e..77d8624 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -414,6 +414,19 @@ ], "strict": false }, + { + "name": "slark-dsh-cicd-plugin", + "source": "./skills-dev/slark-dsh-cicd-plugin", + "description": "DSH 插件包与 Slark 宿主补丁的发布实战技能:npm run pack 双资产、无上游写权限时的 fork 发布、干净单提交与树一致性 gate、draft Release、发布后 SHA 核对、asar 完整性与 ai-proj 状态对齐。", + "version": "1.0.0", + "category": "devops", + "keywords": [ + "devops", + "deployment", + "operations" + ], + "strict": false + }, { "name": "req-audit-plugin", "source": "./skills-req/req-audit-plugin", diff --git a/generate-marketplace.py b/generate-marketplace.py index e38e1ce..af0db19 100644 --- a/generate-marketplace.py +++ b/generate-marketplace.py @@ -60,7 +60,7 @@ def load_config(): def get_category_and_keywords(plugin_name): if any(x in plugin_name for x in ['dev-', 'coding', 'frontend']): return "development", ["development", "coding", "workflow"] - elif any(x in plugin_name for x in ['ops-', 'deploy', 'server', 'slark-cicd']): + elif any(x in plugin_name for x in ['ops-', 'deploy', 'server', 'slark-cicd', 'slark-dsh-cicd']): return "devops", ["devops", "deployment", "operations"] elif any(x in plugin_name for x in ['ai-proj', 'req']): return "productivity", ["project-management", "tasks", "requirements"] diff --git a/skills-dev/slark-dsh-cicd-plugin/.claude-plugin/plugin.json b/skills-dev/slark-dsh-cicd-plugin/.claude-plugin/plugin.json new file mode 100644 index 0000000..2ae9b7d --- /dev/null +++ b/skills-dev/slark-dsh-cicd-plugin/.claude-plugin/plugin.json @@ -0,0 +1,11 @@ +{ + "name": "slark-dsh-cicd-plugin", + "description": "DSH 插件包与 Slark 宿主补丁的发布实战技能:npm run pack 双资产、无上游写权限时的 fork 发布、干净单提交与树一致性 gate、draft Release、发布后 SHA 核对、asar 完整性与 ai-proj 状态对齐。", + "version": "1.0.0", + "author": { + "name": "qiudl" + }, + "install_name": "slark-dsh-cicd", + "install_type": "skill", + "dir_category": "dev" +} diff --git a/skills-dev/slark-dsh-cicd-plugin/skills/SKILL.md b/skills-dev/slark-dsh-cicd-plugin/skills/SKILL.md new file mode 100644 index 0000000..a479b37 --- /dev/null +++ b/skills-dev/slark-dsh-cicd-plugin/skills/SKILL.md @@ -0,0 +1,213 @@ +--- +name: slark-dsh-cicd +description: DSH 插件包与 Slark 宿主补丁的发布 runbook。覆盖 npm run pack 双 tgz 双资产、无上游写权限时的 fork 发布、干净单提交与树一致性 gate、改指向后必须重新打包、draft→publish 节奏、GitHub HTTPS/SSH 与 fetch 卡死处置、发布后 SHA 核对、app.asar 完整性约束、ai-proj 发布状态对齐。当用户要发布或升级 DSH 插件(dsh-worktable 等)、发布/更新 Slark 宿主补丁、push 或下载 GitHub 失败、插件「检查更新」看不到新版本、需要 fork 发布、或排查 asar 完整性/签名问题时使用。 +--- + +# DSH 插件与 Slark 宿主发布 runbook (slark-dsh-cicd) + +面向「把插件包/宿主补丁真正发出去」的可执行清单。默认在**发布机**执行;命令按阶段照做, +每阶段结束先核验再进入下一阶段。 + +## 适用与分工 + +两条发布线,**互不依赖**,不要串流程: + +| 发布线 | 产物 | 入口 | 权威源 | +| --- | --- | --- | --- | +| A · DSH 插件 | `dist/v/dsh-worktable.tgz` + `dsh-worktable-.tgz`(同一验收包) | `/npm run pack` | GitHub Release(tag = `v<包内版本>`) | +| B · Slark 宿主补丁 | 重打包 + 签名的 Slark.app(含内嵌 DSH runtime) | 宿主自身打包/签名链 | 宿主发布链,不经 GitHub Release | + +与同市场技能的分工,避免重复: + +- **本技能**:DSH 插件包发布、宿主补丁打包侧的完整性约束、发布链本身(权限、tag、Release、SHA 核对)。 +- `slark-cicd`:Slark 仓库 staging 验收、生产发布、Desktop 安装包上传 OSS、PR/CI 门禁——服务器与包分发细节以它为准。 +- `dev-cicd`:通用流水线设计与排查(Gitea Actions/缓存/并发)。 +- `ai-proj-cicd-release`:AI-Proj 服务自身的门禁与回滚。 + +## 铁律(先记死) + +1. **打包只走唯一入口**:`npm run pack`(或仓库自带的等价脚本)。手写 `tar`/`npm pack` 会绕过结构断言与安装导入验证。 + 脚本自己会做:版本一致性 → 兼容回归 → 构建 → 语法检查 → 结构断言(精确文件清单、无 `src/`、无 `.map`)→ + 独立临时目录真实安装 + `import()` 断言 → 客户端/宿主门禁 → 双资产同源 → SHA-256。 +2. **`package.json` 与 `dsh.plugin.json` 的版本必须相等**,否则构建与打包脚本 fail-closed。发版只升这一处对,不要只改一边。 +3. **产物出了包就不再改**:任何源码/常量/文档改动都可能改变 bundle → 旧 `.tgz` 立即作废、sha 必变。**改完必须重新 pack 并重新记录 sha**。 +4. **对上游仓库零改动是硬指标**(尤其是没有写权限的外部作者仓库):不 push、不打 tag、不建 Release/PR,一次都不做。 +5. **公开发布必须是 draft 起步**,对外动作经用户过目后再 `--draft=false`。 +6. **force push 只允许发生在自己 fork 的分支/tag 上**;绝不对上游使用 `-f`。 +7. **发布用的分支必须是干净单提交**,不要为了省事把本地历史推上去(本地历史可能含个人路径、凭据、临时调试 commit)。 +8. **"下载通了" ≠ "hash 对了"**:发布完成的判据是「远端资产 sha == 本地验收 sha」,不是页面能打开。 + +## 阶段 0:身份与权限三连(先判定能力,再决定链路) + +```bash +gh auth status # 登录账号是否符合预期 +ssh -T git@github.com 2>&1 | head -3 # SSH 身份(回显 Hi ! 即通) +gh api repos// --jq '.permissions' # 关键:{"pull":true,"push":} +``` + +- **只有 `push:true` 才能走「上游直发」**;`push:false` 时不要硬撞,直接走阶段 2 的 fork 发布。 +- **`git ls-remote` 通 ≠ 能 push**:读权限随时可通,写权限被拒要到 push 才暴露。不要用 ls-remote 成功推断可写。 +- 同时确认远端协议:`git remote -v`。HTTPS 到 GitHub 可能整体不通(见「网络与链路故障处置」), + 必要时改用 SSH:`git remote set-url origin git@github.com:/.git`。 + +## 阶段 1:发布线 A — DSH 插件(有上游写权限) + +```bash +export HOME="/Users/johnq" +export PATH="/Users/johnq/.local/node-v22.22.3-darwin-arm64/bin:/opt/homebrew/bin:$PATH" +cd / +npm run check && npm run test:gate && npm run pack +shasum -a 256 dist/v/*.tgz # 两个文件必须同 sha +tar -xzf dist/v/dsh-worktable.tgz -C "$(mktemp -d)" && grep -rn "<旧仓库名>" <解包目录> # 期望无输出 +git add -A && git commit -m "release: v(REQ-…)…" +git tag -f v && git push origin HEAD v +gh release create v dist/v/dsh-worktable.tgz dist/v/dsh-worktable-.tgz \ + --draft --title " v" --notes-file +``` + +- tag **必须等于包内版本**(`v` + `package.json#version`),否则下游按 tag 拼版本化资产名会 404。 +- Release 附**双资产**:固定名(供 `releases/latest/download/.tgz` 长期入口)+ 版本化名(可追责)。 + +## 阶段 2:发布线 B — 无上游写权限 → fork 发布 + +```bash +gh repo fork / --clone=false # 已存在则复用 +git remote add fork git@github.com:/.git # 已存在则 git remote set-url fork … +git fetch --no-tags origin main +``` + +### 2.1 干净单提交 + 树一致性 gate(必做,不可省) + +```bash +OURS=$(git rev-parse <本地完成发布内容的 HEAD>) +git checkout -B release/v origin/main +git rm -rq --cached . +git checkout "$OURS" -- . +git add -A +git commit -m "release: v(REQ-…)…" +git diff --stat "$OURS" # 必须是空输出 +``` + +- `git diff --stat "$OURS"` **非空即 abort**:切回原分支、删掉该发布分支、报告差异,不要「差一点也推」。 +- 该 gate 的真实作用是:让公开发布分支的**树**等于本地验收树,同时**不携带本地历史提交**(个人路径、调试、凭据)。 +- `git rm -rq --cached .` 只清索引,随后 `git checkout "$OURS" -- .` 覆盖工作树;若上游 `main` 存在本地树里**已删除**的 + 文件,残留文件会被 `git add -A` 重新加回导致 gate 失败——先确认 `git diff --name-status origin/main ` 无 `D`/`R`。 +- 提交前可顺手确认没有敏感路径混入:`git log -S'<本机绝对路径前缀>' --oneline`。 + +### 2.2 推分支 + tag + 附双资产的 draft Release + +```bash +git push -u fork release/v +git tag -f v && git push -f fork v # -f 只作用于 fork 的 tag +gh release create v dist/v/dsh-worktable.tgz dist/v/dsh-worktable-.tgz \ + --repo / --draft --title " v" --notes-file +``` + +- 推完复核「原仓库零改动」:`git ls-remote `(应无新分支/tag)+ `gh release list --repo `(列表应与之前一致)。 +- Release notes 至少写:新增 / 修复 / 清理 / 验证(实际跑过的测试与数字)/ 安装命令(指向 fork)/ 包 SHA-256 / 已知边界。 + +## 阶段 3:改指向(换仓库、换发布方时) + +只要「发布方」变了,插件里所有指向旧仓库的常量都要一次改全,否则**更新检查读的还是旧仓库 → 永远发现不了新版**: + +- 更新检查仓库常量(如 `UPDATE_REPO`,可能有多份:入口 + 独立模块 + 设置面板各自实现); +- 升级命令/提示词里的安装 URL(可能拼在字符串里); +- `package.json#repository.url`; +- 发布后核对脚本里硬编码的 REPO; +- README/AGENTS/安装说明里的一行命令、`git clone` 地址、文档链接; +- 任何 `grep -rn "<旧 owner>"` 的残留。 + +规则: + +- **只改指向,不改版本号与逻辑**;逐处 `git diff` 复核。 +- 「相关项目/其它仓库」的外链如果指向**另一位开发者的独立仓库**,不要顺手改指(目标仓库不存在会变成死链)——保留并在交付里说明。 +- **改完必须重新 pack**(铁律 3),解包 `grep` 确认产物内无旧仓库名,sha 与 Release 全部按新值重来。 + +## 阶段 4:draft → publish + +```bash +gh release edit v --repo / --draft=false +``` + +- **draft 期间 `releases/latest` 仍指向上一个已发布版本** → 插件内「检查更新」看不到新版本; + draft 资产的 tag 路径也不公开可下(需鉴权)。这是「更新检查不生效」最常见的**非 bug 原因**,先查 Release 是否还是 draft。 +- 发布前用用户过目确认;发布后再跑阶段 5。 + +## 阶段 5:发布后核对 + +优先用仓库自带的核对脚本,但**平台适配要先判定**:`verify-remote.mjs` 之类脚本若用 +`powershell Invoke-WebRequest` 下载,则**只在 Windows 可用**,在 macOS 会以 `FAIL: download fixed-name asset` 收场 +(它的 GET URL 仍能证明改指生效,不代表脚本思路错)。 + +macOS/无 PowerShell 时的等价核对(全部要过): + +```bash +gh release view v --repo / --json assets # 两个资产的 digest 必须都等于本地 sha +gh release download v --repo / --dir "$TMP" # draft 也可下载(已鉴权) +shasum -a 256 "$TMP"/*.tgz # 与本地验收 sha 逐字一致 +cmp "$TMP/dsh-worktable.tgz" dist/v/dsh-worktable.tgz # byte-identical +tar -xzf "$TMP/dsh-worktable.tgz" -C "$TMP/ext" && grep -rn "<旧仓库名>" "$TMP/ext" # 无输出 +curl -sL -o /dev/null -w '%{http_code}\n' <版本化资产 URL> # 发布后 200/302;draft 阶段 404 属预期 +``` + +结论口径:**文件名 + 结构(精确文件清单)+ 包内版本 + 双资产同源 + 远端=本地验收 SHA + 真实安装导入** 全过才算发布验收。 +draft 阶段只能做「远端资产 = 本地验收包」的比对,匿名可下载性要等 publish 后再验。 + +## 阶段 6:Slark 宿主补丁(宿主侧特有) + +- **改 `app.asar` 无效**:Electron 用 `ElectronAsarIntegrity` 记录 asar 头哈希并有 fuse 完整性校验,直接热改会让 + 哈希失配,破坏签名,应用拒绝启动或行为异常。**必须重打包 + 重新安装**,不要在安装目录里就地改文件。 +- 宿主补丁落在 fork/分支上时:rebase 到发布基线后**必须重跑全量测试**(类型检查 + 全量单测), + 例如 `pnpm -r typecheck` 与 `node --import tsx --test "src/**/*.test.ts"`;rebase 不产生冲突**不代表语义没变**。 +- 宿主发布与插件发布解耦:宿主要用新插件版本,通常靠宿主内嵌 runtime 的升级,而不是「插件先发、宿主自动跟进」。 + +## 网络与链路故障处置 + +| 现象 | 判定 | 处置 | +| --- | --- | --- | +| `curl` 访问 GitHub 返回 HTTP `000`(HTTPS 整体不通) | 出口到 github.com:443 被掐断,与凭据无关 | 改走 SSH:`git remote set-url origin git@github.com:/.git`,并确认 SSH 身份 | +| `git fetch` 长时间无输出/0 字节、卡十几分钟 | 链路假死,不是"慢" | 判死并清理后重试(见下方循环模板),不要原地等 | +| 30 秒内报 `fatal: early EOF` | 链路被中途掐断(代理/MTU/网络策略) | 记录原文与时间点;换协议/换网络重试;不要反复 force | +| macOS 没有 `timeout` 命令 | BSD 无 GNU timeout | 用后台 + 轮询模板 | +| `git push` 报无权限但 ls-remote 正常 | 只读凭据 | 直接走 fork 发布(阶段 2),不要重试上游 | + +macOS 无 `timeout` 时的判死模板: + +```bash +( git fetch --no-tags origin main ) & PID=$! +for i in $(seq 1 30); do sleep 1; kill -0 "$PID" 2>/dev/null || break; done +if kill -0 "$PID" 2>/dev/null; then kill -9 "$PID"; pkill -9 -f git-upload-pack; echo "TIMEOUT(30s) — 链路假死"; fi +``` + +- 认证/网络失败时**不做破坏性重试**(尤其不要为了"绕过"而 force 到上游);把失败原文、已完成的步骤、当前指针状态写清楚上报。 +- 推送成功但平台上看不到:查 `git config --get-regexp '^url\.'` 是否有 `pushInsteadOf` 静默改写了目标。 + +## ai-proj 对齐 + +- 需求阶段:动手前立项(`create_requirement`,写清需求描述 / 预期结果 / 验收标准三段式 + AC),commit/PR 引用 `REQ-…`。 + 纯文档/工具/只读排查可例外。 +- 交付阶段:**真实发布之后**才推进 `staging → released`;只有计划、没有发布产物或验收证据时不要推进。 +- 归档阶段:`/req done` 归档前要**逐条 AC 证据**(命令、输出、资产 sha、URL),不能只写"已完成"。 +- **文档接口故障绕过**:若 `append-document-content` / `create-and-attach` 持续报 + `document_versions_document_id_version_number_key` 唯一约束错误(同一 `(document_id, version_number)` 冲突), + 改用 `PUT /api/v1/requirements/{id}` 把说明写进**需求描述**——`requirements` 表不经过 `document_versions`,可绕开该约束; + 不要伪造版本号或删除已有文档版本。 + +## 故障分流 + +| 现象 | 处置 | +| --- | --- | +| 插件「检查更新」永远看不到新版 | 依次查:Release 是否还是 draft;`releases/latest` 指向;插件内 `UPDATE_REPO` 是否仍指旧仓库;`latest` 资产名是否与代码拼的一致 | +| pack 报结构断言失败 | 包内混入了 `src/`、`.map` 或多余文件;检查 `files` 字段与构建产物位置,不要手改 tgz | +| 两个 tgz 的 sha 不一致 | 打包脚本的"同源复制"被绕过(手工 pack/改名);重新走唯一入口 | +| `git diff --stat ` 非空 | 上游 `main` 有本地已删除/重命名文件残留 → 先 `git rm --cached` 清理并确认无 `D`/`R`,gate 不过不上推 | +| 发布分支含个人路径/凭据 commit | 不要 push 该历史;改用干净单提交分支(阶段 2.1) | +| `gh release create` 报 tag 不存在/被占用 | tag 必须已存在或由 `create` 指定;draft 会以 `untagged-…` 预览 URL 呈现,属正常,publish 后即 `.../tags/v` | +| draft 资产匿名下载 404 | 预期行为(draft 需鉴权);发布后用 `curl -sL -o /dev/null -w '%{http_code}'` 复验 | +| 宿主改完不生效 | 是否只改了 `app.asar`(被完整性校验挡住);必须重打包重装;再查是否加载了另一份 runtime | + +## 参考 + +- `references/fork-release-and-post-checks.md` —— fork 发布可复制命令序列、Release notes 模板、发布后核对矩阵。 +- 同市场:`slark-cicd`(Slark staging/生产/Desktop)、`dev-cicd`(流水线设计)、`ai-proj-cicd-release`(AI-Proj 发布链)。 +- 权威流程以目标仓库自带的发布脚本与文档为准;本技能是清单,不替代仓库脚本的断言。 diff --git a/skills-dev/slark-dsh-cicd-plugin/skills/references/fork-release-and-post-checks.md b/skills-dev/slark-dsh-cicd-plugin/skills/references/fork-release-and-post-checks.md new file mode 100644 index 0000000..97e99f1 --- /dev/null +++ b/skills-dev/slark-dsh-cicd-plugin/skills/references/fork-release-and-post-checks.md @@ -0,0 +1,134 @@ +# Fork 发布与发布后核对 + +本文件是 `slark-dsh-cicd` 的操作附件:需要**无上游写权限发布**,或需要**逐项核对远端资产**时读取。 +把它当模板:替换 `<...>` 占位符,按阶段执行,每阶段的核验不通过就停下,不要"带病"推进。 + +## 0. 变量与前置 + +```bash +export HOME="/Users/johnq" +export PATH="/Users/johnq/.local/node-v22.22.3-darwin-arm64/bin:/opt/homebrew/bin:$PATH" + +UP=/ # 例如 Aisland-SJL/dsh-worktable(外部作者,无写权限) +ME= # 例如 qiudl +PKG=/01_content # 打包脚本所在目录 +VER=0.4.1 # = package.json#version +``` + +```bash +gh auth status +ssh -T git@github.com 2>&1 | head -3 +gh api "repos/$UP" --jq '.permissions' # push:false → 必须走 fork 发布 +git remote -v +``` + +## 1. 改指向 → 重新打包(顺序不可颠倒) + +```bash +cd "$PKG" +grep -rn "" .. --include='*.json' --include='*.ts' --include='*.tsx' --include='*.md' --include='*.mjs' +# 逐处改完只后再打包: +npm run check && npm run test:gate && npm run pack +shasum -a 256 dist/v$VER/*.tgz +TMP=$(mktemp -d) && tar -xzf dist/v$VER/dsh-worktable.tgz -C "$TMP" +grep -rn "" "$TMP" ; echo "grep exit=$? (1 = 无残留,正确)" +``` + +判据:`check`/`test:gate`/`pack` 全部 exit 0;两个 tgz 同 sha;解包无旧仓库名。 + +## 2. fork 与干净发布分支 + +```bash +cd +gh repo fork "$UP" --clone=false # 已存在会提示 already exists,可复用 +git remote add fork "git@github.com:$ME/.git" # 已存在:git remote set-url fork … +git fetch --no-tags origin main + +OURS=$(git rev-parse HEAD) # 本地"发布内容已就绪"的 HEAD +git diff --name-status origin/main "$OURS" | awk '$1 ~ /^[DR]/' # 期望空;有 D/R 先处理再用 gate + +git checkout -B release/v$VER origin/main +git rm -rq --cached . +git checkout "$OURS" -- . +git add -A +git commit -m "release: v$VER(REQ-…)<一句话说明>" + +DIFFOUT="$(git diff --stat "$OURS")" +if [ -n "$DIFFOUT" ]; then + echo "GATE FAILED:"; echo "$DIFFOUT" + git checkout <原分支> && git branch -D release/v$VER # abort:不留半成品分支 + exit 1 +fi +echo "GATE PASSED: release tree == OURS tree" +``` + +## 3. 推送(只对 fork)与 draft Release + +```bash +git push -u fork release/v$VER +git tag -f v$VER && git push -f fork v$VER # -f 仅限自己 fork 的 tag + +gh release create v$VER \ + dist/v$VER/dsh-worktable.tgz dist/v$VER/dsh-worktable-$VER.tgz \ + --repo "$ME/" --draft --title " v$VER" --notes-file /tmp/rel-notes.md +``` + +原仓库零改动复核: + +```bash +git ls-remote "git@github.com:$UP.git" # 无 release/v… 分支、无新 tag +gh release list --repo "$UP" # 与发布前一致 +``` + +### Release notes 模板(draft 阶段就写全新值) + +```markdown +# v +> 发布方:fork /(原仓库 为上游来源)。插件内更新检查已指向本 fork。 + +## 新增 / 修复 / 清理 +## 验证 +- check / gate / pack 实际输出(测试条数、断言项) +- 双资产同 SHA: +- 解包 grep 无旧仓库名 +- 发布分支为干净单提交(父提交 = 上游 main),`git diff --stat ` 为空 +## 安装 +网页端 / 桌面端一行命令(指向 fork) +## 已知边界 +- draft 期间 releases/latest 仍指旧版 → 更新检查看不到新版 +- 保留的第三方外链、平台未验证范围 +``` + +## 4. publish 与发布后核对矩阵 + +```bash +gh release edit v$VER --repo "$ME/" --draft=false +``` + +| 核对项 | 命令 | 通过判据 | +| --- | --- | --- | +| 资产列表与 digest | `gh release view v$VER --repo $ME/ --json assets` | 两个资产 `digest` = 本地 sha | +| 下载后 sha | `gh release download v$VER --repo $ME/ --dir "$D"` + `shasum -a 256 "$D"/*.tgz` | 与本地逐字一致 | +| 与本地验收件一致 | `cmp "$D/dsh-worktable.tgz" dist/v$VER/dsh-worktable.tgz` | 无差异(byte-identical) | +| 包内无旧仓库名 | 解包后 `grep -rn ""` | 无输出(exit 1) | +| 包内版本 = tag | 解包读 `package.json#version` | `v$VER` | +| 匿名可下载 | `curl -sL -o /dev/null -w '%{http_code}\n' <资产 URL>` | publish 后 200/302;draft 期 404 属预期 | +| 安装可用 | 临时目录 `npm install ` + `import()` 断言 | 导出/版本断言通过 | + +- **`verify-remote.mjs` 的平台限制**:其下载走 `powershell Invoke-WebRequest`,只在 Windows 可用; + 在 macOS 会 `FAIL: download fixed-name asset`。此时用上表的 `gh release view/download` + `shasum` + `cmp` 等价替代, + 并说明该脚本的 GET URL 已证明改指生效。 +- **"检查更新"看不到新版**的排查顺序:Release 是否 draft → `releases/latest` 指向 → 插件内 `UPDATE_REPO` 指向 → + `latest` 资产名与代码拼法一致。 + +## 5. 链路判死模板(macOS 无 `timeout`) + +```bash +( git fetch --no-tags origin main ) & PID=$! +for i in $(seq 1 30); do sleep 1; kill -0 "$PID" 2>/dev/null || break; done +if kill -0 "$PID" 2>/dev/null; then kill -9 "$PID"; pkill -9 -f git-upload-pack; echo "TIMEOUT(30s)"; fi +``` + +- HTTPS 到 GitHub `curl` 返回 `000` → 整体不通,改 SSH(`git remote set-url`)。 +- 30 秒内 `fatal: early EOF` → 链路被掐断;记录原文与时间,换网络/协议重试。 +- 认证或网络失败时不做破坏性重试,也不要把 force 用到上游;保留本地提交并上报失败原文。 diff --git a/update-plugin-meta.py b/update-plugin-meta.py index 87d8680..b74e52c 100644 --- a/update-plugin-meta.py +++ b/update-plugin-meta.py @@ -49,6 +49,7 @@ PLUGIN_MAP = { "karpathy-guidelines-plugin": ("karpathy-guidelines", "skill", "dev"), "pull-request-plugin": ("pull-request", "skill", "dev"), "review-checklist-plugin": ("review-checklist", "skill", "dev"), + "slark-dsh-cicd-plugin": ("slark-dsh-cicd", "skill", "dev"), # skills-integration "data-excel-plugin": ("data-excel", "skill", "integration"),