NAnt でアセンブリのバージョンアップデート
via CodeZine:NAntでアセンブリのバージョンアップデートを自動化する
複数アセンブリのバージョン番号管理を自動化する、いい方法はないかと考えている時に上記の記事を見つけた。
アイデア自体はいいんだけど、ビルド番号を決定するスクリプトがどうも気持ち悪い。
なんとかしようとタスクリファレンスを眺めていたら、アセンブリからバージョン番号を取得する関数があるじゃないですか。
現在のバージョン番号はアセンブリに埋め込まれているわけだから、そこから次のバージョン番号を決定すればいいのでは?と考えてやってみたらうまくいったのでメモしておく。
ついでにサンプル一式
想定するフォルダ構成
作業フォルダ以下にビルドスクリプト、アセンブリ出力先、ソースフォルダを格納する。

ビルドスクリプトを実行すると、アセンブリが bin フォルダに出力される。
ちなみに以下は2回目の実行で出力されたアセンブリのプロパティ。

ビルドスクリプト
ビルドスクリプトがやっているのはこんな感じ。
- CountUp タスク → バージョン番号のインクリメント。(既存のアセンブリがなければ 1.0.0.0)
- GenerateAsmInfo タスク → バージョン番号を埋め込んだ AssemblyInfo.cs を生成
- Build タスク → 出力先を指定して、プロジェクトをビルド
対象は .NET 1.1 だけど、solution タスクのところを MSBuild の呼び出しに変更すれば .NET 2.0 でもいけるはず。
<?xml version="1.0" encoding="utf-8" ?>
<project name="BuildAssembly" default="Build" basedir="." xmlns="http://nant.sf.net/release/0.85-rc4/nant.xsd">
<property name="SolutionName" value="Solution"/>
<property name="AssemblyName" value="ClassLibrary1"/>
<property name="base.dir" value="${project::get-base-directory()}"/>
<property name="source.dir" value="${base.dir}/source"/>
<property name="output.dir" value="${base.dir}/bin"/>
<property name="output.file" value="${output.dir}/${AssemblyName}.dll"/>
<property name="info.file" value="${source.dir}/${SolutionName}/${AssemblyName}/AssemblyInfo.cs"/>
<property name="proj.file" value="${source.dir}/${SolutionName}/${AssemblyName}/${AssemblyName}.csproj"/>
<target name="CountUp" description="バージョン番号をカウントアップ">
<!-- アセンブリがなければ 1.0.0.0 からスタート -->
<if test="${not file::exists(output.file)}">
<property name="version" value="1.0.0.0"/>
</if>
<!-- アセンブリがあればアセンブリバージョンを読み取って、ビルド番号をカウントアップ -->
<if test="${file::exists(output.file)}">
<property name="version" value="${assemblyname::get-version(assemblyname::get-assembly-name(output.file))}"/>
<property name="major" value="${version::get-major(version::parse(version))}"/>
<property name="minor" value="${version::get-minor(version::parse(version))}"/>
<property name="build" value="${version::get-build(version::parse(version))}"/>
<property name="revision" value="${version::get-revision(version::parse(version))}"/>
<property name="build" value="${int::parse(build) + 1}"/>
<property name="version" value="${major}.${minor}.${build}.${revision}"/>
</if>
</target>
<target name="GenerateAsmInfo" depends="CountUp" description="AssemblyInfoを作成">
<!-- 既存の AssemblyInfo.cs を削除 -->
<delete file="${info.file}"/>
<!-- AssemblyInfo.cs を生成 -->
<attrib file="${info.file}" normal="true" />
<asminfo output="${info.file}" language="CSharp">
<imports>
<import namespace="System.Reflection" />
<import namespace="System.Runtime.InteropServices" />
<import namespace="System.Runtime.CompilerServices" />
</imports>
<attributes>
<attribute type="AssemblyTitleAttribute" value="${AssemblyName} for .NET 1.1" />
<attribute type="AssemblyDescriptionAttribute" value="" />
<attribute type="AssemblyConfigurationAttribute" value="" />
<attribute type="AssemblyCompanyAttribute" value="Company" />
<attribute type="AssemblyProductAttribute" value="${AssemblyName}" />
<attribute type="AssemblyCopyrightAttribute" value="Copyright (C) 2006, HOGE CORP." />
<attribute type="AssemblyTrademarkAttribute" value="${AssemblyName}" />
<attribute type="AssemblyCultureAttribute" value="" />
<attribute type="ComVisibleAttribute" value="false" />
<attribute type="AssemblyVersionAttribute" value="${version}" />
</attributes>
</asminfo>
</target>
<target name="Build" depends="GenerateAsmInfo" description="ビルド">
<solution configuration="release" outputdir="${output.dir}">
<projects>
<include name="${proj.file}"/>
</projects>
</solution>
</target>
</project>