mcpField
U
upstream-fix-and-pin

upstream-fix-and-pin

github.com/mizchi开发41656 次安装1 周前更新
代码仓库

关于 upstream-fix-and-pin

用于修复上游依赖并让下游开发继续进行的开发技能,涵盖提交补丁、用完整提交 SHA 固定依赖,以及评审延迟时切换到本地链接。

主要功能

  1. 01上游修复与 PR 流程
  2. 02用完整提交 SHA 固定依赖
  3. 03配置 pnpm v10 构建脚本白名单
  4. 04软件包产物与安装指引
  5. 05合并后更新固定版本及本地链接回退

适用场景

  1. 01修复等待合并时保持下游开发
  2. 02测试期间可复现地固定依赖补丁
  3. 03处理 Git 依赖的 pnpm v10 安装脚本
  4. 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 即可运行」,下游项目不能遇到问题。最低限度:

  1. 将 dist/ 纳入 git 跟踪(例如 tsc 输出)。将其从 .gitignore 中移除并提交。添加 .gitattributes,设置 dist/** linguist-generated=true 和 -diff,可以避免 PR review 时 diff 膨胀。
  2. (辅助措施)在 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)
  • 依赖上游的 prepare script,却不将 dist/ 纳入 git 跟踪(会被 pnpm v10 的 allowlist 卡住,用户体验也会变差)

评论

支持 Markdown