Exercício – Criar várias configurações usando modelos

Concluído

Nos exercícios anteriores, você implementou um pipeline que cria o site Space Game. Você começou com um script que executou cada ação de build e mapeou cada ação à tarefa de pipeline correspondente. A saída do pipeline é um arquivo .zip que contém o aplicativo Web compilado.

Neste exercício, você usará um modelo para definir tarefas de build que podem criar qualquer configuração definida no arquivo de projeto. Os modelos permitem que você defina a lógica uma vez e, em seguida, reutilize-a várias vezes. Os modelos combinam o conteúdo de vários arquivos YAML em um único pipeline.

Dica

Esta etapa no módulo é opcional. Se você não quiser saber mais sobre modelos no momento, prossiga para a próxima etapa, Limpar o ambiente do Azure DevOps. Para obter mais informações sobre modelos, confira Tipos e uso de modelos.

Vamos começar conferindo o que Clara e Marina estão fazendo.

A demonstração

Clara, animada em compartilhar seus resultados, tenta achar Marina para mostrar a ela o pipeline de build.

Marina: Estou impressionada que você conseguiu fazer isso funcionar tão rápido! Na verdade, vim vê-la porque recebi um email informando que o build estava pronto. Obrigado! Vi que o pipeline compila apenas a configuração de Lançamento. Também poderemos usar builds de Depuração para capturar informações adicionais se o aplicativo falhar. Podemos adicionar isso?

Clara: Com certeza. Eu me esqueci de considerar os builds de Depuração quando configurei isso. Que tal sentarmos juntas e adicioná-lo?

Marina: Você me mostrou o arquivo YAML que define as etapas de build, mas não tenho certeza se eu saberia como modificá-lo.

Clara: Está bem. Você pode observar enquanto digito. Podemos examiná-lo melhor juntas.

Como definir ambas as configurações de build?

Considere as tarefas a seguir que compilam e publicam a configuração de Versão do projeto Web Space Game. (Não adicione este código ao arquivo 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

Para criar a configuração de Depuração, você pode repetir estas duas tarefas, mas substituir Release por Debug.

Fazer isso produzirá o resultado que você está buscando, mas o que acontece quando o build se torna mais complexo ou seus requisitos mudam? Você precisará localizar e alterar manualmente ambas as variações de cada tarefa de build. Depois de adicionar os requisitos de build extras, você também precisará criar duas tarefas, uma para a configuração de Depuração e outra para Lançamento, para atender a esses requisitos.

Uma solução melhor é usar um modelo.

O que são modelos?

Um modelo permite que você defina tarefas comuns de build uma vez e reutilize essas tarefas várias vezes.

Você chamará um modelo do pipeline pai como uma etapa de build. Passe parâmetros para um modelo por meio do pipeline pai.

Clara pode definir tarefas para compilar e publicar o aplicativo como um modelo e, depois, aplicar esse modelo a cada configuração necessária.

Definir o modelo

Lembre-se que um modelo permite que você defina tarefas comuns de build uma vez e reutilize essas tarefas várias vezes. Chame um modelo por meio de seu modelo pai como uma etapa de build e passe parâmetros para um modelo por meio do pipeline do pai.

Agora você criará um modelo que pode compilar qualquer configuração definida no arquivo de projeto.

  1. No console integrado do Visual Studio Code, na raiz do seu projeto, crie o diretório templates.

    mkdir templates
    

    Na prática, você pode colocar um arquivo de modelo em qualquer local. Não é necessário colocá-los no diretório templates.

  2. No Visual Studio Code, selecione Arquivo > Novo Arquivo. Em seguida, para salvar o arquivo em branco como build.yml no diretório templates do seu projeto, selecione Arquivo > Salvar. Um exemplo seria ~/mslearn-tailspin-spacegame-web/templates.

    Importante

    Como antes, no Windows, na lista Salvar como tipo, selecione YAML.

  3. No Visual Studio Code, adicione esse código ao 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
    

    Essas tarefas parecem as que você definiu anteriormente para compilar e publicar o aplicativo. No entanto, em um modelo, você trabalha com parâmetros de entrada de maneira diferente de variáveis normais. Há duas diferenças:

    • Em um arquivo de modelo, use a seção parameters em vez de variables para definir entradas.
    • Em um arquivo de modelo, use a sintaxe ${{ }} em vez de $() para ler o valor de um parâmetro. Ao ler o valor de um parâmetro, você incluirá a seção parameters no nome dele. Por exemplo, ${{ parameters.buildConfiguration }}.

Chamar o modelo por meio do pipeline

Agora você chamará o modelo que acabou de criar por meio do pipeline. Você fará isso uma vez para a configuração de Depuração e, em seguida, repetirá o processo para a configuração de Versão.

  1. No Visual Studio Code, modifique azure-pipelines.yml como você vê aqui:

    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()
    

    Esse arquivo parece o original, exceto pelo fato de que ele substitui o build e publica tarefas com chamadas ao modelo que executa as mesmas tarefas.

    Você verá que o modelo é chamado uma vez para cada configuração. Para passar o nome de configuração para o modelo, cada tarefa template usa o argumento parameters.

Executar o pipeline

Agora você efetuará push das alterações para o GitHub e verá a execução de pipeline.

  1. No terminal integrado, adicione azure-pipelines.yml e templates/build.yml ao índice, confirme as alterações e envie as alterações por push ao GitHub.

    git add azure-pipelines.yml templates/build.yml
    git commit -m "Support build configurations"
    git push origin build-pipeline
    
  2. No Azure Pipelines, rastreie o build por meio de cada uma das etapas, como você fez anteriormente.

    Conforme o pipeline é executado, você verá que o processo expande as tarefas no modelo. As tarefas que compilam e publicam o projeto são executadas duas vezes, uma para cada configuração de build.

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

  3. Quando o build for concluído, volte para a página de resumo e selecione o artefato publicado como você fez anteriormente. Expanda a pasta de destino.

    Você verá que o pipeline produz um arquivo .zip para as configurações de Depuração e Lançamento.

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

Mesclar o branch no principal

Neste ponto, você tem um pipeline de build funcional que realiza tudo que Clara precisa no momento.

Na prática, você enviará uma solicitação de pull que mescla o branch build-pipeline no branch main.

Ignoraremos essa etapa por enquanto. No próximo módulo, você aprenderá algumas maneiras de colaborar com sua equipe no GitHub, incluindo como enviar, examinar e mesclar solicitações de pull.