Git フック で継続的インテグレーション

Git を長期的に使用している方は、おそらく Git フック という名前を耳にしたことがあるかもしれません。また、Git フックを少し使用したこともあるかもしれません。Git フック は、継続的インテグレーションを行う上でとても素晴らしいものです。そこで、今回は継続的インテグレーション関連のユースケースを 3 つと、ワークフローに追加可能な既存のフックをいくつか紹介したいと思います。Git フック をご存じない方も、基本から始めますのでご心配はいりません。

Git フック とは

フックとは、コミットやマージなどの操作の前後でカスタムスクリプトを起動するために Git に備わっている仕組みです。Git のプラグインシステムと考えてください。Git リポジトリの .git ディレクトリ内を見てみると、「hooks」という名前のディレクトリが見つかります。この中に、フックスクリプトのサンプルセットが入っています。

Git hooks for continuous integration: .git directory

Git フックのインストールは単純で、ドキュメントも揃っていますので、ここでは省略します。

フックは 2 つの大きなクラスに分けられます。クライアントサイドとサーバーサイドです。クライアントサイドフックはローカルの端末で動作し、サーバーサイドフックは Git サーバーで動作します。

また、フックを pre- または post- フックに分類することもできます。pre-receive フックは何らかの git 操作の前に実行され、必要に応じてオプションでキャンセルすることもできます。そのフックは、ユーザーやチームメイトが誤ってコードをコミットしないようにリポジトリを守る働きがあります。post-receive フックは操作が完了した後に動作します。そのためキャンセル用のオプションはありません。その代わりに、post-receive フックは開発ワークフローの一部を自動化してくれます。

Git フックを使うことは、何でも思い通りに動く小さなロボットを子分に持つようなものだ (ワッハッハッ!)


Git フックは以下の自動化を行います。

  • コミットメッセージ内に関連する課題のキーが含まれているか確認する
  • マージの前提条件を実施する
  • チームのチャットルームに通知を送る
  • 他のブランチに切り替えた後にワークスペースをセットアップする

Server- and client-side git hooks for continuous interation

フィーチャーブランチでクリーンビルドを実施する

サーバーサイドの pre-receive フックは、継続的インテグレーションにとって特に強力なものになります。コードが特定の条件を満たさない限り、開発者がマスターにコードをプッシュすることを防ぐからです。優秀な忍者が護衛しているように、悪いコードから守ってくれます。

開発者は大抵の場合誠実なので、ブランチでテストが上手くいかない場合はマスターにマージしません。しかし、ときにはチェックを忘れることがあります。あるいは、他の人とブランチを共有するとき、最後にブランチのビルドなどをチェックしたあとに多くの変更が行われることがあります。

そこで私たちは、マスターへのマージを調べるサーバーサイドフックを追加しています。そのフックがマージを発見すると、スクリプトがブランチ上の最新のビルドをチェックして、テストの失敗がある場合はマージを拒否します。私の同僚とアトラシアンの開発者 Tim Pettersenそのためのスクリプトを書きました。これは Bamboo と併せて動作し、Bitbucket 上で利用可能となっています。皆さんもこれを入手し、カスタマイズしてリポジトリに追加することができます。

苦労して確保したコードカバレッジを保護する

私はこれまで、多くのチームがコードカバレッジの維持で苦労している姿を見てきました。テストで何度も遡ってコードベースをカバーしなければならず、テストが強化されないまま多くの機能が追加されることで、苦労して確保したカバレッジが失われていくのはストレスがたまります。そこで Tim は、コードカバレッジが失われないようにマスターを保護する pre-receive サーバーサイドフックも書きました。

Sample git hooks for continuous integration

このフックはマスターへのマージも調べ、継続的インテグレーションサーバーにコールアウトすることでマスター上の現在のコードカバレッジとブランチ上のカバレッジをチェックします。ブランチのカバレッジが低下する場合、マージは拒否されます。

多くの継続的インテグレーションサーバーは、リモート API 経由でコードカバレッジデータを公開しません。そこでこのスクリプトがコードカバレッジレポートを明らかにします。これを行うには、マスターとブランチビルドの両方でレポートを発行するようにビルドを設定する必要があります。レポートが発行されると、ユーザーは継続的インテグレーションサーバーにコールすることで、マスターから最新のカバレッジレポートを手に入れることができます。ブランチカバレッジについては、最新のビルド、またはマージされるリファレンス (コミット) に関連するビルドからカバレッジレポートを手に入れることができます。

誤解の無いように言っておくと、このフックは、ビルドの 1 つですでにコードカバレッジが確保されているものとみなしています。このフックが魔法のように機能するわけではなく、単にユーザーのビルド結果のカバレッジデータを調べるだけです。このフックはデフォルトで Bamboo と併せて動作し、さらに Clover (アトラシアンの Java と Groovy 用コードカバレッジツール) でも動作します。また、カスタマイズすることで、他のビルドサーバーやコードカバレッジツールと統合することも可能です。

ブランチビルドのステータスをチェックする

なぜなら、友人であれば、その友人に壊れたブランチをチェックアウトさせることはないからです。

ここにクライアントサイド Git フックで遊ぶチャンスがあります。ユーザーのターミナルウインドウ内でビルドステータスを表示する ost-checkout フックスクリプトも Tim が作りました。このスクリプトは、ブランチのヘッドリビジョン番号をローカルコピーから取得し、継続的インテグレーションサーバーにクエリを発行してそのリビジョンがビルドされたかどうかを調べ、もしビルドされていればそのビルドが成功したかどうかを調べます。

Client-side git hooks for continuous integration

マスターからブランチを作りたいですよね。このフックはマスター上の head コミットが正常にビルドできかたどうかを教えてくれます。つまり、「安全な」コミットでフィーチャーブランチを作成するということです。また、リビジョンのビルドが失敗したことをフックが伝える場合は、チームのウォールボードにそのブランチのグリーンビルドが表示されます (逆の場合も同様)。これは、ユーザーのコピーが古いことを意味します。最新版を取得するかローカルコピーを使って作業を継続するかはユーザー次第です。

アトラシアンの開発者は、このフックを使うことで、頭を痛めていた多くの問題から解放されました。ここで説明したサーバーサイドフックを採用するようにチームを説得できない方は、せめてローカルの端末にこれをインストールしてください。後悔はしないでしょう。

自動化でさらに便利に

ここで紹介した継続的インテグレーション用の Git フックはすべて、デフォルトで Bamboo、Clover、Bitbucket と併せてご利用になれます。また、Git フックはベンダーに依存しないことを忘れないでください。そのため、フックをカスタマイズしてお手持ちのどんなツールとも併せて使うことができます。

継続的インテグレーションに Git を使用する方法に興味がある方は、当社の最新マイクロサイト The Pipeline をご参照ください。こちらでは、JIRA、Bitbucket、Bamboo を使用して継続的デリバリーを行うことに焦点を当てています。継続的デリバリーに Git ワークフローを使用するヒントや、アトラシアンツールに接続して継続的デリバリーを行うための情報も豊富にご用意しています。

The Pipeline で継続的デリバリーについて学ぶ

 

この記事がお役に立ちましたか? ソーシャルネットワークでシェアして、Git フックを広めるお手伝いをしてください!



*本ブログは Atlassian Blogs の翻訳です。本文中の日時などは投稿当時のものですのでご了承ください。
*原文 : 2016 年 2 月 1 日 "Git hooks for continuous integration"