.NET で開発しているプロジェクトのソースコードをチェックアウトして、ビルドして、出来あがったアセンブリを公開用リポジトリにコミット、という作業を MSBuild で自動化してました。
でもいい加減、条件分岐とかループとか MSBuild でやるの面倒になったので、ビルドスクリプトを Ruby + Rake で書き変えることにしました。やっぱ Rake いいわぁ。言語内 DSL 最高。
作成した Rakefile をメモしておきます。
# coding: utf-8 require "yaml" SVN = 'svn' MSBUILD = 'C:/windows/Microsoft.NET/Framework/v4.0.30319/MSBuild.exe' File.open("./projects.yml") do |io| YAML.load_documents(io) do |obj| obj.keys.each do |key| namespace key do # YAML からビルドに必要な情報を取得 src_repo_url = obj[key]["src_repo"] bin_repo_url = obj[key]["bin_repo"] src_work_dir = obj[key]["src_work"] bin_work_dir = obj[key]["bin_work"] sln_path = obj[key]["sln_path"] # クリーンアップ # CLOBBER を使うと動的に生成した他のタスクの成果物まで削除してしまうので # クリーンアップ用タスクを用意 desc "Cleanup" task :cleanup do FileUtils.rm_rf(bin_work_dir) FileUtils.rm_rf(src_work_dir) end # ソースコードをチェックアウト desc "Checkout source code files from subversion repository." task :checkout_src do sh "#{SVN} checkout #{src_repo_url} #{src_work_dir}" end # アセンブリをチェックアウト desc "Checkout binary files from subversion repository." task :checkout_bin do sh "#{SVN} checkout #{bin_repo_url} #{bin_work_dir}" end # 古いアセンブリを削除 desc "Delete all old binary files." task :delete_old_bin do Dir.glob("#{bin_work_dir}/**/*").each do |path| if File.file?(path) puts "Delete #{path}" File.delete(path) end end end # ソリューションをビルド desc "Build Visual Studio solution." task :build do sh "#{MSBUILD} #{sln_path} /p:Configuration=Release /p:Platform=\"Any CPU\" /t:Rebuild" end # 空のディレクトリをリポジトリから削除 desc "Delete all empty directories." task :delete_empty_dirs do Dir.glob("#{bin_work_dir}/**/*").each do |path| if File.directory?(path) and Dir.glob("#{path}/*").count == 0 sh "#{SVN} delete #{path}" end end end # 新しいアセンブリをリポジトリに追加 desc "Regist new files to subversion repository." task :add_new_files do pattern = File.join(bin_work_dir, "*") sh "#{SVN} add #{pattern}" end # アセンブリのリポジトリをコミット desc "Commit binary repository." task :commit_bin do message = '"update binary files"' sh "#{SVN} commit #{bin_work_dir} -m #{message} --username foo --password bar" end # すべてのタスクを実行 desc "Execute all build task." task :all => [:cleanup, :checkout_src, :checkout_bin, :delete_old_bin, :build, :delete_empty_dirs, :add_new_files, :commit_bin] end end end end
あとは、Rakefile と同じディレクトリに projects.yml ファイルを作成して、次のような設定を記述。
foo_main: src_repo: "http://reposerver/svn/Foo/trunk" bin_repo: "http://reposerver/svn/FooBin/trunk" src_work: "C:/Work/Foo" bin_work: "C:/Work/Foo/BIN" sln_path: "C:/Work/Foo/Foo.sln" foo_ver1: src_repo: "http://reposerver/svn/Foo/branches/1.0" bin_repo: "http://reposerver/svn/FooBin/branches/1.0" src_work: "C:/Work/Foo1.0" bin_work: "C:/Work/Foo1.0/BIN" sln_path: "C:/Work/Foo1.0/Foo.sln"
これで rake を実行すれば、YAML ファイルから設定を読み込んで、動的にタスクを生成できます。ビルドするプロジェクトが増えたら、そのプロジェクトのリポジトリや作業ディレクトリを YAML に追加するだけ。