Git hook (post-receive) による継続的デプロイメント
#git #deployment
このページでは、 post-receive の使い方を記載する。
Git hooks と post-receive の概要
Git hooks (日本語 ) 機能を利用することで、いくつかの git 操作の前後にスクリプトを実行できる。
この post-receive hook は git push の受け取り (receive) が完了すると発火されるものである。
post-receive にデプロイ処理を記述しておくことで、 git push された内容を継続的にデプロイすることが可能である。
前提: git push する側、される側の準備
git push する側
git push を行う remote repository の登録が必要。
ssh 経由で push する場合は以下:
git remote add <remote name> ssh://<user>@<address>:<path to repository>
git push される側 (受け取り側)
デプロイされる側も Git リポジトリが必要である。受け取り側のマシンで git init しておく。
その後、 .git/hooks/ ディレクトリの配下に post-receive ファイルを作成する。
例:
git init
$EDITOR .git/hooks/post-receive
例: HM0008 のデプロイにおける post-receive の利用
HM0008 のホスティング に関するリポジトリの post-receive では以下を実施した。
- working tree の更新 (push された内容の checkout)
- 必要なデプロイ操作: markdown ファイルを html ファイルへ変換、 systemd サービスのリロードなど
working tree の更新:
unset GIT_DIR
unset GIT_WORK_TREE
unset GIT_INDEX_FILE
unset GIT_QUARANTINE_PATH
# ----------------------
# DEPLOY
# ----------------------
# checkout the latest states
echo "Checking out latest default branch..."
for dir in $SCRIPT_DIR $COMPILER_DIR $QUADLET_CONFIG_DIR $MARKDOWN_DIR; do
echo "- $dir"
git -C $dir checkout -f default || exit 1
done
echo "DONE"
echo
メモ:
- hook 実行時に、いくつか環境変数が設定される (
GIT_DIRなど) 。 hook 内で git 操作をする場合には考慮が必要。- 今回はそれらを
unsetしている
- 今回はそれらを
コンパイラや、 markdown ファイルのリポジトリに git push された場合:
echo "Building sinter..."
pushd $COMPILER_DIR
cargo build --release --quiet || exit 1
echo "DONE"
echo
# recreate target directory
rm -r $HTML_TARGET_DIR
mkdir -p $HTML_TARGET_DIR
echo "Compiling markdown files..."
# compile markdown files to html
cargo run --release \
--quiet \
-- \
--input $MARKDOWN_DIR \
--output $HTML_TARGET_DIR \
--templates $COMPILER_DIR/templates \
--config $CONFIG_FILE || exit 1
popd
systemctl --user restart zettel-pod.service || exit 1
echo "DONE"
echo
pod ファイルも git push でデプロイしている:
echo "Updating unit files..."
# copy unit files
cp -v $QUADLET_CONFIG_DIR/*.pod $SYSTEMD_DIR || exit 1
cp -v $QUADLET_CONFIG_DIR/*.container $SYSTEMD_DIR || exit 1
echo "DONE"
echo
echo "Reloading systemd services..."
# reload systemd
systemctl --user daemon-reload || exit 1
systemctl --user restart zettel-pod.service || exit 1
echo "DONE"
echo
メモ
pre-receiveを使うと、 push 前に CI に相当する操作もできそうpre-receiveやpre-commitでは、exit 1(正確には、 0 以外の exit status でスクリプトを終了) することで、 push / commit を abort できるようだ
#public