- 新建 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 <OURS> 树一致性 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 干净
5.5 KiB
5.5 KiB
Fork 发布与发布后核对
本文件是 slark-dsh-cicd 的操作附件:需要无上游写权限发布,或需要逐项核对远端资产时读取。
把它当模板:替换 <...> 占位符,按阶段执行,每阶段的核验不通过就停下,不要"带病"推进。
0. 变量与前置
export HOME="/Users/johnq"
export PATH="/Users/johnq/.local/node-v22.22.3-darwin-arm64/bin:/opt/homebrew/bin:$PATH"
UP=<upstream-owner>/<repo> # 例如 Aisland-SJL/dsh-worktable(外部作者,无写权限)
ME=<your-account> # 例如 qiudl
PKG=<repo>/01_content # 打包脚本所在目录
VER=0.4.1 # = package.json#version
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. 改指向 → 重新打包(顺序不可颠倒)
cd "$PKG"
grep -rn "<upstream-owner>" .. --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 "<upstream-owner>" "$TMP" ; echo "grep exit=$? (1 = 无残留,正确)"
判据:check/test:gate/pack 全部 exit 0;两个 tgz 同 sha;解包无旧仓库名。
2. fork 与干净发布分支
cd <repo-root>
gh repo fork "$UP" --clone=false # 已存在会提示 already exists,可复用
git remote add fork "git@github.com:$ME/<repo>.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: <name> 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
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/<repo>" --draft --title "<name> v$VER" --notes-file /tmp/rel-notes.md
原仓库零改动复核:
git ls-remote "git@github.com:$UP.git" # 无 release/v… 分支、无新 tag
gh release list --repo "$UP" # 与发布前一致
Release notes 模板(draft 阶段就写全新值)
# <name> v<ver>
> 发布方:fork <ME>/<repo>(原仓库 <UP> 为上游来源)。插件内更新检查已指向本 fork。
## 新增 / 修复 / 清理
## 验证
- check / gate / pack 实际输出(测试条数、断言项)
- 双资产同 SHA:<sha256>
- 解包 grep 无旧仓库名
- 发布分支为干净单提交(父提交 = 上游 main),`git diff --stat <OURS>` 为空
## 安装
网页端 / 桌面端一行命令(指向 fork)
## 已知边界
- draft 期间 releases/latest 仍指旧版 → 更新检查看不到新版
- 保留的第三方外链、平台未验证范围
4. publish 与发布后核对矩阵
gh release edit v$VER --repo "$ME/<repo>" --draft=false
| 核对项 | 命令 | 通过判据 |
|---|---|---|
| 资产列表与 digest | gh release view v$VER --repo $ME/<repo> --json assets |
两个资产 digest = 本地 sha |
| 下载后 sha | gh release download v$VER --repo $ME/<repo> --dir "$D" + shasum -a 256 "$D"/*.tgz |
与本地逐字一致 |
| 与本地验收件一致 | cmp "$D/dsh-worktable.tgz" dist/v$VER/dsh-worktable.tgz |
无差异(byte-identical) |
| 包内无旧仓库名 | 解包后 grep -rn "<upstream-owner>" |
无输出(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 <tgz> + 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)
( 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 用到上游;保留本地提交并上报失败原文。