T-CREATOR

GitHub Actions 入門:最初のワークフローを作成する手順

GitHub Actions 入門:最初のワークフローを作成する手順

近年、ソフトウェア開発の現場では「継続的インテグレーション(CI)」と「継続的デリバリー(CD)」が当たり前になってきました。手作業でのテストやデプロイが主流だった時代から、自動化によって開発効率と品質を同時に向上させる時代へと変わってきています。

GitHub Actions は、GitHub が提供する CI/CD サービスです。コードをプッシュするだけで自動的にテストが実行され、問題がなければそのままデプロイまで完了する。そんな開発フローを、追加コストなしで実現できるのが大きな魅力ですね。

この記事では、GitHub Actions を初めて触る方に向けて、最初のワークフローを作成する手順を詳しく解説いたします。難しそうに感じるかもしれませんが、実は想像以上にシンプルで、一度覚えてしまえば開発がとても楽になるはずです。

背景

手動デプロイの課題と限界

従来の手作業による開発フローには、多くの課題が潜んでいます。

まず、人的ミスのリスクが常につきまといます。本番環境へのデプロイ時に設定ファイルを間違えたり、必要なファイルをアップロードし忘れたり。こうしたヒューマンエラーは、どれだけ注意深く作業しても完全には防げません。

次に、時間とコストの問題があります。毎回手作業でテストを実行し、ビルドして、デプロイする作業は非常に時間がかかります。特にチーム開発では、メンバーそれぞれが同じ作業を繰り返すことになり、開発効率が大幅に低下してしまいます。

また、品質の一貫性を保つことも困難です。開発者によってテストの実行方法が異なったり、デプロイ手順が微妙に違ったりすると、品質にばらつきが生まれてしまいます。

手動での作業フローを図で表すと、以下のような複雑で時間のかかるプロセスになります:

mermaidflowchart TD
  A[コード変更] --> B[手動テスト実行]
  B --> C{テスト結果}
  C -->|失敗| D[エラー修正]
  D --> B
  C -->|成功| E[手動ビルド]
  E --> F[手動デプロイ]
  F --> G{デプロイ確認}
  G -->|失敗| H[ロールバック作業]
  G -->|成功| I[完了]
  H --> D

このように、手作業では多くのステップで人が介入し、ミスが発生する可能性が高くなっています。

自動化がもたらすメリット

自動化によって得られるメリットは計り知れません。

品質の向上が最も大きな利点でしょう。決められた手順でテストが必ず実行されるため、見落としやミスが大幅に減少します。また、複数のテストケースを同時並行で実行できるため、より包括的な品質チェックが可能になります。

開発速度の向上も見逃せません。自動化により、開発者は本来の開発作業に集中できるようになります。デプロイに関する心配をせずに済むため、新機能の開発や既存機能の改善により多くの時間を割けるようになります。

コストの削減も重要なポイントです。人件費の削減はもちろんですが、障害対応コストの削減効果も大きいでしょう。自動化により品質が安定すれば、本番環境での問題発生率が下がり、緊急対応の必要性も減少します。

さらに、チーム全体のスキル向上にもつながります。自動化の仕組みを理解することで、開発者一人ひとりがより高いレベルでの開発フローを身につけることができます。

課題

初心者が感じる自動化への壁

GitHub Actions を始めようと思っても、多くの初心者の方が壁を感じられるのは事実です。

専門用語の多さが最初の障壁になることが多いですね。「ワークフロー」「ジョブ」「ステップ」「アクション」「ランナー」といった用語が次々と出てきて、それぞれの関係性を理解するのに時間がかかります。

YAML 記法への不安も大きな課題です。GitHub Actions は YAML ファイルで設定を記述しますが、インデントのルールが厳格で、わずかなミスでも動作しません。プログラミングに慣れていない方にとっては、なかなかハードルが高く感じられるでしょう。

どこから始めれば良いか分からないという声もよく聞きます。公式ドキュメントは充実していますが、情報量が膨大で、自分のプロジェクトに必要な部分を見つけるのが困難です。

複雑な設定への不安

GitHub Actions の柔軟性は魅力的ですが、同時に複雑さの原因でもあります。

設定ミスによる問題を恐れる方が多いのは当然です。間違った設定により本番環境に影響が出たり、意図しないコストが発生したりする可能性があります。

セキュリティへの懸念も無視できません。API キーやパスワードなどの機密情報を適切に管理する方法が分からず、セキュリティリスクを心配される方も少なくありません。

メンテナンスの負担についても不安を感じる方がいらっしゃいます。一度設定したワークフローが古くなったときの更新方法や、エラーが発生したときの対処法が分からないという声をよく耳にします。

課題を整理すると、以下のような構造になります:

mermaidmindmap
  root((GitHub Actions導入の課題))
    学習コスト
      専門用語の理解
      YAML記法の習得
      概念の把握
    技術的不安
      設定ミスのリスク
      セキュリティ懸念
      デバッグの困難さ
    運用面の心配
      メンテナンス負担
      コスト管理
      チーム展開

これらの課題を一つずつ解決していくことで、GitHub Actions を安心して活用できるようになります。

解決策

GitHub Actions の基本概念

GitHub Actions を理解するために、まずは基本的な概念から確認していきましょう。

GitHub Actions は、GitHub リポジトリ内でコードの変更をトリガーとして自動実行される仕組みです。特定のイベント(プッシュ、プルリクエスト作成など)が発生すると、事前に定義された処理が自動で実行されます。

イベントは、ワークフローを開始するきっかけとなる出来事です。代表的なものには以下があります:

#イベント名説明
1pushコードがリポジトリにプッシュされたとき
2pull_requestプルリクエストが作成・更新されたとき
3schedule定期実行(cron 形式で指定)
4workflow_dispatch手動実行

ランナーは、実際にワークフローが実行される仮想環境です。GitHub が提供するホステッドランナー(Ubuntu、Windows、macOS)を無料で使用できます。

ワークフロー、ジョブ、ステップの関係性

GitHub Actions の構造は階層的になっており、この関係性を理解することが非常に重要です。

**ワークフロー(Workflow)**が最上位の概念です。一つのワークフローは特定の目的(テスト実行、デプロイなど)を持った自動化のまとまりです。

**ジョブ(Job)**は、ワークフロー内で実行される作業の単位です。複数のジョブを並列実行することも、順次実行することもできます。それぞれのジョブは独立したランナー上で実行されます。

**ステップ(Step)**は、ジョブ内で実行される個々のタスクです。コマンドの実行やアクションの呼び出しを行います。

**アクション(Action)**は、再利用可能な処理のまとまりです。GitHubMarketplace で公開されているものを使用することも、独自に作成することもできます。

以下の図で、これらの関係性を確認してみてください:

mermaidgraph TD
  subgraph "ワークフロー (.yml ファイル)"
    subgraph "ジョブ1 (Ubuntu ランナー)"
      S1[ステップ1: チェックアウト]
      S2[ステップ2: Node.js セットアップ]
      S3[ステップ3: 依存関係インストール]
      S4[ステップ4: テスト実行]
    end

    subgraph "ジョブ2 (Windows ランナー)"
      S5[ステップ1: チェックアウト]
      S6[ステップ2: ビルド実行]
      S7[ステップ3: アーティファクト保存]
    end
  end

  S1 --> S2 --> S3 --> S4
  S5 --> S6 --> S7

この階層構造により、複雑な処理も段階的に整理して実装できます。

.github/workflows ディレクトリの役割

GitHub Actions のワークフローファイルは、リポジトリのルートディレクトリにある .github​/​workflows フォルダに配置します。

このディレクトリ内に置かれた .yml または .yaml 拡張子のファイルは、自動的にワークフローとして認識されます。ファイル名は任意ですが、内容が分かりやすい名前を付けることをお勧めします。

bash.github/
└── workflows/
    ├── ci.yml          # 継続的インテグレーション
    ├── deploy.yml      # デプロイメント
    └── test.yml        # テスト実行

複数のワークフローファイルを作成することで、用途別に処理を分けることができます。例えば、テスト用とデプロイ用のワークフローを分離することで、管理がしやすくなります。

具体例

Hello World ワークフローの作成

最初のワークフローとして、シンプルな Hello World を作成してみましょう。

まず、リポジトリに .github​/​workflows ディレクトリを作成します:

bashmkdir -p .github/workflows

次に、最初のワークフローファイル hello.yml を作成します:

yamlname: Hello World Workflow

# トリガーの設定
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

上記の設定により、main ブランチへのプッシュやプルリクエスト作成時にワークフローが実行されます。

次に、ジョブの定義を追加します:

yamljobs:
  hello-world:
    # 実行環境の指定
    runs-on: ubuntu-latest

    steps:
      # リポジトリのコードをチェックアウト
      - uses: actions/checkout@v4

最初のステップでは、actions​/​checkout アクションを使用してリポジトリのコードをランナーにダウンロードします。

続いて、Hello World メッセージを表示するステップを追加します:

yaml# Hello World メッセージの表示
- name: Say Hello
  run: |
    echo "Hello, GitHub Actions!"
    echo "現在の時刻: $(date)"
    echo "実行環境: $RUNNER_OS"

run キーワードを使用することで、シェルコマンドを直接実行できます。複数行のコマンドは | を使って記述します。

完成したワークフローファイルをリポジトリにコミットすると、自動的に実行が開始されます。GitHub の Actions タブで実行状況を確認できます。

Node.js アプリケーションのビルドとテスト

実際のプロジェクトでよく使われる、Node.js アプリケーションのビルドとテストを自動化してみましょう。

まず、Node.js 環境のセットアップから始めます:

yamlname: Node.js CI

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [18.x, 20.x]

strategy.matrix を使用することで、複数の Node.js バージョンでテストを並列実行できます。

次に、Node.js 環境のセットアップステップを追加します:

yamlsteps:
  - uses: actions/checkout@v4

  # Node.js のセットアップ
  - name: Use Node.js ${{ matrix.node-version }}
    uses: actions/setup-node@v4
    with:
      node-version: ${{ matrix.node-version }}
      cache: 'yarn'

${{ matrix.node-version }} により、マトリックス戦略で指定したバージョンが動的に設定されます。

依存関係のインストールとテスト実行のステップを追加します:

yaml# 依存関係のインストール
- name: Install dependencies
  run: yarn install --frozen-lockfile

# リンター実行
- name: Run linter
  run: yarn lint

# テスト実行
- name: Run tests
  run: yarn test

# ビルド実行
- name: Build application
  run: yarn build

--frozen-lockfile フラグにより、yarn.lock ファイルの内容を変更せずに依存関係をインストールできます。これにより、ローカル環境と同じ依存関係バージョンを保証できます。

自動デプロイの基本設定

テストが成功した場合の自動デプロイ設定も見てみましょう。

まず、デプロイ用のジョブを別途定義します:

yamldeploy:
  needs: test
  runs-on: ubuntu-latest
  if: github.ref == 'refs/heads/main' && github.event_name == 'push'

  steps:
    - uses: actions/checkout@v4

needs: test により、テストジョブが成功した場合のみデプロイジョブが実行されます。if 条件により、main ブランチへのプッシュ時のみデプロイが実行されるよう制限されています。

環境変数とシークレットを使用した安全なデプロイ設定:

yaml# アプリケーションのビルド
- name: Build for production
  run: yarn build
  env:
    NODE_ENV: production

# デプロイ実行
- name: Deploy to production
  run: |
    echo "Deploying to production server..."
    # デプロイコマンドをここに記述
  env:
    DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
    SERVER_HOST: ${{ secrets.SERVER_HOST }}

機密情報は ${{ secrets.SECRET_NAME }} の形式で参照し、GitHub の Settings > Secrets and variables > Actions から設定します。

CI/CD の全体的なフローを図で表すと以下のようになります:

mermaidsequenceDiagram
    participant Dev as 開発者
    participant GitHub as GitHub Repository
    participant Actions as GitHub Actions
    participant Server as 本番サーバー

    Dev->>GitHub: git push
    GitHub->>Actions: ワークフロー開始
    Actions->>Actions: テスト実行
    Actions->>Actions: ビルド実行
    Actions->>GitHub: 結果通知

    alt テスト成功 & mainブランチ
        Actions->>Server: 自動デプロイ
        Server-->>Actions: デプロイ完了
        Actions->>Dev: 成功通知
    else テスト失敗
        Actions->>Dev: 失敗通知
    end

このように、開発者がコードをプッシュするだけで、テストからデプロイまでの一連の流れが自動化されます。

実践的な設定例

実際のプロジェクトでよく使用される、より実践的な設定例をご紹介します。

環境変数を活用したマルチ環境対応:

yamlname: Multi Environment Deploy

on:
  push:
    branches: [main, staging, develop]

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      # 環境の判定とデプロイ先の決定
      - name: Set environment variables
        run: |
          if [[ $GITHUB_REF == 'refs/heads/main' ]]; then
            echo "ENVIRONMENT=production" >> $GITHUB_ENV
            echo "DEPLOY_URL=${{ secrets.PROD_URL }}" >> $GITHUB_ENV
          elif [[ $GITHUB_REF == 'refs/heads/staging' ]]; then
            echo "ENVIRONMENT=staging" >> $GITHUB_ENV
            echo "DEPLOY_URL=${{ secrets.STAGING_URL }}" >> $GITHUB_ENV
          else
            echo "ENVIRONMENT=development" >> $GITHUB_ENV
            echo "DEPLOY_URL=${{ secrets.DEV_URL }}" >> $GITHUB_ENV
          fi

キャッシュ機能を活用したビルド時間の短縮:

yaml# 依存関係のキャッシュ
- name: Cache dependencies
  uses: actions/cache@v3
  with:
    path: |
      node_modules
      ~/.cache/yarn
    key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
    restore-keys: |
      ${{ runner.os }}-yarn-

エラー時の通知設定:

yaml# Slack通知(失敗時)
- name: Notify failure
  if: failure()
  uses: 8398a7/action-slack@v3
  with:
    status: failure
    channel: '#dev-alerts'
    text: 'デプロイが失敗しました'
  env:
    SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}

まとめ

第一歩として学んだこと

この記事では、GitHub Actions の基本的な概念から実際のワークフロー作成まで、段階的に学習してまいりました。

重要なポイントをおさらいします。GitHub Actions はワークフロー > ジョブ > ステップの階層構造で構成されており、.github​/​workflows ディレクトリに YAML ファイルとして定義します。シンプルな Hello World から始めて、実際の Node.js プロジェクトでのビルド・テスト・デプロイまで、段階的に機能を追加していく方法を確認しました。

特に、エラーを恐れずに小さく始めることが成功への近道です。最初は単純なワークフローから始めて、慣れてきたら段階的に機能を追加していく。この approach により、無理なく GitHub Actions を習得できるでしょう。

セキュリティ対策についても基本的な考え方をお伝えしました。機密情報は GitHub Secrets を使用し、適切な権限設定を行うことで、安全に自動化を実現できます。

次のステップへの道筋

GitHub Actions の基本を理解された今、次のレベルへ進むための学習路線をご提案いたします。

段階的なスキルアップをお勧めします:

#ステップ学習内容期間目安
1基礎固め本記事の内容を実践、エラー対応の経験1-2 週間
2応用機能マトリックス戦略、条件分岐、並列処理2-3 週間
3セキュリティシークレット管理、OIDC 認証、権限設定1-2 週間
4最適化キャッシュ活用、実行時間短縮、コスト削減2-3 週間
5高度な活用カスタムアクション作成、複合ワークフロー3-4 週間

実践的な学習方法として、以下のようなステップで進められることをお勧めします:

自分のプロジェクトで小さなワークフローから始める。失敗を恐れず、エラーが発生したら GitHub の Actions タブでログを確認し、問題を一つずつ解決していく。この過程で、YAML 記法や Linux コマンドの理解も深まります。

コミュニティの活用も非常に重要です。GitHub Marketplace には数千のアクションが公開されており、多くの問題は既存のアクションで解決できます。また、他の開発者のワークフローファイルを参考にすることで、ベストプラクティスを学べるでしょう。

モニタリングと改善の習慣も身につけましょう。ワークフローの実行時間やコストを定期的に確認し、必要に応じて最適化を行う。この継続的改善により、より効率的な開発フローを構築できます。

GitHub Actions は単なるツールではなく、現代的な開発手法を身につけるための重要な技術です。この第一歩から始めて、継続的に学習を続けることで、必ず皆さまの開発効率向上に貢献するはずです。

関連リンク