turborepoを使ったVercelのプロジェクト内でワークスペース毎にbuildをスキップしたい!
対象者
- monorepoの各ワークスペースをVercelにそれぞれ別のプロジェクトにデプロイしている
- turborepoを使っている
- プロジェクトの無駄なデプロイを防ぎたい!
やりたいこと
monorepo構成のアプリケーション群をVercelにデプロイしているときに、それぞれのワークスペースごとに別々のプロジェクトを作ってデプロイしていると思います。
VercelのGithubインテグレーションを使っていると、1つのワークスペースのみ修正しpushすると他のパッケージも全てデプロイが走ってしまうので、無駄にデプロイをしてしまうなんてことが起きると思います😭
VercelにはIgnored Build Stepという機能があります。
build実行時に最初にIgnored Build Step記載したコマンドを実行し、exit 0
ならばbuildを行わない=デプロイを行わない ようにできます。
例として記載されている git diff --quiet HEAD^ HEAD ./
は直前のコミットと現在のディレクトリの中の差分を検知して0か1を返却してくれます。
しかしmonorepo構成の場合、他のパッケージに依存していてそのパッケージのみ修正されていた場合にデプロイされず、いつまで経っても古い状態のままになってしまいます。
どうしようかなー、、、と思っていたところ、まさしくドキュメントに書いてありました
If you are using Turborepo, you can set the Ignored Build Step to npx turbo-ignore to automatically detect if your project or one of its dependencies has changed and needs to be built and deployed.
turbo-ignore
turbo-ignoreを使えと書いてあります。
turbo-repoは親コミットから現在のコミットへの変更を検索し、影響を受けるパッケージを特定してくれるそうです。
内部で turbo run build --dry
を実行しているらしく、turbo.jsonで指定したoutputs等もちゃんと見た上でbuildの必要があるかないかを判断してくれます。
mopnorepoのプロジェクトをVercelにデプロイしている場合は、このコマンドを入れておくと良さそうです!
(ご利用は計画的に)
npx turbo-ignore
自体はコマンドなのでローカルや他のホスティングサービスやGithub ActionsやCircleCI等でも使えます。
VercelにはデプロイしていなくてCICDツールで自動デプロイをしている場合や、一部のワークスペースをnpmパッケージとして保存している場合、なんか他に特定の処理を行っている場合等にも、使えるとおもいます。
ぜひ一度試してみてください!
Tips
fallbackオプション
npx turbo-ignore --fallback=<ref>
turbo-ignoreには fallback
オプションを指定出来ます。
Vercelではデフォルトで、そのブランチの以前のデプロイが存在しない場合にはそのままデプロイを行うようになっているみたいです。
そのため、新ブランチをpushした際にデプロイの必要性がないプロジェクトもデプロイされてしまいます。
--fallbackオプションを指定すると、以前のデプロイが存在しない場合の挙動を指定出来ます。(デフォルトではNone)
例のようにnpx turbo-ignore --fallback=HEAD^
としてあげると、親コミット(HEAD^)と比較するようになりますので、無駄なデプロイを減らすことができます。
READMEにはVercel以外では常にHEAD^をみるようになっているそうなので、上記のようにCI等で使う際は指定しなくても良さそうです。
Ignored Build Stepに指定する際にはなるべくfallbackオプションをつけておくといいでしょう。
まとめ
Vercelの各プロジェクトページ → Settings → Git → Ignored Build Stepに npx turbo-ignore ${ワークスペース名}
を設定するとbuildコマンドの依存関係を見てbuildの必要がなかった場合デプロイをスキップしてくれる。
npx turbo-ignore
自体はコマンドなのでGithubActionsやCircleCI等でジョブをスキップしたい時などにも使える。
Discussion