ASP.NET のプロジェクトを作成すると、 Web.config ファイルが生成されます。 それと同時に、Web.Debug.config と Web.Release.config が作成され、アプリケーションの発行を行う際の構成にあわせて、 Web.config の変換を行ってくれます。 今回はこの構成ファイルの書き換え機能を App.config に対して実行できるような Azure Pipelines のテンプレートを作ってみようと思います。
環境
- Visual Studio 2019
- .NET Framework 4.8
- コンソールアプリケーション(App.config のあるプロジェクトなら同じことができます)
プロジェクトを準備する
まずは適当にコンソールアプリケーションを作成します。 超シンプルに、 AppSettings から値を取得してコンソールに表示するだけにしておきます。
using System; using System.Configuration; namespace ConsoleApp1 { class Program { static void Main(string[] args) { Console.WriteLine($"Setting1: {ConfigurationManager.AppSettings["Setting1"]}"); } } }
App.config はこのような形で、 AppSettings に 1 つだけキーを足しておきます。
<?xml version="1.0" encoding="utf-8" ?> <configuration> <appSettings> <add key="Setting1" value="LocalDebugSetting"/> </appSettings> </configuration>
実行するとこんな感じです。
差し替える構成ファイルを準備する
さて、ここから本番です。 今回は App.config に設定されている Settings1 の値を、ビルド時に差し替えるような XML 変換のファイルを作っていきます。 Web.config の場合 Release で発行したときは Web.Release.config の XML 変換が適用されます。 似たような構成にするため、以下のような App.Release.config を作ります。
<?xml version="1.0" encoding="utf-8" ?> <configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"> <appSettings> <add key="Setting1" value="ReleaseSetting" xdt:Transform="Replace" xdt:Locator="Match(key)"/> </appSettings> </configuration>
ファイルのプロパティは以下のように設定しておきます。
ソリューション上は下記のようになります。
YAML テンプレートを準備する
続いて今回のキモとなる、 YAML のテンプレートを作成します。 .git ディレクトリのあるルートディレクトリ内に、 pipelines-template ディレクトリを作成し、その中に以下の YAML を配置します。 ファイル名は publish-desktop-app-template.yml としておきました。
parameters: - name: projectRootDirectory type: string default: '' - name: projectFileName type: string default: '*.csproj' - name: outputPath type: string default: '' - name: buildPlatform type: string default: 'AnyCPU' - name: buildConfiguration type: string default: 'Release' steps: - task: Bash@3 displayName: 'パラメーターチェック' inputs: targetType: 'inline' script: | if [ -z "$PROJECTROOTDIRECTORY" ]; then echo "##vso[task.logissue type=error;]テンプレートパラメーター \"projectRootDirectory\" が指定されていません。" echo "##vso[task.complete result=Failed;]" fi if [ -z "$OUTPUTPATH" ]; then echo "##vso[task.logissue type=error;]テンプレートパラメーター \"outputPath\" が指定されていません。" echo "##vso[task.complete result=Failed;]" fi env: PROJECTROOTDIRECTORY: ${{ parameters.projectRootDirectory }} OUTPUTPATH: ${{ parameters.outputPath }} - task: FileTransform@2 displayName: 'App.config 変換 - ${{ parameters.projectRootDirectory }}' inputs: folderPath: '${{ parameters.projectRootDirectory }}' xmlTransformationRules: '-transform "**\App.${{ parameters.buildConfiguration }}.config" -xml "**\App.config"' - task: VSBuild@1 displayName: 'アプリケーションのビルド - ${{ parameters.projectRootDirectory }}' inputs: solution: '${{ parameters.projectRootDirectory }}/**/${{ parameters.projectFileName }}' msbuildArgs: '/p:OutPutPath="${{ parameters.outputPath }}"' platform: '${{ parameters.buildPlatform }}' configuration: '${{ parameters.buildConfiguration }}'
ここまで作成したら Azure DevOps のリポジトリにファイル一式をプッシュしておきます。
ビルドパイプラインを作成する
続いて Azure DevOps から、ビルドパイプラインの YAML を作成していきます。 作成したテンプレートを呼び出すようにしましょう。 また動作確認のため、最終的にビルドしたアプリケーションを Pipeline Artifacts に登録しておきます。
trigger: none pool: vmImage: 'windows-latest' steps: - template: 'pipelines-template/publish-desktop-app-template.yml' parameters: projectRootDirectory: '$(Build.SourcesDirectory)/ConfigTransformationSample/ConsoleApp1' outputPath: '$(Build.Artifactstagingdirectory)/ConsoleApps/ConsoleApp1' - task: PublishPipelineArtifact@1 inputs: targetPath: '$(build.ArtifactStagingDirectory)\ConsoleApps' artifact: 'ConsoleApplications' publishLocation: 'pipeline'
結果確認
上記のビルドパイプラインを実行すると、構成ファイルの変換が実行され、Pipeline Artifacts には以下の構成ファイルを含むアプリケーションが配置されているはずです。
<?xml version="1.0" encoding="utf-8"?> <configuration> <appSettings> <add key="Setting1" value="ReleaseSetting" /> </appSettings> </configuration>
これで ASP.NET のアプリケーションと同じような方法で、構成ファイルの XML 変換を実行できるようになりました。
まとめ
今回は ASP.NET Web アプリケーションの発行のような形で、デスクトップアプリケーションのビルドができる YAML テンプレートを作ってみました。 カスタマイズして使ってみてください。
注意点
テンプレートに渡す sourceDirectory の配下には、 プロジェクトを 1 つだけ置くようにしましょう。 ここにルートディレクトリを渡してしまうと、 App.config の書き換えが思ったようにいかなくなります。 これは FileTransform のタスクの制約なのであきらめるしかなさそうです。
本稿で解説した YAML について
なお一部のコードについて、本稿で解説した物とは異なる箇所があります。