連載:Team Foundation Server 2008の下流工程への適用

第4回 チーム・ビルドによる開発の安定化

アバナード株式会社 安藤 大祐
2009/08/12
Page1 Page2 Page3

自動ビルドの効果と種類

 自動ビルドといっても、どのような効果を目的とするか、その狙いによってカスタマイズ方法は異なってくる。筆者が考える自動ビルドの狙いは、以下の3パターンだ。

  1. リリース・ビルドによる、ビルド負荷とリスクの軽減
  2. デイリー・ビルドによる、品質の“見える化”
  3. 継続的インテグレーションによる、品質リスクの軽減

1. リリース・ビルドによる、ビルド負荷とリスクの軽減

概要

 1つ目のパターンは、ビルド・プロセスの自動化である。例えば、企業向けのASP.NETカスタム・アプリケーションを作成しているとしよう。Webアプリケーションを配置する場合、一般的には、以下のようなビルド・プロセスが必要となる。

(1)ソース・コードの最新バージョン(=リリース対象となる正規のもの)を取得する
(2)アプリケーションのビルドと、Webサイトのプリコンパイル
(3)ステージング環境や本番環境など、配置する環境ごとにWeb.configを修正する
(4)今回のリリースで反映が必要となるデータベースの差分スキーマ(ALTER文など)を作成する
(5)用意したリリース・モジュールを、各環境へ配置する

 本稿でいうリリース・ビルドとは、これらの作業を自動化するためのものだ。といっても、通常は、リリース・ビルドしたタイミングでは本番環境に配置することはできないため(例えば夜間のメンテナンス時間中にしか配置を実施できない、など)、自動化の範囲は(1)から(5)の配置作業の直前までとなる。それでも、ファイルの配置処理やデータベースのDDL(Data Definition Language)実行処理(=レコード操作)を行うバッチ・ファイルを記述しておけば、属人的な作業はほとんど発生せず、リリース作業のリスクや工数は、大きく軽減される。

TFSでの実現方法

 リリース・ビルドは、ビルドが承認された段階で、手動で実行する。そのため、特にスケジュールの設定は必要なく、作成したビルドの定義を任意のタイミングで実行すればよい。

 ただし、チーム・ビルドのデフォルト機能で実現できる範囲は(1)と(2)だけである。それ以上のことを行う必要がある場合は、直接TFSBuild.projを修正し、そのスクリプトを記述する必要がある。筆者は、過去、ClickOnce、Reporting Service、SharePointアドオンといったアプリケーションのリリースをチーム・ビルドで自動化した経験があるが、その際も、直接それらスクリプトをMSBuildで記述している。

2. デイリー・ビルドによる、品質の見える化

概要

 2つ目のパターンであるが、TFSではチーム・ビルドや、バージョン管理、作業項目トラッキングなど、TFS上で発生したさまざまのアクティビティを集計・分析し、レポートとして可視化する機能を持っている。毎日決められた時間(例えば、毎日12:00など)に実行するデイリー・ビルドを構成することで、日々の進ちょく状況や、プログラムの品質を日次でトラッキングすることができる。

 ビルドを実施する際に収集可能な情報は、以下のようなものである。

  • ビルドの詳細(実行時間や、ビルド名、出力フォルダのパスなど)
  • ビルドに含まれる変更セット(変更されたソース・コード、関連付けられた作業項目)
  • コード・カバレッジの実行結果

 これらはビルドをするたびに収集される。従って、デイリー・ビルドを作成することは必須ではない。が、常に鮮度のよい情報を、一定のサイクルで蓄積することの価値は大きいと考えている。

TFSでの実現方法

 デイリー・ビルドの目的は情報の収集である。従って、リリース・ビルドのような複雑なビルドのカスタマイズは不要であり、チーム・ビルドの標準機能で実現可能である。スケジュールの設定は、ビルドの定義の「トリガ」で指定可能となっている。

3. 継続的インテグレーションによる、品質リスクの軽減

概要

 継続的インテグレーションとは、チェックインなどをトリガにして、頻繁に自動ビルドを実行するソフトウェア開発手法の1つである。

 ソース・コードがチェックインされるたび、プログラムのビルドや単体テスト、静的コード分析を実施し、新しいコード変更による予期せぬエラーや副作用を、即座に発見することを目的とする。

TFSでの実現方法

 デイリー・ビルド同様、継続的インテグレーションも、チーム・ビルドの標準機能で実現可能である。チェックインをトリガとするビルドのスケジュール設定や、自動ビルドの中での単体テスト、静的コード分析の実行といった機能を標準で備えている。

 継続的インテグレーションの注意点は、ビルドの時間である。チェックインをトリガとするため、常にビルドし続けている状態になる、といったことも十分想定できる。プロジェクトの速度にもよるのだが、基本的には継続的インテグレーションは行わず、品質チェックはデイリー・ビルドと統合する、という方針でも何の問題もない。

 以降では、本題であるビルドのカスタマイズについて、説明したい。

ビルド・プロセスのカスタマイズ

 前述のアーキテクチャでも説明したが、チーム・ビルドは、MSBuildのスクリプト・ファイル一式である。つまり、カスタマイズ方法とは、MSBuildのスクリプトを書くこととイコールで、具体的には、ビルドの定義ごとに作成されるTFSBuild.projファイルを修正すればよい。

 以下では、カスタマイズのポイントを説明する。

ビルドの構成のカスタマイズ

 まずは、チーム・ビルドで用意されている拡張ポイントについて説明しよう。

プロパティ値の変更

 チーム・ビルドでは、オーバーライド可能ないくつかのプロパティが用意されており、TfsBuild.projファイルでオーバーライドすることにより、既存のビルド処理をカスタマイズできる。

 下の表は、オーバーライド可能な主なプロパティの一覧である。

プロパティ名 概要 カスタマイズの用途
IncrementalGet このプロパティをtrueに設定することで、インクリメント方式の取得(=差分のみ取得)が実行される。このプロパティは、CleanCompilationOutputOnly=true、SkipInitializeWorkspace=true、ForceGet=falseに設定されていることと同義 ソース・コード量が多く、全ソースの取得に時間がかかる場合や、前回のビルド結果を保持したい場合に利用
IncrementalBuild このプロパティをtrueに設定することで、インクリメンタル・ビルドが実行される。このプロパティは、SkipClean=true、SkipInitializeWorkspace=true、ForceGet=falseに設定されていることと同義 ソース・コード量が多く、ビルドに時間がかかる場合や、前回のビルド結果を保持したい場合に利用
RunCodeAnalysis 静的コード分析を実行する設定。以下の3つの値が設定できる。
・Default:プロジェクトの設定に従う
・Always:常に実行
・Never:常に実行しない
静的コード分析の実行の設定変更が必要な場合に利用
RunTest 単体テストを実行するか否かを設定。trueの場合は、実行する 単体テストの実行の設定変更が必要な場合に利用
LabelName Labelタスクによって使用されるラベル名を定義できる。既定では、ラベル名はInitializeEndToEndIterationターゲット内の$(BuildNumber)に設定される ラベル名をより分かりやすいものへ変更したい場合に利用
BuildNumber 表示名やラベル名などに利用されるビルド番号を設定。既定の設定を変更したい場合は、BuildNumberOverrideTargetターゲットでプロパティを上書きする ビルド名をアセンブリ・バージョンと合わせるなど、より分かりやすいものへ変更したい場合に利用
LastGoodBuildNumber 最後に成功したビルド名。現在のビルドに関連付けられる変更セットや作業項目は、最後に成功したビルドとの差分になる 「最後に成功したビルド」の定義を変えたい場合に利用。例えば、「現在本番環境で稼働しているビルド」をLastGoodBuildNumberに設定することで、現在のビルドと、本番リリースされているビルドとの差分情報を取得できる。これにより、影響範囲の検討が簡単になる
SkipWorkItemCreation このプロパティをtrueに設定することで、CoreCreateWorkItemターゲットがスキップされ、ビルド失敗時に、作業項目が起票されなくなる ビルド失敗時の作業項目の起票が不要な場合
SkipDropBuild このプロパティをtrueに設定することで、CoreDropBuildターゲットがスキップされ、ビルド後の出力ファイルやログ・ファイル、テスト結果をリリース・サーバへドロップする処理が行われなくなる 独自のドロップ処理(=出力/配置処理)を行う場合
表1 オーバーライド可能な主なプロパティの一覧
TfsBuild.projファイルにプロパティを追加/修正することで、ビルド処理のカスタマイズが可能。

ビルド・プロセスの拡張(ターゲットの拡張)

 チーム・ビルドには、ビルド・プロセスの拡張用に空のターゲットが用意されており、TfsBuild.projファイル内の空のターゲットをカスタマイズして、さまざまなビルド・タスクを追加できる。

 一般的によく利用されると思われる拡張用ターゲットは以下のとおり。

ターゲット名 概要 カスタマイズの用途
BuildNumberOverrideTarget ビルド番号または格納場所に関連するプロパティをカスタマイズする場合は、このターゲットにタスクを挿入する。作成するタスクでは、BuildNumberという出力プロパティを作成する ・ビルド番号のカスタマイズ
BeforeCompile コンパイルの開始前に呼び出される ・別のワークスペースのモジュール(例えば、共通フレームワークなど)の最新バージョンを取得
・アセンブリ番号の更新
AfterCompile コンパイルが完了した後に呼び出される ・ビルド結果DLLを別のワークスペースに自動反映
BeforeTest テストの実行前に呼び出される ・単体テスト実行前準備
AfterTest テストが完了した後に呼び出される ・単体テスト実行後処理
GenerateDocumentation ビルド処理中にドキュメントを自動的に生成する場合は、このターゲットにタスクを記述する ・コード・ドキュメントの作成
PackageBinaries バイナリのパッケージを作成する場合は、このターゲットにタスクを記述する ・MSIパッケージの作成
・ClickOnceマニフェストの作成
AfterDropBuild ビルドしたバイナリ、ビルドのログ・ファイル、およびテスト結果をリリース・サーバにドロップした後に呼び出される ・配置のカスタマイズ(SkipDropBuild=trueであること)
表2 オーバーライド可能である、主な拡張用ターゲット一覧
TfsBuild.projファイルに、ターゲットを追加することで、ビルド処理のカスタマイズが可能。
Microsoft.TeamFoundation.Build.targetsファイルは変更しないこと。

カスタム・タスクの作成

 独自のタスクを作成して、チーム・ビルドを拡張できる。基本的なものであれば、前述のMSBuild Community TasksMSBuild Extension Packといったオープンソース・ライブラリに用意されている。しかし、より複雑なシステムや、独自の開発プロセスに沿ったビルドを行う場合には、既存のライブラリだけでは足りないケースも出てくるであろう。そんなときのためにも、カスタム・タスクの作り方を知っておくと便利だ。

 カスタム・タスクの作成方法は簡単で、ITaskインターフェイス(Microsoft.Build.Framework名前空間)を実装するクラスを(C#やVBで)記述し、TfsBuild.projファイルに登録すればよい。以下にコードのサンプルを示す。

public class SimpleTask : Task   
{
  [Required]   
  public string Name
  {
    get { return name; }
    set { name = value; }
  }

  [Output]   
  public string Value
  {
    get { return varValue; }
    set { varValue = value; }
  }

  public override bool Execute()   
  {
    ……省略……
    return true;
  }
}
カスタム・タスクの例
Microsoft.Build.Frameworkアセンブリへの参照が必要。
  Microsoft.Build.Utilities名前空間のTaskクラスを継承する(※Microsoft.Build.Utilitiesアセンブリへの参照が必要)。Taskクラスは、ITaskインターフェイスを実装して、基本機能を提供するヘルパー・クラス。
  プロパティ値を必須項目にしたい場合は、Required属性を付与する。
  出力項目(=MSBuildスクリプト側に渡す値)には、Output属性を付与する。
  Executeメソッドをオーバーライドし、タスクの実装を記述する。戻り値は、タスクが成功した場合はtrue、失敗した場合はfalseとなる。

 記述したコードをコンパイルして作成された.DLLファイルは、サーバやソース管理へ配置した後、次のように記述してビルド・スクリプトに登録する。

<UsingTask
    TaskName="MyTasks.SimpleTask"   
    AssemblyFile="MyAssembly.Build.Tasks.dll"/>   
<UsingTask>要素の例
カスタム・タスクとして作成した.DLLファイルを、このコード例のようにしてビルド・スクリプトに登録する。
  作成したカスタム・タスクのタスク名を設定。
  カスタム・タスクが含まれる.DLLファイルへのパスを設定。この例は、ソース管理上のTfsBuild.projファイルと同じディレクトリに.DLLファイルを格納しているケースを想定。

 以上がビルドのカスタマイズの基礎だ。次のページでは、その実例を示す。


 INDEX
  [連載] Team Foundation Server 2008の下流工程への適用
  第4回 チーム・ビルドによる開発の安定化
    1.チーム・ビルドのアーキテクチャ
  2.自動ビルドの効果と種類
    3.ビルド・プロセスのカスタマイズ

インデックス・ページヘ  「Team Foundation Server 2008の下流工程への適用」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間