GitHub Actions内でPostgresを起動しつつ、起動するまで待つ
やりたいこと
GitHub Actions内でテストを実行する都合上、DBを起動したいです。DBにはPostgresを使います。
ざっくり以下のような感じでActionsを作っていきたいと思ったわけです。
docker compose up db -d
docker compose exec db psql -c "テストデータを入れるSQL"
- テスト実行
docker compose down
しかし、2でまだDBが起動しとらんよ、というエラーが発生し、こけてしまったのでした。
そこで、DBが起動するまで待つ処理を頑張って編み出したので紹介します。
やりかた
まずは答えです。
あとで、それぞれやっていることを解説します。
- name: Up db and wait for ready
run: |
docker compose up db -d
set +e
for (( i=0; i<10; ++i )); do
docker compose exec db pg_isready
if [ $? -eq 0 ]; then
break
fi
sleep 1;
done
DBが起動しているかを調べる
pg_isready
というコマンドがあります。こいつは、Postgresがreadyかどうか調べてくれる大変スグレモノです。
docker compose exec db pg_isready
を実行すると、DBが起動していればEXIT STATUS=0になりますし、起動していなければEXIT STATUS=2になります。
コマンドのオプションに --timeout
というのがあるのですが、少なくとも今回の用途には使えませんでした。起動していない場合は何を指定しても、 no response
と出て一瞬でエラーになります。最低限コネクションは張れる前提ということなんでしょうか。
起動するまで待つようにする
タイムアウトが効かないのであれば、DBが起動するまで pg_isready
をポーリングすればよいでしょう。無限ループにならないようにforループを使います。
しかし、これだけだと、GitHub Actionsでは使えません。ステータスコードが0以外になった瞬間にGitHub Actionsはエラーになって終了してしまいます。
GitHub Actionsでエラーになっても終了しないようにする
set +e
を使います。 set -e
はスクリプトが途中でエラーになったら以降処理を行わない、という意味ですが、それの逆をやってくれるコマンドです。
GitHub Actionsではデフォルトで set -e
が有効になっているため、 set +e
で無効にしてあげる必要があります。
まとめ
Postgresが有効になるまで待つためにいろいろ引っかかったのですが、解決方法がググっても出てこずわりと困りました。
ChatGPTに聞いて set +e
で回避できることを知るなどしました。
以上です。よろしくお願いします。
Discussion