연습 - 템플릿을 사용하여 여러 구성 빌드

완료됨

이전 연습에서 Space Game 웹 사이트를 빌드하는 파이프라인을 구현했습니다. 먼저 각 빌드 작업을 수행하고 각 작업을 해당 파이프라인 태스크에 매핑하는 스크립트부터 시작했습니다. 파이프라인의 출력은 컴파일된 웹앱을 포함하는 .zip 파일입니다.

이 연습에서는 템플릿을 사용하여 프로젝트 파일에 정의된 모든 구성을 빌드할 수 있는 빌드 작업을 정의합니다. 템플릿을 사용하면 논리를 한 번 정의한 다음 여러 번 다시 사용할 수 있습니다. 템플릿은 여러 YAML 파일의 내용을 단일 파이프라인으로 결합합니다.

모듈에서 이 단계는 선택 사항입니다. 현재 템플릿에 대해 알아보지 않으려면 다음 단계인 Azure DevOps 환경 정리를 진행합니다. 템플릿에 대한 자세한 내용은 템플릿 유형 및 사용을 참조하세요.

먼저 Mara, Amita와 체크인해 보겠습니다.

데모

Mara는 결과를 공유할 생각에 들떠 있고 빌드 파이프라인을 보여 주기 위해 Amita를 찾아왔습니다.

Amita: 이 일을 이렇게 빨리 해내다니 놀라워요! 사실, 빌드가 준비되었다는 메일을 받았기 때문에 Mara 님을 보러 가려고 했어요. 감사합니다! 파이프라인이 릴리스 구성만으로 빌드된 것을 확인했어요. 또한 디버그 빌드를 사용하여 앱 충돌 시 추가 정보를 캡처할 수 있도록 했는데, 추가할 수 있나요?

Mara: 물론이죠. 설정할 때 디버그 빌드를 고려하지 못했어요. 함께 앉아서 추가해 보면 어떨까요?

Amita: 빌드 단계를 정의하는 YAML 파일을 보여주셨지만 수정하는 방법을 모르겠어요.

Mara: 괜찮아요. 입력하는 동안 한 번 보세요. 함께 생각해 봐요.

두 빌드 구성을 어떻게 정의할 수 있나요?

Space Game 웹 프로젝트의 릴리스 구성을 빌드, 게시 다음 작업을 고려합니다. (이 코드를 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

디버그 구성을 빌드하려면 이러한 두 가지 작업을 반복할 수 있지만 ReleaseDebug로 바꿉니다.

이렇게 하면 원하는 결과를 얻을 수 있지만 빌드가 더 복잡하거나 요구 사항이 변경되면 어떻게 될까요? 각 빌드 작업의 변형은 수동으로 찾아서 변경해야 합니다. 빌드 요구 사항을 추가한 후에는 디버그 구성과 릴리스를 위한 작업을 하나씩 두 개 만들어 해당 요구 사항을 충족해야 합니다.

더 나은 해결 방법은 템플릿을 사용하는 것입니다.

템플릿이란?

템플릿을 사용하면 공통 빌드 작업을 한 번 정의한 다음, 해당 작업을 여러 번 다시 사용할 수 있습니다.

상위 파이프라인에서 템플릿을 빌드 단계로 호출합니다. 상위 파이프라인에서 템플릿으로 매개 변수를 전달할 수 있습니다.

Mara는 앱을 빌드하여 템플릿으로 게시하는 작업을 정의한 다음 필요한 각 구성에 해당 템플릿을 적용할 수 있습니다.

템플릿 정의

템플릿을 사용하면 공통 빌드 작업을 한 번 정의한 다음, 해당 작업을 여러 번 다시 사용할 수 있음을 기억하세요. 부모 템플릿에서 템플릿을 빌드 단계로 호출하고 부모 파이프라인에서 템플릿으로 매개 변수를 전달합니다.

이제 프로젝트 파일에 정의된 구성을 빌드할 수 있는 템플릿을 만듭니다.

  1. Visual Studio Code 통합 콘솔의 프로젝트 루트에서 ‘템플릿’ 디렉터리를 만듭니다.

    mkdir templates
    

    실제로 템플릿 파일은 모든 위치에 저장할 수 있습니다. 템플릿을 ‘템플릿’ 디렉터리에 저장할 필요는 없습니다.

  2. Visual Studio Code에서 파일 > 새 파일을 선택합니다. 그런 다음 프로젝트의 templates 디렉터리에 빈 파일을 build.yml로 저장하려면 파일 > 저장을 선택합니다. 예를 들어 ~/mslearn-tailspin-spacegame-web/templates가 될 수 있습니다.

    중요

    이전과 마찬가지로 Windows에서 파일 형식 목록에서 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
    

    이러한 작업은 애플리케이션을 빌드 및 게시하기 위해 앞에서 정의한 것과 같습니다. 하지만 템플릿에서는 일반적인 변수로 작업하는 것과는 다른 방식으로 입력 매개 변수를 사용합니다. 다음과 같은 두 가지 차이점이 있습니다.

    • 템플릿 파일에서는 variables 대신 parameters 섹션을 사용하여 입력을 정의합니다.
    • 템플릿 파일에서는 $() 대신 ${{ }} 구문을 사용하여 매개 변수의 값을 읽습니다. 매개 변수의 값을 읽을 때 매개 변수 이름에 parameters 섹션을 포함합니다. 예: ${{ parameters.buildConfiguration }}

파이프라인에서 템플릿 호출

이제 파이프라인에서 방금 빌드한 템플릿을 호출합니다. 디버그 구성에 대해 이와 같이 한 번 수행하고 릴리스 구성에 대해 해당 프로세스를 반복합니다.

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

    이 파일은 빌드와 게시 작업을 동일한 작업을 수행하는 템플릿 호출로 바꾼다는 점을 제외하고 원본 파일과 같습니다.

    각 구성에 대해 템플릿이 한 번 호출되는 것을 볼 수 있습니다. 구성 이름을 템플릿에 전달하기 위해 각 template 작업은 parameters 인수를 사용합니다.

파이프라인 실행

변경 내용을 GitHub로 푸시하고 파이프라인 실행을 확인합니다.

  1. 통합 터미널에서 azure-pipelines.ymltemplates/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에서 각 단계를 진행하는 동안 빌드를 추적합니다.

    파이프라인이 실행되면 프로세스가 템플릿 내에서 작업을 확장하는 것을 볼 수 있습니다. 프로젝트를 빌드 및 게시하는 작업은 각 빌드 구성에 대해 한 번씩 두 번 실행됩니다.

    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분기에 병합하는 ‘끌어오기 요청’을 제출했습니다.

지금은 이 단계를 건너뜁니다. 다음 모듈에서는 끌어오기 요청을 제출, 검토, 병합하는 방법을 비롯하여 GitHub에서 팀과 협업하는 몇 가지 방법을 알아봅니다.