关于 upstream-fix-and-pin
用于修复上游依赖并让下游开发继续进行的开发技能,涵盖提交补丁、用完整提交 SHA 固定依赖,以及评审延迟时切换到本地链接。
主要功能
- 01上游修复与 PR 流程
- 02用完整提交 SHA 固定依赖
- 03配置 pnpm v10 构建脚本白名单
- 04软件包产物与安装指引
- 05合并后更新固定版本及本地链接回退
适用场景
- 01修复等待合并时保持下游开发
- 02测试期间可复现地固定依赖补丁
- 03处理 Git 依赖的 pnpm v10 安装脚本
- 04上游评审停滞时继续本地开发
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mizchi/ skills --skill upstream-fix-and-pin安装后在 Claude Code 中输入/upstream-fix-and-pin确认已加载。
附带文件README.md
详细介绍
上游修复与固定版本
适用场景
需要修复依赖库,且该修复是下游项目实现或调试所必需的情况。具体来说:
- 目标 OSS 由自己(或同一 org)拥有,可以自行提交 PR
- 如果下游项目在修复合并前停滞,会造成问题
- 想在采用 monkey-patch / fork publish / vendor 等较重的手段前先尝试这种方式
流程
[1] 上流に branch を切って fix
│
▼
[2] push して PR
│
▼ 下流は (3) で繋ぐ
[3] 下流 package.json を git ref で pin (branch HEAD SHA)
│
▼
[4] PR が merge されたら main の merge SHA に張り替え
│
▼
[5] (任意) 上流が npm publish するならそれに乗り換え
如果 PR 长期没有进展,请改用 link:(见下文)。
固定版本语法
pnpm / npm 通用:
{
"dependencies": {
"<pkg>": "github:<owner>/<repo>#<full-40-char-sha>"
}
}
固定分支名(#fix/foo)虽然方便,但 merge / rebase 会导致 SHA 变化,因此无法复现。仅用于 lab / 验证时,应一律使用完整 SHA。
获取 SHA
GitHub 的 codeload 要求提供完整的 40 位 SHA。如果传入短 SHA:
ERR_PNPM_FETCH_404 GET https://codeload.github.com/<owner>/<repo>/tar.gz/<short>: Not Found - 404
输入错误也会报同样的错误。要确保获取正确的 SHA:
# upstream の clone から
git -C ~/ghq/github.com/<owner>/<repo> rev-parse <branch>
# クローン無しで origin 直
git ls-remote https://github.com/<owner>/<repo> <branch>
PR 验证脚本中使用 git ls-remote 更安全(本地 clone 如果过旧,可能会获取到不同的 SHA)。
pnpm v10:构建脚本 allowlist
如果通过 git ref 固定的包在 PR 中添加了 "prepare": "tsc" 这类安装时 hook,pnpm v10 默认会拒绝执行构建脚本。错误信息:
ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED
The git-hosted package "<pkg>@<ver>" needs to execute build scripts but is not in the "onlyBuiltDependencies" allowlist.
在下游的 package.json 中明确允许:
{
"pnpm": {
"onlyBuiltDependencies": ["<pkg>"]
}
}
(如果是 workspace,则在 pnpm-workspace.yaml 中设置同等的 field)
这是 supply-chain mitigation。对于不包含 prepare 的 PR,或将构建产物(dist/)纳入 git 跟踪的 PR,无需设置 allowlist。
PR 中应包含哪些内容
为了让「通过 git install 即可运行」,下游项目不能遇到问题。最低限度:
- 将
dist/纳入 git 跟踪(例如tsc输出)。将其从.gitignore中移除并提交。添加.gitattributes,设置dist/** linguist-generated=true和-diff,可以避免 PR review 时 diff 膨胀。 - (辅助措施)在
package.json中添加"prepare": "tsc"。通过 npm install 安装时会运行。pnpm git ref 需要设置 allowlist,因此会增加用户操作步骤,这是需要权衡的地方。
是否两者都添加,还是只持续跟踪 dist/,取决于偏好。后者对 consumer 的阻碍更少。
从长期维护的角度来看,可以在 CI 中加入「通过 commit hook 执行 pnpm build && git diff --exit-code dist/」,在修改 src/ 时防止忘记同步 dist/。
合并后更新固定版本
PR 合并后,更新下游使用的 SHA:
# main の HEAD SHA を取得
git -C ~/ghq/github.com/<owner>/<repo> fetch origin main
git -C ~/ghq/github.com/<owner>/<repo> rev-parse origin/main
将该 SHA 填入下游的 package.json,运行 pnpm install → tests → commit。merge SHA 也会显示在 GitHub 的 PR 页面上(Merged commit <sha>)。
合并长期没有进展时,改用 link:
如果 PR 等待 review 后一直没有进展、没有 reviewer,或 main 正在改造而无法合并等情况持续 1-2 周以上,请切换到 link:,继续本地开发:
{
"dependencies": {
"<pkg>": "link:../../ghq/github.com/<owner>/<repo>"
}
}
这段时间,上游即使在其他 branch 上进行 hack 也不会相互影响。请注意,lockfile 不会记录 SHA,因此可复现性会隐式依赖 ghq 的 HEAD(在团队共享的 repo 中需要另寻方案)。
自动化的可能性
可以设置一个 agent,通过 /schedule 在「2 周后,如果 PR 已合并,就将下游的 specifier 改为 main HEAD SHA 并提交」,这样就不会忘记回收等待合并的修改。对于合并时间难以预测的 PR,这尤其有效。
检查清单
提交 PR 的一方:
- 将
dist/纳入 git 跟踪(包括 tsc 输出) - 在
.gitattributes中设置dist/** linguist-generated=true和-diff - 在 PR 正文中说明「已确认下游的 install 运行正常」
- (如有需要)也添加
"prepare": "tsc"
下游(consumer)一方:
- 使用完整的 40 位 SHA 固定版本(
github:owner/repo#<full-sha>) - pnpm v10 中,如果包包含
prepare,则将其添加到onlyBuiltDependencies - 执行
pnpm install→ 确认dist/存在 - 运行 tsc / tests / 实机验证
- 在 PR 合并前固定使用此 SHA
反面模式
- 使用分支名固定版本(
#fix/foo)—— rebase 会导致 SHA 变化,完全无法复现 - 使用短 SHA 固定版本(
#abc1234)—— GitHub codeload 会返回 404 - 长期使用
link:等待合并(有意暂时切换过去是可以的,但不要忘记 lockfile 依赖 ghq HEAD) - 依赖上游的
preparescript,却不将dist/纳入 git 跟踪(会被 pnpm v10 的 allowlist 卡住,用户体验也会变差)