# Azure Pipelines から GitHub Actions への移行

GitHub Actions とAzure Pipelinesは、いくつかの構成を共通に持っているため、GitHub Actions への移行は比較的容易であることを意味します。

## 概要

Azure PipelinesとGitHub Actionsでは、コードを自動的にビルド、テスト、公開、リリース、およびデプロイするワークフローを作成できます。 Azure PipelinesとGitHub Actionsは、ワークフローの設定において似ているところがあります。

* ワークフローの設定ファイルはYAMLで書かれ、コードのリポジトリに保存されます。
* ワークフローには 1 つ以上のジョブが含まれます。
* ジョブには 1 つ以上のステップもしくは個別のコマンドが含まれます。
* ステップもしくはタスクは、再利用とコミュニティとの共有が可能です。

詳しくは、「[GitHub Actionsについて](/ja/actions/learn-github-actions/understanding-github-actions)」をご覧ください。

## 主要な相違点

Azure Pipelinesから移行する場合は、次の違いを考慮してください。

* Azure Pipelinesでは、従来の *classic エディター* がサポートされています。これにより、YAML ファイルでパイプライン定義を作成する代わりに、GUI エディターで CI 構成を定義できます。 GitHub Actionsはワークフローの定義にYAMLファイルを使い、グラフィカルなエディタはサポートしていません。
* Azure Pipelinesを使用すると、ジョブ定義の一部の構造を省略できます。 たとえば、ジョブが 1 つだけしかないなら、ジョブを定義する必要はなく、ステップだけを定義すれば済みます。 GitHub Actionsは明示的な設定が必要であり、YAMLの構造は省略できません。
* Azure Pipelinesでは、YAML ファイルで定義\_stages\_をサポートしています。これは、デプロイ ワークフローの作成に使用できます。 GitHub Actionsでは、ステージは個別のYAMLワークフローファイルに分割しなければなりません。
* オンプレミスAzure Pipelinesビルド エージェントは、機能を使用して選択できます。 GitHub Actionsのセルフホステッド ランナーは、ラベルで選択できます。

## ジョブとステップの移行

Azure Pipelinesのジョブとステップは、GitHub Actions のジョブとステップとよく似ています。 どちらのシステムでも、ジョブは以下の特徴を持ちます。

* ジョブは、順番に実行される一連のステップを持ちます。
* ジョブは、個別の仮想マシンまたは個別のコンテナで実行されます。
* ジョブは、既定では並列に実行されますが、順次実行するように設定することもできます。

## スクリプトのステップの移行

スクリプトやシェルのコマンドを、ワークフロー中のステップとして実行できます。 Azure Pipelinesでは、`script` キーを使用するか、`bash`、`powershell`、または `pwsh` キーを使用してスクリプト ステップを指定できます。 スクリプトは [Bash タスク](https://docs.microsoft.com/azure/devops/pipelines/tasks/utility/bash?view=azure-devops)または [PowerShell タスク](https://docs.microsoft.com/azure/devops/pipelines/tasks/utility/powershell?view=azure-devops)への入力として指定することもできます。

GitHub Actions では、`run` キーを使ってすべてのスクリプトを指定します。 特定のシェルを選択するには、スクリプトを提供する際に `shell` キーを指定します。 詳しくは、「[GitHub Actions　のワークフロー構文](/ja/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun)」をご覧ください。

以下は、それぞれのシステムにおける構文の例です。

### スクリプト ステップのAzure Pipelines構文

```yaml
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 構文

```yaml
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
```

## スクリプトのエラー処理の差異

Azure Pipelinesでは、出力が `stderr` に送信された場合にエラーが発生するようにスクリプトを構成できます。 GitHub Actionsはこの設定をサポートしていません。

GitHub Actionsは、可能な場合にはシェルを"fail fast"に設定します。これは、スクリプト中のコマンドの 1 つがエラーコードで終了した場合に即座にスクリプトを停止させるものです。 これに対し、Azure Pipelinesでは、エラーが発生するとすぐに終了するように明示的な構成が必要です。 詳しくは、「[GitHub Actions　のワークフロー構文](/ja/actions/using-workflows/workflow-syntax-for-github-actions#exit-codes-and-error-action-preference)」をご覧ください。

## Windowsの既定のシェルの違い

Azure Pipelinesでは、Windows プラットフォーム上のスクリプトの既定のシェルは、Command シェル (*cmd.exe*) です。 GitHub Actions では、Windows プラットフォーム上のスクリプトの既定のシェルは PowerShell です。 PowerShellは、組み込みコマンド、変数の展開、フロー制御で多少の差異があります。

シンプルなコマンドを実行するなら、コマンドシェルのスクリプトを変更なしにPowerShellで実行できるかもしれません。 しかしほとんどの場合は、PowerShellの構文でスクリプトをアップデートするか、GitHub Actionsに対してスクリプトをPowerShellではなくコマンドシェルで実行するように指定することになります。
`shell` を `cmd` として指定することでこれを実行できます。

以下は、それぞれのシステムにおける構文の例です。

### 既定で CMD を使用する Azure Pipelines の構文

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

### CMD を指定するための GitHub Actions 構文

```yaml
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
```

詳しくは、「[GitHub Actions　のワークフロー構文](/ja/actions/using-workflows/workflow-syntax-for-github-actions#using-a-specific-shell)」をご覧ください。

## 条件と式の構文の移行

Azure PipelinesとGitHub Actionsは、どちらもステップを条件付きで実行できます。 Azure Pipelinesでは、条件式は `condition` キーを使用して指定されます。 GitHub Actionsでは、条件式は `if` キーを使って指定します。

Azure Pipelinesは、式内の関数を使用して、ステップを条件付きで実行します。 それに対し、GitHub Actionsはinfix表記を使います。 たとえば、Azure Pipelines の `eq` 関数をGitHub Actions の `==` 演算子に置き換える必要があります。

以下は、それぞれのシステムにおける構文の例です。

### 条件式の Azure Pipelines 構文

```yaml
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 構文

```yaml
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 }}
```

詳しくは、「[ワークフロー内とアクション内で式を評価する](/ja/actions/learn-github-actions/expressions)」をご覧ください。

## ジョブ間の依存関係

Azure Pipelinesと GitHub Actions の両方で、ジョブの依存関係を設定できます。 どちらのシステムでも、既定ではジョブは並行に実行されますが、ジョブの依存関係を明示的に指定できます。 Azure Pipelinesでは、これは `dependsOn` キーを使用して行われます。 GitHub Actions では、`needs` キーを使って行います。

以下は、それぞれのシステムにおける構文の例です。 ワークフローは `initial` という名前の最初のジョブを開始し、そのジョブが完了すると `fanout1` と `fanout2` という名前の 2 つのジョブが実行されます。 最後に、これらのジョブが完了すると、ジョブ `fanin` が実行されます。

### ジョブ間の依存関係のAzure Pipelines構文

```yaml
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 構文

```yaml
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."
```

詳しくは、「[GitHub Actions　のワークフロー構文](/ja/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idneeds)」をご覧ください。

## タスクのアクションへの移行

Azure Pipelinesでは、複数のワークフローで再利用できるアプリケーション コンポーネントである *tasks* を使用します。 GitHub Actions は\_アクション\_を使います。これは、タスクの実行とワークフローのカスタマイズに利用できます。 どちらのシステムでも、実行するタスクやアクションの名前を、必要な入力のキー/値のペアとともに指定できます。

以下は、それぞれのシステムにおける構文の例です。

### Azure Pipelinesのタスク構文

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

### アクションの GitHub Actions 構文

```yaml
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](https://github.com/marketplace?type=actions) にあります。または、独自のアクションを作成することもできます。 詳しくは、「[自動化の再利用](/ja/actions/creating-actions)」をご覧ください。