【Git・GitHub操作ガイド】第8章 GitHub Actions入門:面倒な作業は自動化!開発効率を上げる第一歩!

本記事の目的

手動でテストを実行し、デプロイを行うことは学ぶことが多く確実ですが、これらの定型作業を繰り返すようになると、ヒューマンエラーを起こすこともあり、手作業は時間もかかります。
もし、リポジトリに「執事」がいて、決まったルールに従ってこれらの作業を自動でこなしてくれたら、どうでしょうか?すごく、楽になりますよね!

GitHub Actionsは、GitHubに組み込まれた強力な自動化(CI/CD ※)ツールです。
コードがプッシュされた時や、プルリクエストが作成された時などをトリガーに、テスト、ビルド、デプロイといった一連の作業を自動実行することができます。

※ CI/CD: Continuous Integration / Continuous Delivery (継続的インテグレーション / 継続的デリバリー)

それでは、GitHub Actionsを詳しく見ていきましょう!


目次


対象読者

  • GitおよびGitHubの基本的な操作(リポジトリの作成、プッシュ、プルリクエストの作成など)に慣れている方。
  • 開発におけるテストやデプロイといった手作業を自動化して、効率を上げたいと考えている方。
  • CI/CDという言葉は聞いたことがあるが、何から始めれば良いか分からないプログラミング初学者。

GitHub Actionsとは

GitHub Actionsは、ソースコード管理を行うGitHubに深く統合された、CI/CD(継続的インテグレーション/継続的デリバリー)を実現するためのプラットフォームです。

開発ライフサイクル全体(コーディング → ビルド → テスト → リリース → デプロイ)の中で、特にビルド、テスト、デプロイといった、これまで手動で行われがちだった工程を自動化する役割を担います。

JenkinsやCircleCIといった他のCI/CDツールと比較した場合、GitHubマーケットプレイスで公開されている豊富な「アクション」を組み合わせるだけで手軽に始められる点や、開発の拠点であるGitHub上で設定から実行結果の確認までが完結するシンプルさが大きな強みです。


料金について

GitHub Actionsは、プランに応じて無料利用枠が提供されており、特にパブリックリポジトリでは無料で利用できます。プライベートリポジトリで無料枠を超過した場合、従量課金が発生します。

コストが発生する主な要因は以下の2つです。

  1. 実行時間(分単位):
    • ワークフローが仮想環境(ランナー)で実行された時間です。
    • OSによって1分あたりの料金が異なり、一般的に Linux < Windows < macOS の順に高くなります。特別な理由がない限り、Linuxランナー(ubuntu-latest)を選択するとコストを抑えられます。
  2. ストレージ(GB単位):
    • ワークフローで作成されたアーティファクト(Artifacts)キャッシュ(Cache)が使用するストレージ容量です。
    • 不要になったアーティファクトやキャッシュは定期的に削除することが、ストレージ料金の節約に繋がります。

最新の料金体系や各プランの無料枠については、必ず以下の公式ページで確認してください。


ここからは、GitHub Actionsの仕組みを理解するための重要な2つのコンセプト、「全体像(構成要素とその関係)」と「基本的な仕組み」について見ていきましょう。
まずは、GitHub、実行環境といった構成要素たちがどのように連携するのか、大きな視点から全体像を掴みます。
次に、ワークフローを定義するための具体的な手順を詳しく解説します。


GitHub Actionsを支える構成要素とその関係

GitHub Actionsの仕組みを理解するために、まずは「誰が」「どこで」「何を」しているのか、登場人物とその関係性を整理しましょう。

  1. 開発者とローカル環境
    • すべての始まりは、あなたのPCであるローカル環境です。あなたはここでコードを書き、git commitで変更を記録し、git pushでGitHubに送信します。
  2. GitHub
    • プッシュされたコードを受け取るのがGitHubです。GitHubは単なるコードの保管場所ではありません。リポジトリ内の .github/workflows/ ディレクトリに置かれたワークフロー定義ファイル(YAML)を監視しています。
  3. ワークフロー (Workflow)
    • pushやプルリクエスト作成といった特定のイベントをきっかけに起動する、自動化プロセス全体を指します。1つのワークフローは、1つ以上のジョブから構成されます。
  4. ジョブ (Job)
    • ワークフローを構成する個々のタスクです。例えば「テストを実行するジョブ」「ビルドするジョブ」のように役割分担をします。各ジョブは、原則として独立しており、並行して実行できます。
  5. 仮想環境 (ランナー)
    • 各ジョブが実行される場所が、GitHubによって提供される仮想環境(ランナー)です。ジョブが開始されるたびに、まっさらな仮想マシン(例: ubuntu-latest)が用意され、その中でステップが実行されます。重要なのは、ジョブごとに独立した仮想環境が用意されるという点です。これにより、ジョブ間の依存関係がなくなり、クリーンな状態でタスクを実行できます。

この流れを図で表すと、以下のようになります。

GitHub Actionsの処理の流れ

GitHub Actionsの基本的な仕組み

GitHub Actionsの仕組みは、「いつ(When)」「何を(What)」「どのように(How)」を実行するかを定義した「レシピ(ワークフローファイル)」をリポジトリに置くだけ、というシンプルなものです。

  1. ワークフローファイルを作成する
    リポジトリの.github/workflows/という名前の特別なディレクトリに、YAML形式で「レシピ」を書きます。
  2. トリガーを定義する (on)
    mainブランチにプッシュされた時」「プルリクエストが作成された時」など、ワークフローが起動するきっかけを指定します。
  3. ジョブを定義する (jobs)
    実行したい作業のまとまり(ジョブ)を定義します。例えば、「テスト」ジョブや「デプロイ」ジョブなどです。各ジョブは、独立した仮想マシン上で実行されます。
  4. ステップを定義する (steps)
    ジョブの中で実行される、具体的なコマンドや処理を一つずつ順番に記述します。これが実際の「調理手順」にあたります。

この一連の流れを視覚的に表すと、以下のようになります。

GitHub Actionsの基本的な仕組みの一連の流れ

このレシピを一度用意すれば、あとは執事(GitHub Actions)が24時間365日、あなたの代わりに忠実に作業をこなしてくれます。


ワークフローの概念と実践的な例

ここでは、具体的なワークフローの例を通して、その概念を実践的に学びます。

これから紹介する ci.yml というワークフローファイルは、Node.jsプロジェクトを想定しています。
その目的は、mainブランチへのコード変更(pushpull request)があった際に、自動でテストを実行してコードの品質を担保することです。

この一連の流れは、CI(継続的インテグレーション)の最も基本的な実践例と言えます。

1. ワークフローファイルの基本構造

まず、.github/workflows/ci.yml というファイルを作成し、以下の基本構造を理解しましょう。

# ワークフローの名前 (GitHubのActionsタブに表示される)
name: CI

# ワークフローのトリガー
on:
  push:
    branches: [ main ] # mainブランチへのpush
  pull_request:
    branches: [ main ] # mainブランチをターゲットにしたpull_request

# 実行するジョブの集まり
jobs:
  # 'build' という名前のジョブ (名前は任意)
  build:
    # ジョブを実行する仮想マシンのOS
    runs-on: ubuntu-latest # ジョブを実行するOSを指定します。最新のUbuntu環境が使われます。

    # ジョブの実行手順
    steps:
      # ステップ1: リポジトリのコードをチェックアウトする
      - uses: actions/checkout@v4 # このステップがリポジトリのコードを仮想環境にコピーします。

      # ステップ2: Node.js環境をセットアップする
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20.x'

      # ステップ3: 依存パッケージをインストールする
      - run: npm install

      # ステップ4: テストを実行する
      - run: npm test

2. ワークフローファイルの主要な構成要素の解説

name

このワークフローの名前です。GitHubのUI(Actionsタブ)上で、他のワークフローと区別しやすくするために付けます。


on

ワークフローのトリガーとなるイベントを定義します。
上記の例では、「mainブランチへのpush」と「mainブランチをターゲットにしたpull_request」の2つをきっかけに起動します。
他にもschedule(定時実行)やworkflow_dispatch(手動実行)など、様々なイベントをトリガーに設定できます。


jobs

ワークフローが実行する一連のジョブを定義します。
各ジョブは独立した仮想環境で実行され、並列または直列に実行するように設定できます。


runs-on

ジョブを実行する仮想環境(ランナー)の種類を指定します。
ubuntu-latest, windows-latest, macos-latestなど、プロジェクトの要件に合わせてOSを選択できます。


steps

ジョブ内の一連の具体的な手順を定義します。
ステップは上から下に順番に実行されます。

  • uses: 他の人が作成した便利なアクション(再利用可能なスクリプトのパッケージ)を呼び出します。これにより、複雑なタスクを短い記述で実現できます。
    • actions/checkout@v4: リポジトリのコードを仮想マシン上にチェックアウトするための、ほぼ必須のアクションです。
    • actions/setup-node@v4: 特定のバージョンのNode.js実行環境をセットアップします。.x を使ったバージョン指定(例: 20.x)により、メジャーバージョン内の最新安定版が自動で選択され、環境の互換性問題を減らします。
  • run: シェルコマンドを直接実行します。npm installmake buildなど、あなたが普段ターミナルで実行するコマンドをそのまま記述できます。

ワークフロー構文について

これらの構成要素は、YAML(ヤムル)という形式のファイルに キー: 値 のペアで記述されます。YAMLではインデント(字下げ)が階層構造を表すため、非常に重要です。タイプミスやインデントの間違いでワークフローが正しく動作しないことも多いため、注意深く記述しましょう。

各要素の詳細な構文や、ここで紹介しきれなかった全てのオプションについては、以下の公式ドキュメントが最も信頼できる情報源です。


3. Secrets:機密情報の取り扱い

APIキーやパスワードなど、ワークフローファイルに直接書き込みたくない機密情報を安全に利用するための仕組みです。

使い方

リポジトリの Settings > Secrets and variables > Actions で新しいシークレットを登録し(例: MY_SECRET)、ワークフローファイル内で ${{ secrets.MY_SECRET }} という構文を使って参照します。

steps:
  - name: Use secret
    run: echo "API Key is being used."
    env:
      API_KEY: ${{ secrets.MY_SECRET }}

GitHubは、シークレットがログに出力されないように自動でマスクしてくれます。


管理レベルと登録方法

シークレットは、利用したい範囲に応じて、以下の3つのレベルで管理できます。

  1. リポジトリレベル (Repository-level):
    • 範囲: 特定の一つのリポジトリ内でのみ利用できます。
    • 設定場所: リポジトリ > Settings > Secrets and variables > Actions > Repository secrets
  2. 環境レベル (Environment-level):
    • 範囲: productionstagingといった特定の「環境(Environment)」に紐づけて管理します。同じワークフローでも、デプロイ先環境によって異なるAPIキーを使いたい場合に非常に便利です。
    • 設定場所: リポジトリ > Settings > Secrets and variables > Actions > Repository secrets > Manage environment secrets > (環境名)
  3. オーガニゼーションレベル (Organization-level):
    • 範囲: オーガニゼーション(組織)全体で共通のシークレットを管理できます。どのリポジトリから利用を許可するか、アクセスポリシーを設定することも可能です。
    • 設定場所: オーガニゼーション > Settings > Secrets and variables > Actions

シークレットの登録は、ブラウザ上のUIだけでなく、GitHub CLI (ghコマンド) を使ってコマンドラインから行うこともできます。

例えば、MY_API_KEY という名前のシークレットを現在のリポジトリに登録する場合、ターミナルで以下のコマンドを実行します。コマンド実行後、シークレットの値を入力するよう求められるので、ペーストしてEnterキーを押します。

# 対話形式でシークレットの値を設定
gh secret set MY_API_KEY

特定の環境やオーガニゼーションレベルでシークレットを設定する場合は、フラグを使って対象を指定します。

# "staging" という名前の環境にシークレットを設定
gh secret set --env staging STAGING_DB_PASSWORD

# オーガニゼーション "my-org" のシークレットを設定
# (オーガニゼーションの管理者権限が必要です)
gh secret set --org my-org SHARED_API_KEY

このようにCLIを使うことで、セットアップ作業の自動化や、手作業によるコピー&ペーストのミス防止に繋がります。


利用上の注意点

  • 値の不可視性: 一度登録したシークレットの値は、後からWeb画面で確認することはできません(再設定のみ可能)。
  • ログのマスキング: ワークフローのログにシークレットの値が直接出力されることはありませんが、例えばスクリプト内で値を加工して表示するなど、意図しない形で漏洩する可能性はゼロではありません。取り扱いには十分注意してください。
  • 命名規則: シークレット名は、慣例的に大文字のスネークケース(例: AWS_ACCESS_KEY_ID)で命名されることが一般的です。

4. キャッシュとアーティファクト:実行時間の短縮と成果物の共有

ワークフローの実行中にファイルを永続化する機能として「キャッシュ」と「アーティファクト」がありますが、これらは用途に応じて明確に使い分けられます。

  • キャッシュ(Cache): 「ジョブのパフォーマンス向上」 を目的とします。
  • アーティファクト(Artifacts): 「ジョブ間のデータ共有と成果物の永続化」を目的とします。

以下で、それぞれの具体的な使い方を見ていきましょう。

  • Cache (actions/cache@v4): npm installなどでダウンロードした依存パッケージなど、時間のかかるファイルをキャッシュし、次回のワークフロー実行時に再利用することで、実行時間を大幅に短縮します。例えば、以下のようにpackage-lock.jsonのハッシュをキーにしてキャッシュを作成します。
- uses: actions/cache@v3
  id: npm-cache # use this to check for `cache-hit` ==> if: steps.npm-cache.outputs.cache-hit != 'true'
  with:
    path: ${{ steps.npm-cache-dir.outputs.dir }}
    key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
    restore-keys: |
      ${{ runner.os }}-node-
  • Artifacts (actions/upload-artifact@v4, actions/download-artifact@v4): ビルド成果物(実行ファイルやテストレポートなど)を一時的に保存し、後のジョブで利用したり、ワークフロー完了後にダウンロードしたりするための仕組みです。

(実践)最初のワークフローを動かしてみよう

理論を学んだら、次は実際に手を動かしてGitHub Actionsが動作する様子を確認してみましょう。

ここでは、リポジトリにコードをプッシュすることなく、誰でも安全に試せる最もシンプルなワークフローを紹介します。

ステップ1: ワークフローファイルの作成

まず、あなたのGitHubリポジトリのルートに .github/workflows/ というディレクトリを作成してください。そして、その中に hello-world.yml という名前で以下の内容のファイルを作成・保存します。

# ワークフローの名前
name: Hello World Action

# ワークフローのトリガー: 手動実行を許可
on:
  workflow_dispatch:

# 実行するジョブ
jobs:
  # ジョブの名前
  say-hello:
    # 実行環境
    runs-on: ubuntu-latest

    # ジョブの実行手順
    steps:
      # ステップ1: あいさつを表示
      - name: Say Hello
        run: echo "Hello, World! This is my first GitHub Actions workflow."

      # ステップ2: 実行環境の情報を表示
      - name: Check Runner OS
        run: echo "This job is running on a ${{ runner.os }} server."

このワークフローは、手動実行(workflow_dispatch)をトリガーとして、「Hello, World!」というメッセージと、実行されているOSの情報を表示するだけの非常にシンプルなものです。

ステップ2: ワークフローの手動実行

  1. 作成したファイルをリポジトリにプッシュした後、GitHubでリポジトリページを開き、上部のタブから 「Actions」 をクリックします。
  2. 画面左側のワークフロー一覧に、作成した 「Hello World Action」 が表示されているはずです。それをクリックしてください。
  3. 中央のエリアに 「This workflow has a workflow_dispatch event trigger.」 というメッセージと、「Run workflow」 というボタンが表示されます。このボタンをクリックしてください。
  4. ポップアップが表示されるので、そのまま緑色の 「Run workflow」 ボタンをクリックします。

ステップ3: 実行結果の確認

実行が開始されると、ワークフローの実行履歴が表示されます。実行中のワークフローをクリックし、さらに左側のジョブ名(say-hello)をクリックすると、リアルタイムで実行ログを確認できます。

実行が完了すると、各ステップのログを展開して見ることができます。「Say Hello」のステップを開けば、「Hello, World!」のメッセージが表示されていることが確認できるはずです。

各ステップのログ

これで、GitHub Actionsの第一歩を踏み出すことができました!おめでとうございます!


参考資料


まとめ

GitHub Actionsを導入することで、以下のようなメリットを得られます。

  • 品質向上: PRごとに自動でテストを実行し、バグのあるコードのマージを未然に防げる。
  • 生産性向上: 定型作業から解放され、より創造的な開発作業に集中できます。
  • 属人性の排除: 誰がやっても同じ手順でビルドやデプロイが実行できるため、ミスが減ります。

まずは、簡単なテストを自動実行するワークフローから始めてみましょう!
それだけでも、あなたの開発体験は劇的に向上するはずです。

次のステップとして、以下がお薦めです。

  • まずは手元の簡単なプロジェクトで、この記事のci.ymlをコピーして動かしてみる。
  • scheduleトリガーを使って、定期的に処理を実行する方法も調べてやってみる。

さあ、あなたのMacを快適な開発環境にしましょう!!

SNSでもご購読できます。

コメントを残す

*