私はMSBuildだけでこれを正確に実行しました。私の場合の手順は次のとおりです。
- TFSは、ソリューションファイルではなく、カスタムMSBuildプロジェクトを使用してビルドを実行しました。どのCIビルドシステムでも機能しますが、この場合のTFSについては特別なことは何もありません。
- カスタムビルドプロジェクトでは、すべてのプロジェクトをビルドすることに加えて、一連のweb.config「テンプレート」ファイルを$(OutDir)フォルダーの下の特別なフォルダーにコピーしました。これらは、TFSからのビルドドロップになります。私の場合、組み込みの構成ファイルの変換は、十分に洗練されたものではありませんでしたが、それがうまくいくのであれば、はるかに簡単です。
- web.configファイルには、実際には、構成可能な機能ごとに1つずつ、他の構成ファイルへの参照が含まれていました。これは、カスタム構成プロバイダーを使用しました。ただし、この手法は、web.configファイルが1つしかない場合にも機能します。
- ビルドを駆動していたのと同じカスタムMSBuildプロジェクトの新しいMSBuildターゲットとして、コマンドラインから自動展開(公開)を有効にしました。
- その後、メインビルドの公開ステップをVMまたはQAマシンに自動化するだけでなく、コマンドラインから他のサーバー(最終的にはステージングサーバー)に手動で展開できるようにするのも簡単でした。
web.configテンプレートには次のようなものがありました。
In the connection string: "Data Source=${SQLINSTANCE};Initial Catalog=${SQLDATABASENAME}..."
MSBuildは中括弧を混乱させないため、交換可能なトークンの区切り文字が$()ではなく${}であることは重要です。
公開ステップでは、MSBuildプロパティ関数を使用して、構成ファイルのビットを置き換えます。以下は、MSDNのMSBuildインラインタスクの説明から抜粋したものです。
<UsingTask
TaskName="ReplaceToken"
TaskFactory="CodeTaskFactory"
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
<ParameterGroup>
<File ParameterType="System.String" Required="true" />
<Token ParameterType="System.String" Required="true" />
<Replacement ParameterType="System.String" Required="true" />
</ParameterGroup>
<Task>
<Code Type="Fragment" Language="cs">
<![CDATA[
string content = File.ReadAllText(File);
content = content.Replace(Token, Replacement);
File.WriteAllText(File, content);
]]>
</Code>
</Task>
</UsingTask>
次に、プロジェクトで、このタスクを次のコマンドで使用できます。
<ReplaceToken
File="PathTo\Web.config"
Token="${SQLINSTANCE}"
Replacement=".\SQLEXPRESS"
/>
これは実際には単なる大まかなガイドであり、ReplaceTokenのすべてのパラメーターもMSBuildアイテムのメタデータで構成されており、データベース、サーバー、セキュリティなど、それぞれを個別に指定できるオプションが可能です。
したがって、ビルド/デプロイメントごとに、ビルドを実行し、構成テンプレートをコピーし、それらに対して文字列の置換を行ってから、パッケージ/公開を自動化します。これは、最後の段階です。
あなたの最善の策は、このブログから始めることです:http: //vishaljoshi.blogspot.com/2009/02/web-packaging-creating-web-packages.html少し説明し、この答えにはたくさんのいいねが含まれています他の関連するStackOverflowの投稿MsBuildとMsDeployを複数の環境で使用してから、http://www.bing.com/search?q = msbuild + msdeploy + command + line&go =&form = QBLH&qs = n&sk=でオンライン検索します。深く掘り下げる。私はあなたをその部分の検索エンジンに捨てるのは本当に嫌いですが、非常に多くの異なるシナリオがあり、それらを特定するのは難しいことがわかりました。上位10件の回答の約半分は、いくつかの貴重な角度についての洞察を持っています。この時点で私の応答を絞り込むのに役立つ詳細情報を返信してください。私の実装では、Execタスクを使用してMSBuildから直接MSDeploy.exeを呼び出しました。考慮すべきいくつかの事柄:
- さまざまな公開サイトのセキュリティに対処する方法。大量のビルドサービスアカウントを設定する必要があり、msbuildコマンドラインで常にパスワードを渡す必要がありました。あなたが提案するようにWindows認証でうまくいくことができれば、それは少し簡単になるでしょう。
- サービスについては、PSExecを使用してリモートサーバーでinstallutilを実行する必要がありました
- リモートサーバーでappcmdを呼び出してPSExecを使用して自動化した追加の構成項目がいくつかありました。
- サーバー上でリモート共有を開き、「net use」コマンドを使用してビルド中にマップしたり、マップを解除したりするのは簡単です。他の設定がある場合もあります。
- パフォーマンスは厳しいです。大規模なサイトの場合、ファイルごとに実行すると非常に長く実行される可能性があります。RoboCopyはこれ以上高速ではありません。MSDeployを使用してリモートでパッケージ化する(ソースとしてローカルドロップをポイントし、パッケージソースのリモート共有をポイントする)ことは、Rackspaceに対して非常に高速であることがわかりました。最初に1回のMSDeploy呼び出しを使用してzipファイルにパッケージ化し、次に2回目の呼び出しを使用してパッケージをリモートでプッシュする必要がある場合があります。
これで始められることを願っています。私が本当に見逃したり、見落としたりしたことがある場合は、コメントするか、質問に詳細を記入してください。
コメントへの回答:
「公開」ターゲットは、これらの線に沿ったものです。
<Target Name="Publish">
<!-- token replacement in config files, as above -->
<!-- ...lots of custom setup, selection of various properties used below -->
<PropertyGroup>
<_MsDeployExe>$(PROGRAMFILES)\IIS\Microsoft Web Deploy\msdeploy</_MsDeployExe>
<_MsDeploySourceArg>-source:contentpath="$(_BuildDropFolder)"</_MsDeploySourceArg>
<_MsDeployDestArg>-dest:contentpath=\\$(_RemoteComputerName)\DropFolder</_MsDeployDestArg>
</PropertyGroup>
<Message
Text=""$(_MsDeployExe)" -verb:sync $(_MsDeploySourceArg) $(_MsDeployDestArg)"
/>
<Exec
Condition="'$(DryRun)' != 'true'"
Command=""$(_MsDeployExe)" -verb:sync $(_MsDeploySourceArg) $(_MsDeployDestArg)"
ContinueOnError="false"
WorkingDirectory="$(MSBuildThisFileDirectory)"
/>
</Target>