연습 - 테스트 단계로 승격

완료됨

릴리스 파이프라인에는 단계가 여전히 두 개 있지만 이전과는 다릅니다. 단계는 ‘빌드’와 ‘개발’입니다. GitHub로 푸시하는 모든 변경 내용은 ‘빌드’ 단계가 실행되도록 트리거합니다. ‘개발’ 단계는 변경 내용이 ‘릴리스’ 분기에 있는 경우에만 실행됩니다. 여기에서 파이프라인에 ‘테스트’ 단계를 추가합니다.

팀은 매일 아침 3시에 예약된 트리거를 사용하여 개발 단계에서 테스트 단계로 빌드를 승격하기로 했습니다. 예약된 트리거를 설정하려면 다음 작업을 수행합니다.

  • 빌드 구성에서 일정을 정의합니다.
  • ‘테스트’ 단계를 정의하는데, 여기에는 빌드 이유가 Schedule로 표시된 경우에만 단계를 실행하는 조건이 포함됩니다.

학습 목적으로, 여기서는 일정을 정의하되 빌드가 개발에서 테스트로 직접 이동하도록 허용합니다. 이렇게 설정하면 일정이 트리거될 때까지 기다릴 필요가 없습니다. 이 모듈을 완료한 후에 다른 cron 식을 사용하여 예약된 시간에만 테스트 단계를 실행해 보세요.

테스트 단계로 변경 내용 승격

여기서는 파이프라인 구성을 수정하여 빌드를 ‘테스트’ 단계로 배포합니다.

  1. Visual Studio Code에서 azure-pipelines.yml을 다음과 같이 수정합니다.

    trigger:
    - '*'
    
    variables:
      buildConfiguration: 'Release'
      releaseBranchName: 'release'
    
    schedules:
    - cron: '0 3 * * *'
      displayName: 'Deploy every day at 3 A.M.'
      branches:
        include:
        - release
      always: false 
    
    stages:
    - stage: 'Build'
      displayName: 'Build the web application'
      jobs: 
      - job: 'Build'
        displayName: 'Build job'
        pool:
          vmImage: 'ubuntu-20.04'
          demands:
          - npm
    
        variables:
          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'
    
        - task: DotNetCoreCLI@2
          displayName: 'Build the project - $(buildConfiguration)'
          inputs:
            command: 'build'
            arguments: '--no-restore --configuration $(buildConfiguration)'
            projects: '**/*.csproj'
    
        - task: DotNetCoreCLI@2
          displayName: 'Publish the project - $(buildConfiguration)'
          inputs:
            command: 'publish'
            projects: '**/*.csproj'
            publishWebProjects: false
            arguments: '--no-build --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)/$(buildConfiguration)'
            zipAfterPublish: true
    
        - publish: '$(Build.ArtifactStagingDirectory)'
          artifact: drop
    
    - stage: 'Dev'
      displayName: 'Deploy to the dev environment'
      dependsOn: Build
      condition: |
        and
        (
          succeeded(),
          eq(variables['Build.SourceBranchName'], variables['releaseBranchName'])
        )
      jobs:
      - deployment: Deploy
        pool:
          vmImage: 'ubuntu-20.04'
        environment: dev
        variables:
        - group: Release
        strategy:
          runOnce:
            deploy:
              steps:
              - download: current
                artifact: drop
              - task: AzureWebApp@1
                displayName: 'Azure App Service Deploy: website'
                inputs:
                  azureSubscription: 'Resource Manager - Tailspin - Space Game'
                  appName: '$(WebAppNameDev)'
                  package: '$(Pipeline.Workspace)/drop/$(buildConfiguration)/*.zip'
    
    - stage: 'Test'
      displayName: 'Deploy to the test environment'
      dependsOn: Dev
      #condition: eq(variables['Build.Reason'], 'Schedule')
      jobs:
      - deployment: Deploy
        pool:
          vmImage: 'ubuntu-20.04'
        environment: test
        variables:
        - group: 'Release'
        strategy:
          runOnce:
            deploy:
              steps:
              - download: current
                artifact: drop
              - task: AzureWebApp@1
                displayName: 'Azure App Service Deploy: website'
                inputs:
                  azureSubscription: 'Resource Manager - Tailspin - Space Game'
                  appName: '$(WebAppNameTest)'
                  package: '$(Pipeline.Workspace)/drop/$(buildConfiguration)/*.zip'
    

    schedules 섹션에서는 cron 식 하나를 정의합니다. 구성에 식을 두 개 이상 정의할 수 있습니다. 이 식은 매일 오전 3시에 릴리스 분기를 대상으로 실행되도록 파이프라인을 트리거합니다. always 플래그가 false로 설정되어 릴리스 분기에 이전 실행에서 변경된 내용이 포함된 경우에만 파이프라인이 실행됩니다.

    Test 단계는 빌드 이유가 Schedule과 동일한 경우에만 단계를 실행하는 조건을 정의합니다. (빌드 이유는 기본 제공되는 Build.Reason 변수가 정의합니다.) 이 구성이 false이면 해당 단계를 건너뛰지만 이전 단계는 계속 실행합니다.

    참고

    이 구성은 학습을 위해 표시됩니다. 일정이 트리거될 때까지 기다리지 않고 변경 내용을 개발에서 테스트로 이동할 수 있도록 주석 처리됩니다.

  2. 통합 터미널에서 azure-pipelines.yml을 인덱스에 추가합니다. 그런 다음 변경 내용을 커밋하고 GitHub로 푸시합니다.

    해당하는 Git 명령을 실행하기 전에 azure-pipelines.yml을 저장합니다.

    git add azure-pipelines.yml
    git commit -m "Deploy to the Test stage"
    git push origin release
    
  3. Azure Pipelines에서 빌드로 이동합니다. 실행되는 빌드를 추적합니다.

  4. 빌드가 완료되면 뒤로 단추를 선택하여 요약 페이지로 돌아갑니다.

    A screenshot of Azure Pipelines showing three completed stages: Build, Dev, and Test.

    배포가 성공적으로 완료된 것을 확인할 수 있습니다.

  5. 웹 브라우저에서 테스트 환경의 App Service 인스턴스와 연결된 URL로 이동합니다.

    브라우저 탭이 아직 열려 있는 경우 페이지를 새로 고칩니다. URL을 기억할 수 없는 경우 Azure Portal의 App Service 세부 정보 페이지에서 찾습니다.

    Space Game 웹 사이트가 App Service에 배포되어 실행 중입니다.

    A screenshot of a web browser showing the Space Game website in the Test environment.

  6. 선택적 단계로 Azure Pipelines에서 환경을 선택합니다. 그런 다음 테스트 환경을 선택합니다.

    Azure Pipelines에서는 배포 기록을 기록합니다. 기록에서 코드 커밋과 작업 항목에 대한 환경의 변경 내용을 다시 추적할 수 있습니다.

    A screenshot of Azure Pipelines showing the deployment history. The history shows one successful deployment.

Andy와 Mara가 파이프라인에 ‘테스트’ 단계를 추가하고 결과를 Amita에게 보여 줍니다.

Amita: 변경 내용이 빌드된 후 배포되어 매일 아침 테스트할 수 있다는 점이 아주 마음에 드네요. 그런데 변경 내용이 스테이징에 도달하는 시점을 제어할 방법이 안 보이네요.

Mara: 예, 자동화를 통해 배포하면 많은 시간이 절약됩니다. 아시다시피, 우리는 예약된 트리거만 포함했어요. Tim을 위해 스테이징 환경을 설정하면 Amita를 위해 릴리스 승인을 추가해 보겠습니다. 이렇게 하면 준비가 되었을 때만 변경 내용이 스테이징으로 이동됩니다.