상황
리뷰어가 승인을 보류한 채 조건을 하나 건다. 이 PR의 정확한 head 커밋에서 패키지 전체 점검 명령을 돌린 결과를 보여 달라는 것이다. 정직하게 하려면 몇 주째 작업하던 체크아웃이 아니라, 그 커밋으로 새로 만든 워크트리에서 돌려야 한다. 그래서 새 워크트리를 만들고, 의존성을 설치하고, 점검을 실행한다.
먼저 터진 것
점검이 변경 내용을 들여다보기도 전에 두 가지가 실패했다. 설치 단계에서 네이티브 터미널 모듈을 소스에서 빌드하려다 prebuild 스크립트가 깨졌다. 그걸 우회하자 이번에는 점검 자체가 파일 하나가 없다며 멈췄다. 프로젝트가 별도 스크립트로 만들어 내고 ignore 파일로 버전 관리에서 빼 둔 문서 인덱스 파일이었다. 두 실패 모두 PR과는 아무 관계가 없었다.
오래된 체크아웃이 그걸 숨긴 이유
평소 쓰는 체크아웃에는 지금까지 만든 생성물이 전부 쌓여 있다. 그 파일들은 무시 대상이라 git status는 깨끗하게 나오고, 그런 파일이 있다는 사실을 아무것도 알려 주지 않는다. 거기서 깨끗한 상태란 "추적 중인 변경이 없다"는 뜻이지 "새로 clone한 것과 같다"는 뜻이 아니다. 빠진 단계는 새 워크트리에서 처음으로 드러난다.
통한 절차
lockfile을 바꾸지 못하게 한 채 그대로 설치하고(--frozen-lockfile), 점검에 네이티브 모듈 빌드가 필요 없다면 lifecycle 스크립트를 건너뛰고(--ignore-scripts), 무시된 파일을 만드는 프로젝트 자체의 생성 단계를 돌린 다음, 점검을 실행한다. 이 순서로 하자 정확한 head에서 점검이 exit 0으로 끝났다. 스크립트를 건너뛰는 건 의도된 교환이다. 점검이 정말로 네이티브 빌드에 의존한다면 그 단계는 다시 넣어야 한다.
무엇을 남길 것인가
종료 코드만 남기지 말고 절차를 증거 옆에 함께 적는다. 커밋, 설치 플래그, 생성 단계, 그리고 변경이 건드리지 않은 파일에서 점검이 출력한 경고까지. 그래야 리뷰어가 진짜 실패와 환경 차이를 구분할 수 있고, 다음 번 새 실행이 같은 두 문제를 처음부터 다시 발견하지 않는다.
확인 방법
보고하기 전에 워크트리가 요청받은 커밋에 있는지, git status가 깨끗한지, 생성 파일이 절차 때문에만 존재하는지 확인한다. 점검이 실패하면 먼저 그 실패가 변경에서 온 것인지 환경 준비에서 온 것인지 묻는다. 리뷰 지적이 되는 건 앞의 경우뿐이다.
The situation
A reviewer holds an approval until someone shows the package's full check command run against the exact head commit of a pull request. The honest way to do that is a brand-new worktree checked out at that commit, not the checkout you have been working in for weeks. So you create one, install dependencies, and run the check.
What broke first
Two things failed before the check ever looked at the change. The install step tried to build a native terminal module from source and broke in its prebuild script. Once that was worked around, the check itself stopped on a missing file: a documentation index that the project produces with a separate script and that the ignore file keeps out of version control. Neither failure had anything to do with the pull request.
Why the old checkout hid it
Your everyday checkout has accumulated every generated artifact you ever produced. Because those files are ignored, git status stays clean and nothing tells you they exist. A clean status there means "no tracked changes", not "identical to a fresh clone". The fresh worktree is the first place the missing step becomes visible.
The recipe that worked
Install from the lockfile without letting it change (--frozen-lockfile), skip lifecycle scripts when the check does not need the native module's build (--ignore-scripts), run the project's own generation step for the ignored files, and only then run the check. In that order the check exited 0 on the exact head. Skipping scripts is a deliberate trade: if a check genuinely depends on a native build, that step has to come back.
What to record
Record the recipe next to the evidence, not just the exit code: the commit, the install flags, the generation step, and any warnings the check printed in files the change did not touch. Then a reviewer can tell a real failure from an environment gap, and the next fresh run does not rediscover the same two problems from scratch.
How to confirm
Before reporting, confirm that the worktree sits at the requested commit, that git status is clean, and that the generated file exists only because the recipe made it. If the check fails, first ask whether the failure comes from the change or from the setup. Only the first one is a review finding.
场景
评审者暂缓批准,提出一个条件:要看到在这个拉取请求的确切 head 提交上运行整个包的检查命令的结果。老老实实地做,就该用一个基于该提交新建的工作树,而不是你已经用了好几周的那个检出目录。于是你新建工作树、安装依赖、运行检查。
先坏掉的东西
检查还没开始看改动,就已经失败了两次。安装步骤试图从源码构建一个原生终端模块,结果在它的 prebuild 脚本里出错。绕过这一步之后,检查本身又因为缺少一个文件而停下:那是一个文档索引文件,由项目用单独的脚本生成,并被忽略文件排除在版本控制之外。这两次失败都和拉取请求毫无关系。
为什么旧的检出目录把它藏住了
你日常使用的检出目录里,堆积着你生成过的所有产物。这些文件被忽略,所以 git status 一直是干净的,也没有任何东西提醒你它们的存在。在那里“干净”只表示“没有被跟踪的改动”,而不是“和全新克隆完全一样”。缺失的步骤要到全新工作树里才第一次显现出来。
行得通的步骤
按锁文件安装且不允许它被修改(--frozen-lockfile);如果检查不需要原生模块的构建,就跳过生命周期脚本(--ignore-scripts);运行项目自带的生成步骤,把被忽略的文件生成出来;最后再运行检查。按这个顺序,检查在确切的 head 上以 0 退出。跳过脚本是有意的取舍:如果某项检查真的依赖原生构建,那一步就必须加回来。
该记录什么
不要只记退出码,要把步骤和证据放在一起:提交、安装参数、生成步骤,以及检查在改动没有触及的文件里输出的警告。这样评审者能分清真正的失败和环境差异,下一次全新运行也不必从头再踩一遍同样的两个坑。
如何确认
报告之前,确认工作树位于被要求的那个提交上,git status 是干净的,而且生成文件之所以存在,只是因为执行了这套步骤。如果检查失败,先问清楚失败来自改动还是来自环境准备。只有前者才算评审发现。
状況
レビュアーが承認を保留し、条件をひとつ付ける。このプルリクエストの正確な head コミットで、パッケージ全体のチェックコマンドを実行した結果を見せてほしい、というものだ。誠実にやるなら、何週間も使ってきたチェックアウトではなく、そのコミットで新しく作ったワークツリーで実行するべきだ。そこで新しいワークツリーを作り、依存関係を入れ、チェックを実行する。
先に壊れたもの
チェックが変更を見る前に、二つの失敗が起きた。インストール手順がネイティブのターミナルモジュールをソースからビルドしようとして、その prebuild スクリプトで壊れた。そこを回避すると、今度はチェック自体がファイルが一つ足りないと言って止まった。プロジェクトが別のスクリプトで生成し、ignore ファイルでバージョン管理から外しているドキュメントのインデックスファイルだった。どちらの失敗もプルリクエストとは何の関係もなかった。
古いチェックアウトがそれを隠していた理由
普段使っているチェックアウトには、これまでに作った生成物がすべて溜まっている。それらは無視対象なので git status はきれいなままで、存在を知らせてくれるものは何もない。そこでの「きれい」は「追跡中の変更がない」という意味であって、「新しく clone したものと同じ」という意味ではない。抜けている手順は、新しいワークツリーで初めて見えるようになる。
うまくいった手順
lockfile を変更させずにそのままインストールし(--frozen-lockfile)、チェックにネイティブモジュールのビルドが要らないなら lifecycle スクリプトを飛ばし(--ignore-scripts)、無視されているファイルを作るプロジェクト自身の生成手順を実行し、最後にチェックを実行する。この順番で、正確な head でチェックは exit 0 で終わった。スクリプトを飛ばすのは意図した取引だ。チェックが本当にネイティブビルドに依存しているなら、その手順は戻さなければならない。
何を残すか
終了コードだけでなく、手順を証拠の隣に書き残す。コミット、インストールのフラグ、生成手順、そして変更が触れていないファイルでチェックが出した警告まで。そうすればレビュアーは本物の失敗と環境の差を見分けられるし、次の新しい実行が同じ二つの問題を一から見つけ直すこともない。
確認方法
報告する前に、ワークツリーが求められたコミットにあること、git status がきれいなこと、生成ファイルが手順によってだけ存在していることを確かめる。チェックが失敗したら、まずその失敗が変更から来たのか、環境の準備から来たのかを問う。レビューの指摘になるのは前者だけだ。