Azure Web サイトに用意されている .deployment ファイルを使った Custom Deployment Scripts がどのように実装されているのか気になったのと、Ruby 周りが行き詰っていたので調べてみました。
結論から書いてしまうと、単純に Git に用意されているサーバーサイドフックを使って実現されていました。
サーバーサイドフック
クライアントサイドフックの他に、いくつかのサーバーサイドフックを使うこともできます。これは、システム管理者がプロジェクトのポリシーを強制させるために使うものです。これらのスクリプトは、サーバへのプッシュの前後に実行されます。pre フックをゼロ以外の値で終了させると、プッシュを却下してエラーメッセージをクライアントに返すことができます。つまり、プッシュに関するポリシーをここで設定することができるということです。
Git - Git フック
以上、終わり。
だと流石に中身が無いので、実際にどのようなに実行されているのか調べました。
デプロイ時の処理の流れ
Kudu は git push されると内部で git.exe を使ってコミットを取得します。思っているよりもいろいろと複雑なことをしてますが、とりあえず Process Explorer から実行時の引数を拾ってきました。
この時に git が処理完了のタイミングで hooks/post-receive フックを起動します。
sh.exe を使ってフックの処理を実行します。
そして post-receive フックでは何をやっているかですが、基本的には kudu.exe をさらに実行します。
#!/bin/sh read i echo $i > pushinfo "$KUDU_EXE" "$KUDU_APPPATH" "$KUDU_MSBUILD" "$KUDU_DEPLOYER"
kudu.exe は実際に Git リポジトリから wwwroot へのデプロイを行うためのアプリケーションで、ASP.NET アプリケーションの場合には MSBuild を起動してコンパイルを行ったりしています。
その kudu.exe が内部で .deployment を読み込んで、実際のデプロイスクリプトの実行を行っています。ちなみに ASP.NET や Node.js アプリケーションだけを Git でデプロイした場合にも、内部的にはそれぞれのプラットフォーム向けにデプロイスクリプトが作成されています。
そしてデプロイスクリプトは starter.cmd というバッチファイル経由で実際に実行されます。
@%*
starter.cmd の中身は、引数に渡されたコマンドを実行するだけのシンプルなものです。
.deployment で bash deploy.sh に書くと、cmd.exe の下に bash.exe が作られることになります。
そんなこんなの流れによって、プロセスのツリーが大変なことになる訳です。
ちなみに管理ポータルから再デプロイを実行した場合には git 周りが大幅にスキップされるのと、Kudu の管理下で実行されるので starter.cmd からになります。