Azure Pipelines에서 GitHub Actions로 마이그레이션하기

Azure Pipelines에서 GitHub Actions로 마이그레이션하기

GitHub Actions와 Azure Pipelines는 구성상 몇 가지 유사점을 공유하기 때문에 GitHub Actions로의 마이그레이션이 비교적 간단할 수 있어요. 이 가이드에서는 두 시스템의 차이점과 마이그레이션 시 유의할 점을 알려드릴게요.

출처: 문서

본문

Introduction

Azure Pipelines와 GitHub Actions는 모두 코드를 자동으로 빌드, 테스트, 게시, 릴리스, 배포하는 워크플로우를 만들 수 있게 해 줘요. Azure Pipelines와 GitHub Actions는 워크플로우 구성에서 몇 가지 유사점을 공유해요.

  • 워크플로우 구성 파일은 YAML로 작성되고 코드의 저장소에 저장돼요.
  • 워크플로우에는 하나 이상의 job이 포함돼요.
  • job에는 하나 이상의 단계 또는 개별 명령이 포함돼요.
  • 단계나 작업은 재사용되고 커뮤니티와 공유될 수 있어요.

자세한 내용은 Understanding GitHub Actions 문서를 참고하세요.

Key differences

Azure Pipelines에서 마이그레이션할 때 다음 차이점을 고려하세요.

  • Azure Pipelines는 레거시 *클래식 편집기(classic editor)*를 지원해서 YAML 파일로 파이프라인 정의를 만들지 않고 GUI 편집기에서 CI 구성을 정의할 수 있어요. GitHub Actions는 YAML 파일을 사용해서 워크플로우를 정의하며 그래픽 편집기를 지원하지 않아요.
  • Azure Pipelines는 job 정의에서 일부 구조를 생략할 수 있어요. 예를 들어 job이 하나만 있다면 job을 정의할 필요 없이 단계만 정의하면 돼요. GitHub Actions는 명시적 구성을 요구하며 YAML 구조를 생략할 수 없어요.
  • Azure Pipelines는 YAML 파일에 정의된 stages를 지원해서 배포 워크플로우를 만들 수 있어요. GitHub Actions는 stages를 별도의 YAML 워크플로우 파일로 분리해야 해요.
  • 온프레미스 Azure Pipelines 빌드 에이전트는 기능(capabilities)으로 선택할 수 있어요. GitHub Actions 자체 호스팅 러너는 레이블로 선택할 수 있어요.

Migrating jobs and steps

Azure Pipelines의 job과 단계는 GitHub Actions의 job과 단계와 매우 유사해요. 두 시스템 모두에서 job은 다음 특성을 가져요.

  • job은 순차적으로 실행되는 일련의 단계를 포함해요.
  • job은 별도의 가상 머신 또는 별도의 컨테이너에서 실행돼요.
  • job은 기본적으로 병렬로 실행되지만 순차적으로 실행되도록 구성할 수 있어요.

Migrating script steps

워크플로우의 단계로 스크립트 또는 셸 명령을 실행할 수 있어요. Azure Pipelines에서는 script 키를 사용하거나 bash, powershell, pwsh 키를 사용해서 스크립트 단계를 지정할 수 있어요. 스크립트는 Bash task 또는 PowerShell task의 입력으로 지정할 수도 있어요.

GitHub Actions에서는 모든 스크립트가 run 키로 지정돼요. 특정 셸을 선택하려면 스크립트를 제공할 때 shell 키를 지정할 수 있어요. 자세한 내용은 Workflow syntax for GitHub Actions 문서를 참고하세요.

다음은 각 시스템의 문법 예시예요.

Azure Pipelines syntax for script steps

jobs:
  - job: scripts
    pool:
      vmImage: 'windows-latest'
    steps:
      - script: echo "This step runs in the default shell"
      - bash: echo "This step runs in bash"
      - pwsh: Write-Host "This step runs in PowerShell Core"
      - task: PowerShell@2
        inputs:
          script: Write-Host "This step runs in PowerShell"

GitHub Actions syntax for script steps

jobs:
  scripts:
    runs-on: windows-latest
    steps:
      - run: echo "This step runs in the default shell"
      - run: echo "This step runs in bash"
        shell: bash
      - run: Write-Host "This step runs in PowerShell Core"
        shell: pwsh
      - run: Write-Host "This step runs in PowerShell"
        shell: powershell

Differences in script error handling

Azure Pipelines에서 스크립트는 stderr에 출력이 전송되면 오류로 처리되도록 구성할 수 있어요. GitHub Actions는 이 구성을 지원하지 않아요.

GitHub Actions는 가능할 때마다 셸을 "빠르게 실패(fail fast)"하도록 구성해서, 스크립트의 명령 중 하나가 오류 코드로 종료되면 스크립트를 즉시 중지해요. 반면 Azure Pipelines는 오류 시 즉시 종료하도록 명시적 구성을 요구해요. 자세한 내용은 Workflow syntax for GitHub Actions 문서를 참고하세요.

Differences in the default shell on Windows

Azure Pipelines에서 Windows 플랫폼의 스크립트 기본 셸은 명령 셸(cmd.exe)이에요. GitHub Actions에서 Windows 플랫폼의 스크립트 기본 셸은 PowerShell이에요. PowerShell은 기본 제공 명령, 변수 확장, 흐름 제어에서 몇 가지 차이가 있어요.

간단한 명령을 실행한다면 PowerShell에서 명령 셸 스크립트를 변경 없이 실행할 수 있을 수 있어요. 하지만 대부분의 경우 PowerShell 구문으로 스크립트를 업데이트하거나, GitHub Actions가 PowerShell 대신 명령 셸로 스크립트를 실행하도록 지시해야 해요. shellcmd로 지정하면 됩니다.

다음은 각 시스템의 문법 예시예요.

Azure Pipelines syntax using CMD by default

jobs:
  - job: run_command
    pool:
      vmImage: 'windows-latest'
    steps:
      - script: echo "This step runs in CMD on Windows by default"

GitHub Actions syntax for specifying CMD

jobs:
  run_command:
    runs-on: windows-latest
    steps:
      - run: echo "This step runs in PowerShell on Windows by default"
      - run: echo "This step runs in CMD on Windows explicitly"
        shell: cmd

자세한 내용은 Workflow syntax for GitHub Actions 문서를 참고하세요.

Migrating conditionals and expression syntax

Azure Pipelines와 GitHub Actions는 모두 단계를 조건부로 실행할 수 있어요. Azure Pipelines에서는 조건식이 condition 키로 지정돼요. GitHub Actions에서는 조건식이 if 키로 지정돼요.

Azure Pipelines는 조건부로 단계를 실행하기 위해 표현식 내에서 함수를 사용해요. 반면 GitHub Actions는 중위 표기법(infix notation)을 사용해요. 예를 들어 Azure Pipelines의 eq 함수를 GitHub Actions의 == 연산자로 바꿔야 해요.

다음은 각 시스템의 문법 예시예요.

Azure Pipelines syntax for conditional expressions

jobs:
  - job: conditional
    pool:
      vmImage: 'ubuntu-latest'
    steps:
      - script: echo "This step runs with str equals 'ABC' and num equals 123"
        condition: and(eq(variables.str, 'ABC'), eq(variables.num, 123))

GitHub Actions syntax for conditional expressions

jobs:
  conditional:
    runs-on: ubuntu-latest
    steps:
      - run: echo "This step runs with str equals 'ABC' and num equals 123"
        if: ${{ env.str == 'ABC' && env.num == 123 }}

자세한 내용은 Evaluate expressions in workflows and actions 문서를 참고하세요.

Dependencies between jobs

Azure Pipelines와 GitHub Actions 모두 job에 대한 의존성을 설정할 수 있어요. 두 시스템 모두에서 job은 기본적으로 병렬로 실행되지만, job 의존성을 명시적으로 지정할 수 있어요. Azure Pipelines에서는 dependsOn 키로 수행해요. GitHub Actions에서는 needs 키로 수행해요.

다음은 각 시스템의 문법 예시예요. 워크플로우는 initial이라는 첫 번째 job을 시작하고, 해당 job이 완료되면 fanout1fanout2라는 두 job이 실행돼요. 마지막으로 해당 job들이 완료되면 fanin job이 실행돼요.

Azure Pipelines syntax for dependencies between jobs

jobs:
  - job: initial
    pool:
      vmImage: 'ubuntu-latest'
    steps:
      - script: echo "This job will be run first."
  - job: fanout1
    pool:
      vmImage: 'ubuntu-latest'
    dependsOn: initial
    steps:
      - script: echo "This job will run after the initial job, in parallel with fanout2."
  - job: fanout2
    pool:
      vmImage: 'ubuntu-latest'
    dependsOn: initial
    steps:
      - script: echo "This job will run after the initial job, in parallel with fanout1."
  - job: fanin
    pool:
      vmImage: 'ubuntu-latest'
    dependsOn: [fanout1, fanout2]
    steps:
      - script: echo "This job will run after fanout1 and fanout2 have finished."

GitHub Actions syntax for dependencies between jobs

jobs:
  initial:
    runs-on: ubuntu-latest
    steps:
      - run: echo "This job will be run first."
  fanout1:
    runs-on: ubuntu-latest
    needs: initial
    steps:
      - run: echo "This job will run after the initial job, in parallel with fanout2."
  fanout2:
    runs-on: ubuntu-latest
    needs: initial
    steps:
      - run: echo "This job will run after the initial job, in parallel with fanout1."
  fanin:
    runs-on: ubuntu-latest
    needs: [fanout1, fanout2]
    steps:
      - run: echo "This job will run after fanout1 and fanout2 have finished."

자세한 내용은 Workflow syntax for GitHub Actions 문서를 참고하세요.

Migrating tasks to actions

Azure Pipelines는 여러 워크플로우에서 재사용할 수 있는 애플리케이션 구성 요소인 tasks를 사용해요. GitHub Actions는 actions를 사용해서 작업을 수행하고 워크플로우를 사용자 지정할 수 있어요. 두 시스템 모두에서 실행할 작업 또는 액션의 이름과 필수 입력을 키/값 쌍으로 지정할 수 있어요.

다음은 각 시스템의 문법 예시예요.

Azure Pipelines syntax for tasks

jobs:
  - job: run_python
    pool:
      vmImage: 'ubuntu-latest'
    steps:
      - task: UsePythonVersion@0
        inputs:
          versionSpec: '3.7'
          architecture: 'x64'
      - script: python script.py

GitHub Actions syntax for actions

jobs:
  run_python:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/setup-python@v5
        with:
          python-version: '3.7'
          architecture: 'x64'
      - run: python script.py

워크플로우에서 사용할 수 있는 액션은 GitHub Marketplace에서 찾거나 직접 만들 수 있어요. 자세한 내용은 Reusing automations 문서를 참고하세요.

더 알아보기 (Learn more)