演習 - テンプレートを使用して複数の構成をビルドする

完了

前の演習では、Space Game Web サイトをビルドするパイプラインを実装しました。 各ビルド アクションが実行されており、対応するパイプライン タスクに各アクションがマップされているスクリプトから開始します。 パイプラインの出力は、コンパイルされた Web アプリが含まれている .zip ファイルです。

この演習では、テンプレートを使用して、プロジェクト ファイルで定義されている任意の構成をビルドできるビルド タスクを定義します。 テンプレートを使用すると、ロジックを 1 回定義するだけで、後から何回でも再利用できます。 テンプレートは、複数の YAML ファイルの内容を 1 つのパイプラインにまとめます。

ヒント

モジュールのこの手順は省略可能です。 この段階ではテンプレートについて学習しない場合、次の手順である「Azure DevOps 環境をクリーンアップする」に進んでください。 テンプレートの詳細については、テンプレートの種類と使用に関する記事を参照してください。

まず、Mara と Amita に連絡しましょう。

デモ

自分の結果を共有することに興奮している Mara は、Amita を見つけてビルド パイプラインを見せます。

Amita: すごいですね。この作業をこんなに速くできたなんて! 実際、ビルドの準備ができたことを知らせるメールを受け取ったので、ちょうどあなたに会いに来ていました。 ご協力に感謝いたします。 パイプラインによってリリース構成のみがビルドされていることがわかります。 デバッグ ビルドも使用しているので、アプリがクラッシュした場合に追加情報を得ることもできます。 それを追加できますか?

Mara: もちろんです。 これを設定したときは、デバッグ ビルドについて検討するのを忘れていました。 一緒にじっくりとそれを追加するのはどうでしょう?

Amita: ビルド ステップを定義する YAML ファイルを見せてもらいましたが、それを変更する方法がわかりません。

Mara: それは問題ありません。 私が入力しているときに確認できます。 それについて一緒に検討できます。

両方のビルド構成をどのように定義しますか?

Space Game Web プロジェクトのリリース構成をビルドして発行する次のタスクについて考えてみましょう。 (このコードを azure-pipelines.yml ファイルに追加しないでください。)

- task: DotNetCoreCLI@2
  displayName: 'Build the project - Release'
  inputs:
    command: 'build'
    arguments: '--no-restore --configuration Release'
    projects: '**/*.csproj'

- task: DotNetCoreCLI@2
  displayName: 'Publish the project - Release'
  inputs:
    command: 'publish'
    projects: '**/*.csproj'
    publishWebProjects: false
    arguments: '--no-build --configuration Release --output $(Build.ArtifactStagingDirectory)/Release'
    zipAfterPublish: true

デバッグ構成をビルドするには、これらの 2 つのタスクを繰り返しますが、ReleaseDebug に置き換えます。

これを行うと、求めている結果は得られますが、ビルドが複雑になったり、要件が変更されたりした場合はどうなるでしょうか? 各ビルド タスクの両方のバリエーションを手動で見つけて変更する必要があります。 追加のビルド要件を追加した後、これらの要件を満たすには、デバッグ構成用とリリース用の 2 つのタスクを作成する必要もあります。

より適切な解決策は、テンプレートを使用することです。

テンプレートとは

"テンプレート" を使用すると、共通のビルド タスクを 1 回だけ定義し、それらのタスクを複数回再利用できます。

ビルド ステップとして親パイプラインからテンプレートを呼び出します。 親パイプラインからテンプレートにパラメーターを渡すことができます。

Mara は、アプリをビルドしてテンプレートとして発行してから、必要な各構成にそのテンプレートを適用するタスクを定義することができます。

テンプレートを定義する

テンプレートを使用すると、共通のビルド タスクを 1 回だけ定義し、それらのタスクを複数回再利用できます。 テンプレートをその親テンプレートからビルド ステップとして呼び出し、親パイプラインからテンプレートにパラメーターを渡します。

ここで、プロジェクト ファイルで定義されている構成をビルドできるテンプレートを作成します。

  1. Visual Studio Code 統合コンソールで、プロジェクトのルートに templates ディレクトリを作成します。

    mkdir templates
    

    実際には、テンプレート ファイルは任意の場所に配置できます。 templates ディレクトリに配置する必要はありません。

  2. Visual Studio Code で [File] > [New File] を選択します。 次に、空のファイルをプロジェクトの templates ディレクトリに build.yml として保存するため、[File] > [Save] の順に選択します。 例としては、~/mslearn-tailspin-spacegame-web/templates のようになります。

    重要

    前と同様に、Windows の [Save as type] リストで、[YAML] を選択します。

  3. Visual Studio Code で、build.yml に次のコードを追加します。

    parameters:
      buildConfiguration: 'Release'
    
    steps:
    - task: DotNetCoreCLI@2
      displayName: 'Build the project - ${{ parameters.buildConfiguration }}'
      inputs:
        command: 'build'
        arguments: '--no-restore --configuration ${{ parameters.buildConfiguration }}'
        projects: '**/*.csproj'
    
    - task: DotNetCoreCLI@2
      displayName: 'Publish the project - ${{ parameters.buildConfiguration }}'
      inputs:
        command: 'publish'
        projects: '**/*.csproj'
        publishWebProjects: false
        arguments: '--no-build --configuration ${{ parameters.buildConfiguration }} --output $(Build.ArtifactStagingDirectory)/${{ parameters.buildConfiguration }}'
        zipAfterPublish: true
    

    これらのタスクは、アプリをビルドして発行するために前に定義したものと同じように見えます。 ただし、テンプレートでは、通常の変数を使用する場合とは異なる方法で入力パラメーターを使用します。 2 つの違いを次に示します。

    • テンプレート ファイルでは、入力を定義するために variables ではなく parameters セクションを使用します。
    • テンプレート ファイルでは、パラメーターの値を読み取るために $() ではなく ${{ }} 構文を使用します。 パラメーターの値を読み取る場合は、その名前に parameters セクションを含めます。 たとえば、${{ parameters.buildConfiguration }} となります。

パイプラインからテンプレートを呼び出す

ここでは、パイプラインからビルドしたばかりのテンプレートを呼び出します。 デバッグ構成に対してこれを 1 回実行してから、リリース構成に対してこのプロセスを繰り返します。

  1. Visual Studio Code で、azure-pipelines.yml を次のように変更します。

    trigger:
    - '*'
    
    pool:
      vmImage: ubuntu-latest
    
    variables:
      buildConfiguration: 'Release'
      wwwrootDir: 'Tailspin.SpaceGame.Web/wwwroot'
      dotnetSdkVersion: '6.x'
    
    steps:
    - task: UseDotNet@2
      displayName: 'Use .NET SDK $(dotnetSdkVersion)'
      inputs:
        version: '$(dotnetSdkVersion)'
    
    - task: Npm@1
      displayName: 'Run npm install'
      inputs:
        verbose: false
    
    - script: './node_modules/.bin/node-sass $(wwwrootDir) --output $(wwwrootDir)'
      displayName: 'Compile Sass assets'
    
    - task: gulp@1
      displayName: 'Run gulp tasks'
    
    - script: 'echo "$(Build.DefinitionName), $(Build.BuildId), $(Build.BuildNumber)" > buildinfo.txt'
      displayName: 'Write build info'
      workingDirectory: $(wwwrootDir)
    
    - task: DotNetCoreCLI@2
      displayName: 'Restore project dependencies'
      inputs:
        command: 'restore'
        projects: '**/*.csproj'
    
    - template: templates/build.yml
      parameters:
        buildConfiguration: 'Debug'
    
    - template: templates/build.yml
      parameters:
        buildConfiguration: 'Release'
    
    - task: PublishBuildArtifacts@1
      displayName: 'Publish Artifact: drop'
      condition: succeeded()
    
    trigger:
    - '*'
    
    pool:
      name: 'Default' #replace if needed with name of your agent pool
    
    variables:
      buildConfiguration: 'Release'
      wwwrootDir: 'Tailspin.SpaceGame.Web/wwwroot'
      dotnetSdkVersion: '6.x'
    
    steps:
    - task: UseDotNet@2
      displayName: 'Use .NET SDK $(dotnetSdkVersion)'
      inputs:
        version: '$(dotnetSdkVersion)'
    
    - task: Npm@1
      displayName: 'Run npm install'
      inputs:
        verbose: false
    
    - script: './node_modules/.bin/node-sass $(wwwrootDir) --output $(wwwrootDir)'
      displayName: 'Compile Sass assets'
    
    - task: gulp@1
      displayName: 'Run gulp tasks'
    
    - script: 'echo "$(Build.DefinitionName), $(Build.BuildId), $(Build.BuildNumber)" > buildinfo.txt'
      displayName: 'Write build info'
      workingDirectory: $(wwwrootDir)
    
    - task: DotNetCoreCLI@2
      displayName: 'Restore project dependencies'
      inputs:
        command: 'restore'
        projects: '**/*.csproj'
    
    - template: templates/build.yml
      parameters:
        buildConfiguration: 'Debug'
    
    - template: templates/build.yml
      parameters:
        buildConfiguration: 'Release'
    
    - task: PublishBuildArtifacts@1
      displayName: 'Publish Artifact: drop'
      condition: succeeded()
    

    このファイルは元のファイルと同じように見えますが、これを使用すると、ビルド タスクと公開タスクが、同じこれらのタスクが実行されるテンプレートへの呼び出しに置き換えられる点で異なります。

    このテンプレートは、構成ごとに 1 回呼び出されることがわかります。 テンプレートに構成名を渡すには、各 template タスクで parameters 引数を使用します。

パイプラインを実行する

ここでは、変更を GitHub にプッシュし、パイプラインの実行を確認します。

  1. 統合ターミナルから、azure-pipelines.yml および templates/build.yml をインデックスに追加し、変更をコミットして、GitHub に変更をプッシュします。

    git add azure-pipelines.yml templates/build.yml
    git commit -m "Support build configurations"
    git push origin build-pipeline
    
  2. 以前に行ったように、Azure Pipelines から、ステップごとにビルドをトレースします。

    パイプラインを実行すると、プロセスによってテンプレート内のタスクが展開されることがわかります。 プロジェクトをビルドして発行するタスクは、2 回 (ビルド構成ごとに 1 回) 実行されます。

    Screenshot of Azure Pipelines showing the expanded template tasks. Included are build and publish tasks for both the Debug and Release configurations.

  3. ビルドが完了したら、概要ページに戻り、発行された成果物を前と同じように選択します。 格納フォルダーを展開します。

    パイプラインによって、デバッグ構成とリリース構成の両方の .zip ファイルが生成されていることがわかります。

    Screenshot of Azure Pipelines showing the packaged application for both Debug and Release configurations.

ブランチをメインにマージする

これで、Mara にとって必要なすべてを実現する作業用ビルド パイプラインが完成しました。

実際には、build-pipeline ブランチを main ブランチにマージする "pull request" を送信します。

ここでは、その手順を省略します。 次のモジュールでは、GitHub でチームとの共同作業を行ういくつかの方法について学習します。これには、pull request の送信、確認、およびマージの方法も含まれます。