Git/GitHub基礎 #4 - GitHub Actions

Last Edited: 2/19/2025

このブログ記事では、CI/CDに関するGitHub Actionsを紹介します。

DevOps

これまで、分散型バージョン管理システムとしてのGitの基本機能と、GitリモートリポジトリのホスティングサービスとしてのGitHubについて説明してきました。 これらは、他の人々と共同でプロジェクトを進める上で基本的なものです。しかし、GitHubはDevOpsプラクティスを促進する追加機能も提供しています。 この記事では、そのような機能の1つであるGitHub Actionsと、CI/CDにおけるその有用性について説明します。

YAMLファイル

GitHub Actionsを使用すると、プッシュ、プル、プルリクエストのマージなど、任意のイベントトリガーで仮想ランナーを使用して任意のコマンドを実行できます。 環境設定と実行するコマンドは、ymlまたはyaml拡張子を持つYAMLファイルで指定できます。YAMLは、人間が読みやすく、計算処理能力の高いデータシリアライゼーション言語で、 設定ファイルによく使用されます。JSONの代替として機能し、キーと値のペアを保存しますが、構文が異なります。

key1: value1 # 文字列
key2: 2 # 数値
key3: true # ブール値
key4: on # ブール値 (true & false, on & off, yes & no)
key5: > 
    When > symbol is used, this long sentence is 
    merged into one sentence.
key6: |
    When | symbol is used, the new lines and whitespaces 
    are preserved. 

上記の例は、文字列、数値、ブール値でのキーと値のペアを示しています。YAMLは自動的に型を推論しますが、必要に応じて文字列には二重引用符を使用できます。 長い文字列は、上記のように>|を使用して複数行に分割できます。配列とオブジェクトも以下のように表現できます:

# 配列
array1: 
  - value1
  - value2
  - value3
 
array2: [value1, value2, value3]
 
# オブジェクト
object:
  key1: value1
  key2: value2
  key3: value3
 
# オブジェクトの配列
array3:
  - key1: value1
    key2: value2
  - key1: value3
    key2: value4

配列とオブジェクトを組み合わせることで、複雑なオブジェクトタイプを表現できます。GitHub actionを設定するには、ルートレベルに.githubディレクトリを作成し、 workflowsサブディレクトリを追加して、その中に設定を含むYAMLファイルを配置します。

継続的インテグレーション

継続的インテグレーション(CI)は、開発者がソフトウェアを改善するために、価値のある小さなコード変更を段階的にプッシュすべきというプラクティスです。 CIを実現するには、破壊的な変更が適用される前に検出される必要があり、理想的には自動的に行われるべきです。GitHub Actionsを使用すると、 プッシュやプルリクエストなどのイベント時にテストスクリプトを自動的に実行し、CIを促進できます。以下はテストを実行するワークフローの例です:

testing.yaml
name: "Testing"
 
# ワークフロー実行のイベント
on:
  pull_request:
    branches:
      - main
 
# ワークフロー
jobs:
  test: # ワークフローの名前
    runs-on: ubuntu-latest # OS (mac, windows, ubuntu)
    steps: 
      - uses: actions/checkout@v4 # ソースコードにアクセスするプリセットアクション
      - uses: actions/setup-node@v4 # NodeJSをセットアップするプリセットアクション
        with: 
          node-version: 20
      - name: Install Dependencies
        run: npm ci # clean isntall
      - name: Run Test
        run: npm test # ソースコードのテストを実行
      - run: npm run build # ソースコードがコンパイルするかを確認

上記のYAMLファイルは、mainブランチへのプルリクエストが作成されたときに、UbuntuにインストールされたNodeJS上でコードベースで定義されたテストスクリプトを使用して ソースコードをテストするワークフローを設定します。環境設定を簡素化するために、actions/checkoutactions/setup-nodeなどのプリセットアクションを使用できます。 各コマンドには任意で名前を割り当てることができ、GitHubインターフェースに表示されます(そうでない場合は、デフォルトでRun <command>と表示されます)。 コマンドが失敗した場合、GitHub上で自動的にエラーメッセージが表示されるため、コードをダウンロードしてテストを手動で実行する必要なくデバッグを行えます。

jobs:
  test:
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
        node-version: [18, 20]
    runs-on: ${{ matrix.os }}
    steps: 
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: 
          node-version: ${{ matrix.node-version }}

異なるOSとバージョンでテストとビルドを行うには、strategy: matrix:を使用できます。上記の例では、この戦略を使用してOSとNode.jsバージョンの6つの組み合わせをテストしており、 クロスプラットフォームの互換性が必要なソフトウェアに有効です。

継続的デリバリー

継続的デリバリー(CD)は、開発者がサーバーを毎回手動で設定することなく、継続的にソフトウェアをリリースできるという概念です。これもGitHub Actionsを使用して実現できます。 以下はSSHキーを使用してAWSにソフトウェアをデプロイするワークフローの例です:

deploy.yaml
name: "Deployment"
 
on:
  push: # mainに直接プッシュ、またはプルリクエストのマージ時に実行
    branches:
      - main
 
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps: 
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: 
          node-version: 20
      - name: Install Dependencies
        run: npm ci
      - run: npm run build
      - name: Get SSH key and sort permissions out
        run: |
          mkdir -p ~/.ssh
          echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa && chmod 600 ~/.ssh/id_rsa
      - name: Deploy using SCP
        run: > 
          scp -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa 
          -r ./dist/*${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:~node-app
      - name: Restart the server
        run: > 
          ssh -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} 
          "cd ~/node-app && npm install && pm2 restart 0"

SSHキーやAPIキーなど、リポジトリに属さないシークレットは、"Settings"の"Action secrets"セクションに保存でき、ワークフローはsecrets.を介してアクセスできます。 上記のワークフローは、SSHキーとパーミッションを設定し、SCP(ファイル送信用のネットワークプロトコル)を使用してファイルを送信し、pm2でサーバーを再起動します。 スクリプトの詳細はリモートサーバーのアーキテクチャによって異なりますが、ワークフローを設定すれば、デリバリーを自動化でき、非常に便利です(多くの有料ホスティングサービスも自動的にこれを実行します)。

結論

この記事では、DevOpsに不可欠なYAMLファイル、CI/CD、およびGitHub Actionsを紹介しました。YAMLファイルは複数のDevOpsツールで使用され、 CI/CDはDevOpsプラクティスの中核です。GitHub Actions(プリセットアクション、アクション例、イベントなど)の詳細については、 以下に引用された公式ドキュメントを参照してください。

リソース