github actionでvercelにdeployした時につまづきとわかったこと
経緯
Projectのメンバーを追加せずにデプロイできるようにしたかったため。
Vercelはpublicなリポジトリならお金かからないが、Organizationとか複数の人を入れる場合は一人あたり20ドル払わないといけない。それを回避するため一人のトークンでうまいことやるためにGithub Actionでデプロイさせたかった。
それを試しているうちにいくつかつまづきとわかったことがあったのでまとめておく。
Prismaのクライアントでエラーが出る
https://vercel.com/guides/how-can-i-use-github-actions-with-vercel
上記のGithub Actionでvercelにデプロイするのを試していて、Vercelにあげたあとprismaで以下エラーが出ていた。
prismaのgenerateはうまくいっていて、ローカルでは正しく動いているのにVercelにあげるとエラーになる。
code:error
Unhandled Rejection: Error PrismaClientInitializationError: Prisma Client could not locate the Query Engine for runtime "rhel-openssl-3.0.x".
This happened because Prisma Client was generated for "debian-openssl-1.1.x", but the actual deployment required "rhel-openssl-3.0.x".
Add "rhel-openssl-3.0.x" to binaryTargets in the "schema.prisma1" file and run prisma generate after saving it:
generator client {
provider = "prisma-client-js"
binaryTargets = "native", "rhel-openssl-3.0.x"
}
The following locations have been searched:
/var/task/apps/web/.next/server/chunks
/var/task/apps/web/.next/server
/home/runner/work/project/node_modules/.pnpm/@prisma+client@5.22.0_prisma@5.22.0/node_modules/@prisma/client
/var/task/apps/web/.prisma/client
/tmp/prisma-engines
at za (/var/task/apps/web/.next/server/chunks/570.js:66:756)
at async Object.loadLibrary (/var/task/apps/web/.next/server/chunks/570.js:113:10040)
at async _r.loadEngine (/var/task/apps/web/.next/server/chunks/570.js:114:448)
at async _r.instantiateLibrary (/var/task/apps/web/.next/server/chunks/570.js:113:12506) {
clientVersion: '5.22.0',
errorCode: undefined
}
Node.js process exited with exit status: 128. The logs above can help with debugging the issue.
原因
おそらくは実行環境によって適切なQuery Engineを生成できていないことが原因(GIthub Actionの環境で作ってVercelの環境じゃないから)
わかったこと
vercel deploy単体を実行するとファイルをvercel側にアップデートしてinstall, build, deployをしてくれる。
これは動く
しかし、Github Actionの例だとbuildしてvercel deploy --prebuiltでそのままVercelに送ってデプロイする。
この場合は動かない
そのため、おそらくはGithub Actionの環境でprisma generateする際にprismaはgithub actionの実行環境のQuery Engineを生成しそれをVercelで使おうとするため動かないのだと思われる。
解決策
シンプルにエラーに表示されている対応策のように以下を追加してあげれば動く。
code:schema.prisma
generator client {
provider = "prisma-client-js"
binaryTargets = "native", "rhel-openssl-3.0.x"
}
Github Action上でinstallさせるならinstall commandは空に
何も設定してないとvercel build時にはdefaultのinstall commandが走る
明示的に空文字を入れておいて拒否すればGithub Actionでキャッシュしてinstallできる。
こんな感じに分けておいてVercel側の設定でinstall commandにから文字を入れればskipできる。
code:production-workflow.yaml
- name: Install dependencies
run: pnpm install --frozen-lockfile
...
- name: Build Project Artifacts
run: vercel build --token=${{ secrets.VERCEL_TOKEN }}
Vercelのpnpmとversionが違うとかでfrozen-lockfile失敗したりしないんかね。
pnpm installは--prodはbuildできないので使えない
pnpm installする時はdeployするので--prodでinstallしてしまってもいいんじゃと思ったが、あとのturbo run buildでbuildするためにdevDependenciesが必要なのでやる必要なかった。
というか最終的にoutputで生成したものをそのまま渡すのであんまり意味ないかも、node_modulesの大きさが気になるなら実行にうつしてはないがbuildした後に再度--prodをつけてinstallし治せばいいんじゃないかな。しらけど
vercel deployした後のsourceみる限りなんか必要なパッケージのみがデプロイされてる感じあるのであんまり気にしなくてもいいのかなと思ったり。
Github Action Deployだけで動かせるのか?
deployだけ打つとローカルのプロジェクト(linkされてるもの)全てをVercelに送ってVercel側でinstall, build, deployしてくれる。
そこで思ったのだが、github action上でbuildとかせずにいきなりdeployしても動かせるんではということ
vercel deploy --prebuiltだと成果物とかだけアップロードするので早いってメリットはあるけど、deploy単体でもできるのでこの場合のメリットってなんなんだろうか
WARN! Build not running on Vercel. System environment variables will not be available.
https://vercel.com/docs/environment-variables/system-environment-variables#automatically-expose-system-environment-variables
Github Actionでbuildした場合warn出てるけど、VercelでbuildしないからVERCEL_ENVみたいな環境変数は使えないとかでbuildもvercelに任せれば環境変数取得できたりできそう?
でもあくまでbuild時のみってwarnだしVERCEL_ENVとかruntimeで取得できる環境変数だからdeployをVercelでやっている以上は取れるんじゃないかな?
vercel deployだけだと今のファイル全てをvercelに送ってvercel側でbuild deployする感じな気がする。
なので、成果物のみをuploadするのとプロジェクト全てをアップロードしてからビルドするだと少し時間がかかる気がしている。(測ってはない。)
turbo使っているとかならキャッシュできるけど、使ってなくても勝手にvercel側でキャッシュしているのかな?
ただdeploy単体で動かした場合ちょっと時間かかってる気もする。(体感)
そうなってくるとbuildしてprebuiltを使ってdeployするのが便利なのかも。
vercelコマンド単体でdeployできるけど、基本的にcliからdeployを走らせられるって機能を使ってるだけでprebuiltをつける場合は好きに処理した結果を渡せるぐらいでいいかもな。別にどっちがいいとかどっちを使うべきかっていうよりかはどう使いたいかな気がする。
vercelにdeployした後のファイルがどうなっているのか知らないからなんともわからん。
開発環境用のenv設定teamに入ってないとpullできないから意味なかった
vercel env pullするとlinkできたら環境変数を取得できる。
とはいえTeamに招待されてるユーザーじゃなければログインできないならやっても意味ないんじゃないか?
もちろん--tokenをcliで渡せば取得できるけど、個人的には何も渡さなくてもpullすればすぐ開発できるを想像してたのでちょっと残念。
課金しろよって話ではある。
env pullは開発する時とかに.env.localを取得してすぐに開発できるようにするみたいな感じ
vercel pullとの違いはvercel buildする時に環境変数やビルドスクリプトを取得してビルドするだけで.envを用意するわけではない。
neonの自動branch統合がgithub actionでデプロイしていると使えない
課題:Vercelとneonをmarket placeからinstallして連携したがPR立てた時にbranchはできるがmigrationの実行がmainブランチに対して行われてしまっている。
原因:github actionでvercel pull, vercel buildしたのちvercel deploy --prebuiltのフローだとbranchごとのdbの環境変数になっていなさそう。
vercel統合を使っているとpreview環境作る時にdbのbranchはちゃんと自動で作ってはくれる。
ただ、vercel pullした際の環境変数はビルド単位で設定された環境変数(あってるのか?)ではないため、mainブランチに対してのdb urlしか取得できてない気がする。
そもそもgithub actionを使わずVercelのみで行っている場合、ビルド時にdb urlが切り替わっているかどうかってのは試してないため分からないので本来のフローでpreviewのbranchのurlが入っているのかは謎。
対応策:
1. vercel側でbuild deployさせればおそらくは解決しそう(試してない)
2. branchの自動作成等もgithub actionで行うかかなー。
2でやることにする
そうなってくるとvercelと統合ではなくneon自体独立させてdb urlのみ管理できるようにしようかなーと思う。
おとなしく、github actionでbranch作るの方が簡単そう
https://github.com/neondatabase-labs/preview-branches-with-vercel/blob/main/.github/workflows/deploy-preview.yml
その他関連
vercel cliのコマンドの動作検証