UID:
20260215180313
Created:
2026-02-15
Updated:
2026-02-15

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 では以下を実施した。

  1. working tree の更新 (push された内容の checkout)
  2. 必要なデプロイ操作: 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-receivepre-commit では、 exit 1 (正確には、 0 以外の exit status でスクリプトを終了) することで、 push / commit を abort できるようだ

#public