プッシュボタンリリース(^o^)

達人プログラマー―ソフトウェア開発に不可欠な基礎知識 バージョン管理/ユニットテスト/自動化 (Ascii software engineering series)

達人プログラマー―ソフトウェア開発に不可欠な基礎知識 バージョン管理/ユニットテスト/自動化 (Ascii software engineering series)

毎回のリリース作業の手順が繰り返し作業になってきたので、達人プログラマーの自動化のところに書かれているプッシュボタンリリース用のスクリプトを作成することにした。

NAntContrib-0.85-rc4には、svnsvn-checkout、svn-updateのタスクが用意されているので、NAntのビルドファイルを使用してリリース手順をスクリプト化してみた。使用しているバージョン管理ツールはもちろんSubversion

作成したビルドファイルは2つ。リリースブランチ作成用のビルドファイルとリリース用のビルドファイル。

まず、トランクをチェックアウトした作業フォルダ上で走らせるリリースブランチ用のビルドファイルが実行するのは以下。

  1. トランクのチェックアウトおよびビルドとテスト
  2. リリースブランチの作成
  3. リリースブランチのチェックアウトおよびビルドとテスト

次に、上記ビルドファイルによってチェックアウトされたリリースブランチ用の作業フォルダで走らせるリリース用のビルドファイルが実行するのは以下。

  1. リリース用配布ファイルの生成
  2. 配布ファイル内容のテスト
  3. リリースのタグ付け
  4. 配布ファイルの出荷 (ソースとバイナリのそれぞれの圧縮ファイルをビルドサーバーの共有ディレクトリに格納)

今のプロジェクトではzipファイルの配布でリリースに対応できるのでインストーラの作成までは行わなかったが、これはVSのセットアッププロジェクトを作成してビルドファイルから実行する方法で対応できそうだ。このあたりはNUnit-2.2.8-srcのビルドファイルが参考になるだろう。


参考までにテストプロジェクト用のプッシュボタンリリーススクリプトとメインビルドスクリプトを紹介しておく。

TddStudy.ReleaseBranch.build (リリースブランチ用)

<?xml version="1.0" encoding="utf-8" ?>
<project name="TddStudy" default="branch-test">
  <property name="project.version" value="1.0" unless="${property::exists('project.version')}" />
  <property name="project.revision" value="0" />
  <property name="project.release.type" value="release" />

  <property name="working.dir" value="c:\work" />
  <property name="trunktest.dir" value="${path::combine(working.dir, string::to-lower(project::get-name()) + '-trunktest')}" dynamic="true" />
  <property name="branch.dir" value="${path::combine(working.dir, string::to-lower(project::get-name()) + '-rb' + project.version)}" dynamic="true" />
  
  <property name="svn.repos.url" value="svn://ccnetserver" />
  <property name="svn.username" value="administrator" />
  <property name="svn.password" value="admin" />
  
  <!-- トランクのチェックアウトおよびビルドとテスト -->
  <target name="trunk-test" description="trunk checkout and self-test">
    <delete dir="${trunktest.dir}" if="${directory::exists(trunktest.dir)}" />

    <svn-checkout
      destination="${trunktest.dir}" 
      uri="${svn.repos.url}/${string::to-lower(project::get-name())}/trunk" 
      recursive="true"
      verbose="false"
      username="${svn.username}"
      password="${svn.password}" 
      revision="HEAD"
      cache-auth="false" />

    <nant buildfile="${trunktest.dir}\${project::get-name()}.build" target="release test">
      <properties>
        <property name="create.assemblyinfo" value="true" />
      </properties>
    </nant>
  </target>

  <!-- リリースブランチの作成 -->
  <target name="create-release-branch" description="create release branch">
    <svn command="copy"
      uri="${svn.repos.url}/${string::to-lower(project::get-name())}/trunk" 
      username="${svn.username}"
      password="${svn.password}">

      <arg line="copy ${svn.repos.url}/${string::to-lower(project::get-name())}/trunk ${svn.repos.url}/${string::to-lower(project::get-name())}/branches/RB-${project.version}" />
      <arg value="-m 'Creating release branch for ${project.version}'" />
    </svn>
  </target>

  <!-- リリースブランチのチェックアウトおよびビルドとテスト  -->
  <target name="branch-test" depends="trunk-test, create-release-branch" description="release branch checkout and self-test">
    <svn-checkout
      destination="${branch.dir}" 
      uri="${svn.repos.url}/${string::to-lower(project::get-name())}/branches/RB-${project.version}" 
      recursive="true"
      verbose="false"
      username="${svn.username}"
      password="${svn.password}"
      revision="HEAD"
      cache-auth="false" />

    <nant buildfile="${branch.dir}\${project::get-name()}.build" target="release test">
      <properties>
        <property name="create.assemblyinfo" value="true" />
      </properties>
    </nant>
  </target>
</project>

TddStudy.ReleaseGenerate.build (リリースタグ用)

<?xml version="1.0" encoding="utf-8" ?>
<project name="TddStudy" default="distribute">
  <!-- ターゲットビルドファイルのインクルード -->
  <include buildfile="${project::get-name()}.build" />

  <property name="project.version" value="1.0" unless="${property::exists('project.version')}" />
  <property name="project.revision" value="0" unless="${property::exists('project.revision')}" />
  <property name="project.release.type" value="release" />

  <property name="working.dir" value="c:\work" />
  <property name="branch.dir" value="${path::combine(working.dir, string::to-lower(project::get-name()) + '-rb' + project.version)}" dynamic="true" />
  <property name="test.dir" value="${project::get-base-directory()}/build/testinstall" />
  
  <property name="svn.repos.url" value="svn://ccnetserver" />
  <property name="svn.username" value="administrator" />
  <property name="svn.password" value="admin" />
  
  <property name="shared.dist.dir" value="\\ccnetserver\releases" />

  <!-- リリース用配布ファイルの生成 -->
  <target name="branch-package" description="package on release branch">
    <property name="create.assemblyinfo" value="true" />
    <call target="release" />
    <call target="clean" />
    <call target="package" />
  </target>

  <!-- 配布ファイル内容のテスト -->
  <target name="install-test" description="self-test with unzip source">
    <delete dir="${test.dir}" if="${directory::exists(test.dir)}" />

    <unzip zipfile="${project.zip-path.src}" todir="${test.dir}" />

    <nant buildfile="${test.dir}\${project::get-name()}-${project.version.full}\${project::get-name()}.build" target="release test">
      <properties>
        <property name="create.assemblyinfo" value="true" />
      </properties>
    </nant>
  </target>

  <!-- リリースのタグ付け -->
  <target name="create-release-tag" depends="branch-package, install-test" description="create release tag">
    <svn command="copy"
      uri="${svn.repos.url}/${string::to-lower(project::get-name())}/branches/RB-${project.version}" 
      username="${svn.username}"
      password="${svn.password}" >

      <arg line="copy ${svn.repos.url}/${string::to-lower(project::get-name())}/branches/RB-${project.version} ${svn.repos.url}/${string::to-lower(project::get-name())}/tags/REL-${project.version}.${project.revision}" />
      <arg value="-m 'Tag release ${project.version}.${project.revision}'" />
    </svn>
  </target>

  <!-- 配布ファイルの出荷 -->
  <target name="distribute" depends="create-release-tag" description="distribute release package">
    <copy todir="${shared.dist.dir}/${project::get-name()}">
      <fileset basedir="${project::get-base-directory()}/build">
        <include name="${project.zip-path.src}" />
        <include name="${project.zip-path.bin}" />
      </fileset>
    </copy>
  </target>
</project>

TddStudy.build (メインビルド用)

<?xml version="1.0" encoding="utf-8" ?>
<project name="TddStudy" default="test">
  <tstamp property="build.date" pattern="yyyy-MM-dd" />

  <!-- グローバル プロジェクト設定 -->
  <property name="project.version" value="1.0" unless="${property::exists('project.version')}" />
  <property name="project.revision" value="0" unless="${property::exists('project.revision')}" />
  <property name="project.release.type" value="dev" unless="${property::exists('project.release.type')}" /> <!-- nightly / dev / alpha / beta# / rc# / release -->
  <property name="project.version.full" value="${project.version + '.' + project.revision + if(project.release.type == 'release', '', '-' + project.release.type)}" dynamic="true" />
  <property name="create.assemblyinfo" value="false" unless="${property::exists('create.assemblyinfo')}" />

  <!-- グローバル ビルド設定 -->
  <property name="lib.dir" value="${path::combine(build.dir, 'bin/lib')}" dynamic="true" />
  <property name="lib.family.dir" value="${path::combine(lib.dir, framework::get-family(framework::get-target-framework()))}" dynamic="true" />
  <property name="lib.framework.dir" value="${path::combine(lib.family.dir, version::to-string(framework::get-version(framework::get-target-framework())))}" dynamic="true" />
  <property name="programfiles.dir" value="${environment::get-folder-path('ProgramFiles')}" />
  
  <!-- デフォルト構成 -->
  <property name="project.config" value="debug" /> <!-- debug|release -->
  <property name="build.defines" value="" />
  <property name="build.number" value="${math::abs(math::floor(timespan::get-total-days(datetime::now() - datetime::parse('01/01/2000'))))}" />

  <!-- プラットフォーム固有のプロパティ(プリプロセッサ定義) -->
  <property name="current.build.defines" value="${build.defines}" />

  <!-- サードパーティ製 ツール構成 -->
  <if test="${nant.settings.currentframework == 'net-1.1'}">
    <property name="nunit-console.exe" value="${programfiles.dir}\NUnit 2.2.8\bin\nunit-console.exe" />
  </if>
  <if test="${nant.settings.currentframework == 'net-2.0'}">
    <property name="nunit-console.exe" value="${programfiles.dir}\NUnit-Net-2.0 2.2.8\bin\nunit-console.exe" />
  </if>
  <property name="ncover-console.exe" value="${programfiles.dir}\NCover\NCover.Console.exe" />
  <property name="vil.executable" value="${programfiles.dir}\vil-console-1.1\vil.exe" />
  <property name="vil.assemblies" value="comma,separated,list,of,assemblies,to,analyze (full path)" />
  <property name="fxcop-console.exe" value="${programfiles.dir}\Microsoft FxCop 1.35\FxCopCmd.exe" />
  <property name="simian-console.exe" value="${programfiles.dir}\simian-2.2.10\bin\simian-2.2.10.exe" />
  <property name="ncoverexplorer-console.exe" value="${programfiles.dir}/NCoverExplorer/NCoverExplorer.Console.exe" />

  <!-- プロジェクト構成(デバッグビルド or リリースビルド) -->
  <target name="debug" description="Perform a 'debug' build">
    <property name="project.config" value="debug" />
    <property name="build.debug" value="true" />
    <property name="build.dir" value="${project::get-base-directory()}/build/${framework::get-target-framework()}.${platform::get-name()}/${project::get-name()}-${project.version}.${project.revision}-${project.config}" />
  </target>
  <target name="release" description="Perform a 'release' build">
    <property name="project.config" value="release" />
    <property name="build.debug" value="false" />
    <property name="build.dir" value="${project::get-base-directory()}/build/${project::get-name()}-${project.version.full}" />
  </target>
  <property name="build.log.dir" value="${project::get-base-directory()}/build/log" />

  <!-- ビルド初期設定 -->
  <target name="init" description="Initializes build properties">
    <call target="${project.config}" />
    <call target="set-framework-configuration" />
  </target>

  <!-- CommonAssemblyInfo の生成 -->
  <target name="create-common-assemblyinfo" if="${create.assemblyinfo}">
    <attrib file="src/CommonAssemblyInfo.cs" readonly="false" if="${file::exists('src/CommonAssemblyInfo.cs')}" />
    <asminfo output="src/CommonAssemblyInfo.cs" language="CSharp">
      <imports>
        <import namespace="System" />
        <import namespace="System.Reflection" />
        <import namespace="System.Runtime.CompilerServices" />
        <import namespace="System.Runtime.InteropServices" />
      </imports>
      <attributes>
        <attribute type="ComVisibleAttribute" value="false" />
        <attribute type="CLSCompliantAttribute" value="true" />
        <attribute type="AssemblyTitleAttribute" value="${project::get-name()}" />
        <attribute type="AssemblyDescriptionAttribute" value="テスト駆動開発入門 写経" />
        <attribute type="AssemblyConfigurationAttribute" value="${project.release.type}" />
        <attribute type="AssemblyCompanyAttribute" value="http://qwik.jp/nagile-study2/" />
        <attribute type="AssemblyProductAttribute" value="NAgile勉強会" />
        <attribute type="AssemblyCopyrightAttribute" value="Copyright (C) 2005-${datetime::get-year(datetime::now())} nagile-study2. All right reserved." />
        <attribute type="AssemblyTrademarkAttribute" value="" />
        <attribute type="AssemblyCultureAttribute" value="" />
        <attribute type="AssemblyVersionAttribute" value="${project.version}.${project.revision}.${build.number}" />
        <attribute type="AssemblyInformationalVersionAttribute" value="${project.version}.${project.revision}" />
      </attributes>
    </asminfo>
  </target>

  <!-- カレントビルド構成フォルダのクリーンアップ -->
  <target name="clean" depends="init" description="Deletes current build configuration">
    <delete dir="${build.dir}" if="${directory::exists(build.dir)}" />
    <delete dir="${build.log.dir}" if="${directory::exists(build.log.dir)}" />
  </target>

  <!-- 全てのビルド構成フォルダのクリーンアップ -->
  <target name="cleanall" description="Deletes every build configuration">
    <echo message="Deleting all builds from all configurations" />
    <delete dir="build" if="${directory::exists('build')}" />
  </target>

  <!-- 各プロジェクトのビルド -->
  <target name="build" depends="init, create-common-assemblyinfo" description="Builds current configuration">
    <echo message="Build Directory is ${build.dir}" />
    <echo message="" />

    <mkdir dir="${build.dir}/bin" />
    <mkdir dir="${build.dir}/bin/lib" />
    <copy todir="${build.dir}/bin/lib">
      <fileset basedir="vendor/lib">
        <include name="**/*" />
      </fileset>
    </copy>

    <!-- log4netを使用する場合はコメントアウトを外して下さい。 -->
    <!-- <copy file="${lib.framework.dir}/log4net.dll" tofile="${build.dir}/bin/log4net.dll" /> -->

    <!-- NMock2を使用する場合はコメントアウトを外して下さい。 -->
    <!--<copy file="${lib.framework.dir}/NMock2.dll" tofile="${build.dir}/bin/NMock2.dll" />-->

    <nant buildfile="src/${project::get-name()}.Core/${project::get-name()}.Core.build" target="build" />
    <nant buildfile="src/${project::get-name()}.Tests/${project::get-name()}.Tests.build" target="build" />
  </target>

  <!-- ユニットテストの実行 -->
  <target name="test" depends="build" description="Tests current configuration">
    <nant buildfile="src/${project::get-name()}.Tests/${project::get-name()}.Tests.build" target="test" />

    <copy file="${build.dir}/bin/${project::get-name()}.Tests.dll-results.xml" tofile="${build.log.dir}/${project::get-name()}.Tests.dll-results.xml" />
  </target>

  <!-- 各種レポートの収集 -->
  <target name="reporting" depends="build">
    <call target="ncover" />
    <call target="ncover-explorer" />
    
    <!-- vil1.1は.NET Framework 2.0未対応 -->
    <if test="${nant.settings.currentframework == 'net-1.1'}">
      <call target="vil" />
    </if>
    
    <call target="fxcop" />
    <call target="simian" />

    <copy todir="${build.log.dir}">
      <fileset basedir="${build.dir}/bin">
        <include name="${project::get-name()}.Tests.dll-results.xml" />
        <include name="${project::get-name()}-ncover.xml" />
        <include name="${project::get-name()}-ncoverexplorer.xml" />
        <include name="${project::get-name()}-vil.xml" />
        <include name="${project::get-name()}-fxcop.xml" />
        <include name="${project::get-name()}-simian.xml" />
      </fileset>
    </copy>
  </target>

  <!-- コードカバレッジ レポートの収集 -->
  <target name="ncover">
    <exec program="${ncover-console.exe}" verbose="true" failonerror="true">
      <arg value="//l" />
      <arg file="${build.dir}/bin/${project::get-name()}-ncover.log" />
      <arg value="//x" />
      <arg file="${build.dir}/bin/${project::get-name()}-ncover.xml" />
      <arg value="//ea" />
      <arg value="${project::get-name()}.Core.CoverageExcludeAttribute;${project::get-name()}.Tests.CoverageExcludeAttribute" />
      <arg value="//w" />
      <arg value="${build.dir}/bin" />
      <arg file="${nunit-console.exe}" />
      <arg value="/xml:${project::get-name()}.Tests.dll-results.xml" />
      <arg value="${project::get-name()}.Tests.dll" />
    </exec>

    <copy todir="${build.dir}/bin">
      <fileset basedir="${programfiles.dir}/NCover">
        <include name="Coverage.xsl" />
      </fileset>
    </copy>
  </target>

  <target name="ncover-explorer">
    <ncoverexplorer program="${ncoverexplorer-console.exe}"
      projectName="${project::get-name()}"
      reportType="3"
      outputDir="${build.dir}/bin/"
      xmlReportName="${project::get-name()}-ncoverexplorer.xml"
      htmlReportName="${project::get-name()}-ncoverexplorer.html"
      showExcluded="True"
      satisfactoryCoverage="80" >

      <fileset>
        <include name="${build.dir}/bin/${project::get-name()}-ncover.xml" />
      </fileset>
      <exclusions>
        <exclusion type="Assembly" pattern="*.Tests" />
        <!-- <exclusion type="Namespace" pattern="*.Gui" /> -->
        <!-- <exclusion type="Class" pattern="*Dataset" /> -->
      </exclusions>
    </ncoverexplorer>
  </target>

  <!-- コードメトリクス レポートの収集 -->
  <target name="vil">
    <exec program="${vil.executable}" workingdir="${build.dir}/bin" 
          commandline='/a=${project::get-name()}.Core.dll /outxml="${project::get-name()}-vil.xml" /outHtml="${project::get-name()}-vil.html" /m classes,enumerations,structs,types,LOC,events,impInterfaces,WMC,DIT,CBO,RFC,NOC,constructors,methods,imps,fields,properties /sc=type' failonerror="false"/>
  </target>

  <!-- コードスタイルチェック レポートの収集 -->
  <target name="fxcop">
    <exec program="${fxcop-console.exe}" workingdir="${build.dir}/bin" 
          commandline="/f:${build.dir}/bin/${project::get-name()}.*.dll /d:${lib.framework.dir} /o:${project::get-name()}-fxcop.xml" failonerror="false"/>
  </target>

  <!-- 重複コード検出 レポートの収集 -->
  <target name="simian" description="finds duplicate code">
    <exec program="${simian-console.exe}" failonerror="false">
      <arg value="-recurse=src/*[^T][^e][^s][^t].cs" />
      <arg value="-formatter=xml:${build.dir}/bin/${project::get-name()}-simian.xml" />
    </exec>
    <copy todir="${build.dir}/bin">
      <fileset basedir="${programfiles.dir}/simian-2.2.9">
        <include name="simian.xsl" />
      </fileset>
    </copy>
  </target>

  <!-- HTMLヘルプの生成 -->
  <target name="sdkdoc" depends="build" description="Builds SDK documentation">
    <uptodate property="sdk.uptodate">
      <targetfiles>
        <include name="${build.dir}/doc/sdk/*.chm" />
      </targetfiles>
      <sourcefiles basedir="${build.dir}/bin">
        <include name="${project::get-name()}.Core.dll" />
      </sourcefiles>
    </uptodate>
    <if test="${not(sdk.uptodate)}">
      <ndoc>
        <assemblies basedir="${build.dir}/bin">
          <include name="${project::get-name()}.Core.dll" />
        </assemblies>
        <documenters>
          <documenter name="MSDN">
            <property name="OutputDirectory" value="${build.dir}/doc/sdk" />
            <property name="OutputTarget" value="HtmlHelp" />
            <property name="SdkDocVersion" value="${link.sdkdoc.version}" />
            <property name="SdkDocLanguage" value="ja" />
            <property name="SdkLinksOnWeb" value="${link.sdkdoc.web}" />
            <property name="HtmlHelpName" value="${project::get-name()}-SDK" />
            <property name="IncludeFavorites" value="False" />
            <property name="Title" value="${project::get-name()} SDK Documentation - v${project.version.full}" />
            <property name="SplitTOCs" value="False" />
            <property name="DefaulTOC" value="" />
            <property name="ShowVisualBasic" value="True" />
            <property name="Preliminary" value="${not(project.release.type == 'release')}" />
            <property name="ShowMissingSummaries" value="${build.debug}" />
            <property name="ShowMissingRemarks" value="${build.debug}" />
            <property name="ShowMissingParams" value="${build.debug}" />
            <property name="ShowMissingReturns" value="${build.debug}" />
            <property name="ShowMissingValues" value="${build.debug}" />
            <property name="DocumentAttributes" value="True" />
            <property name="ShowTypeIdInAttributes" value="False" />
            <property name="DocumentInternals" value="False" />
            <property name="DocumentPrivates" value="False" />
            <property name="DocumentProtected" value="True" />
            <property name="DocumentEmptyNamespaces" value="False" />
            <property name="IncludeAssemblyVersion" value="False" />
            <property name="CopyrightText" value="Copyright (C) 2005-${datetime::get-year(datetime::now())} nagile-study2. All right reserved." />
            <property name="CopyrightHref" value="http://qwik.jp/nagile-study2/" />
            <property name="EditorBrowsableFilter" value="Off" />
          </documenter>
        </documenters>
      </ndoc>
    </if>
    <delete>
      <fileset basedir="${build.dir}/doc/sdk">
        <include name="${project::get-name()}-SDK.hhc" />
        <include name="${project::get-name()}-SDK.hhk" />
        <include name="${project::get-name()}-SDK.hhp" />
        <include name="${project::get-name()}-SDK.log" />
        <include name="ndoc_msdn_temp/*" />
      </fileset>
    </delete>
  </target>

  <!-- パッケージの準備 -->
  <target name="package-common" depends="test, updatebin, sdkdoc">
    <copy todir="${build.dir}">
      <fileset>
        <include name="*" />
        <include name="doc/**" />
        <include name="src/**" />
        <include name="vendor/**" />
        <exclude name="**/*.suo" />
        <exclude name="**/*j.user" />
        <exclude name="**/bin/**" />
        <exclude name="**/obj/**" />
      </fileset>
    </copy>
    <property name="project.zip.prefix" value="${project::get-name()}-${project.version.full}" />
  </target>

  <!-- ソースコード パッケージの生成 -->
  <target name="package-src" depends="package-common">
    <property name="project.zip-path.src" value="${project::get-base-directory()}/build/${project::get-name()}-${project.version.full}-src.zip" />
    <delete file="${project.zip-path.src}" if="${file::exists(project.zip-path.src)}" />
    <zip zipfile="${project.zip-path.src}" ziplevel="9">
      <fileset basedir="${build.dir}" prefix="${project.zip.prefix}">
        <include name="${project::get-name()}.build" />
        <include name="${project::get-name()}.sln" />
        <include name="readme.txt" />
        <include name="doc/**/*" />
        <include name="src/**/*" />
        <include name="vendor/**/*" />
      </fileset>
    </zip>
    <echo message="Created '${project.config}' source packages at file://${project::get-base-directory()}/build/" />
  </target>

  <!-- バイナリ パッケージの生成 -->
  <target name="package-bin" depends="package-common">
    <property name="project.zip-path.bin" value="${project::get-base-directory()}/build/${project::get-name()}-${project.version.full}-bin.zip" />
    <delete file="${project.zip-path.bin}" if="${file::exists(project.zip-path.bin)}" />
    <zip zipfile="${project.zip-path.bin}" ziplevel="9">
      <fileset basedir="${build.dir}" prefix="${project.zip.prefix}">
          <include name="bin/**/*" />
          <include name="doc/sdk/${project::get-name()}-SDK.chm" />
          <exclude name="doc/*" />
          <exclude name="bin/NMock2.dll" />
          <exclude name="bin/*.tests.*" />
          <exclude name="bin/lib/*" />
          <exclude name="bin/lib/**/*" />
          <exclude name="bin/*.xml" />
      </fileset>
    </zip>
    <echo message="Created '${project.config}' binary packages at file://${project.zip-path.bin}" />
  </target>

  <!-- パッケージの生成 -->
  <target name="package" depends="package-src, package-bin" description="Creates a binary and source distribution package." />

  <!-- バイナリフォルダのアップデート -->
  <target name="updatebin" depends="build" description="Does a release build and copies them to the bin folder.">
    <delete if="false">
      <fileset basedir="bin">
        <include name="${project::get-name()}*" />
        <include name="log4net.dll" />
      </fileset>
    </delete>
    <copy todir="bin" overwrite="true">
      <fileset basedir="${build.dir}/bin/">
        <include name="**/*" />
        <include name="log4net.dll" />
        <exclude name="NMock2.dll" />
        <exclude name="lib/*" />
        <exclude name="lib/**/*" />
        <exclude name="*Test*" />
        <exclude name="*.xml" />
        <exclude name="*.log" />
        <exclude name="*.xsl" />
      </fileset>
    </copy>
  </target>

  <!-- フレームワーク サポート構成 -->
  <target name="set-framework-configuration">
    <if test="${not(target::exists('set-'+framework::get-target-framework()+'-framework-configuration'))}">
      <fail message="The '${framework::get-target-framework()}' framework is not supported by this version of NAnt." />
    </if>
    <call target="set-${framework::get-target-framework()}-framework-configuration" />
  </target>

  <target name="set-net-1.0-framework-configuration">
    <property name="nant.settings.currentframework" value="net-1.0" />
    <property name="current.build.defines" value="${build.defines}NET,NET_1_0" dynamic="true" />
    <property name="link.sdkdoc.version" value="SDK_v1_0" />
    <property name="link.sdkdoc.web" value="false" />
  </target>

  <target name="set-net-1.1-framework-configuration">
    <property name="nant.settings.currentframework" value="net-1.1" />
    <property name="current.build.defines" value="${build.defines}NET,NET_1_1" dynamic="true" />
    <property name="link.sdkdoc.version" value="SDK_v1_1" />
    <property name="link.sdkdoc.web" value="false" />
  </target>

  <target name="set-net-2.0-framework-configuration">
    <property name="nant.settings.currentframework" value="net-2.0" />
    <property name="current.build.defines" value="${build.defines}NET,NET_2_0" dynamic="true" />
    <property name="link.sdkdoc.version" value="SDK_v2_0" />
    <property name="link.sdkdoc.web" value="false" />
  </target>

  <target name="set-netcf-1.0-framework-configuration">
    <property name="nant.settings.currentframework" value="netcf-1.0" />
    <property name="current.build.defines" value="${build.defines}NETCF,NETCF_1_0" dynamic="true" />
    <property name="link.sdkdoc.version" value="SDK_v1_1" />
    <property name="link.sdkdoc.web" value="true" />
  </target>

  <target name="set-mono-1.0-framework-configuration">
    <property name="nant.settings.currentframework" value="mono-1.0" />
    <property name="current.build.defines" value="${build.defines}MONO,MONO_1_0" dynamic="true" />
    <property name="link.sdkdoc.version" value="SDK_v1_1" />
    <property name="link.sdkdoc.web" value="true" />
  </target>

  <target name="set-mono-2.0-framework-configuration">
    <property name="nant.settings.currentframework" value="mono-2.0" />
    <property name="current.build.defines" value="${build.defines}MONO,MONO_2_0" dynamic="true" />
    <property name="link.sdkdoc.version" value="SDK_v1_1" />
    <property name="link.sdkdoc.web" value="true" />
  </target>

  <target name="set-sscli-1.0-framework-configuration">
    <property name="nant.settings.currentframework" value="sscli-1.0" />
    <property name="current.build.defines" value="${build.defines}SSCLI,SSCLI_1_0" dynamic="true" />
    <property name="link.sdkdoc.version" value="SDK_v1_0" />
    <property name="link.sdkdoc.web" value="true" />
  </target>
</project>

これらの汎用的なテンプレートは、nagile.comからダウンロードできるNAnt-0.85-rc4用ビルドファイルテンプレートに格納しておいた。

ダウンロード