🚀

GitHub Actions 入門:基礎知識から実務で役立つ構築・最適化の手順まで体系的に解説

に公開

背景

実務でGitHub Actionsを使ってCI/CDを構築する機会があり、その際にキャッチアップした知識を以下で体系的にまとめました。
おそらく基礎的なことは網羅できていると思うので、初めてGitHub Actionsを触る人がキャッチアップをする際の参考になれば幸いです。

学習する際に感じたこと

GitHub Actionsをキャッチアップする際に最初に公式ドキュメントを読んだのですが、私のようなあまりCI/CDのツールに関して事前知識がない人間からすると、内容が網羅的過ぎたり、情報が理解しやすいように構造化されてはいないように感じました。
そのため、まずは本記事くらいの必要最低限の基礎知識を理解し、実際に手を動かしながらキャッチアップしていくのが効率がいいと感じます。

GitHub Actionsとは

GitHubが提供するCI/CDプラットフォームです。
GitHub上でプログラムのビルド、テスト、デプロイなどの作業を自動化するためのツールです。

GitHub Actionsの構成要素

主要な構成要素は以下のとおりです。

要素 説明 特徴
Workflow 自動化プロセスの全容 .github/workflows/*.yml に定義する。
Event 実行のトリガー push, pull_request, schedule (定期実行)など。
Runner 実行環境 GitHub提供(Hosted)か自前(Self-hosted)の仮想環境。
Job 実行される処理の塊 デフォルトでは複数のJobは並列に動く。依存関係(needs)の設定をして、順次実行させることも可能。
Step Job内の最小単位 上から順に実行する。コマンド実行やAction呼び出しを行う。
Action 再利用可能な部品 ステップで利用できる再利用可能な部品。GitHub Marketplaceで提供されているものや自作のカスタムアクションを使用可能。

構成要素間の関係

使い方

リポジトリ直下の.github/workflows/ディレクトリ配下に、YAML形式のファイルを追加するだけです。
このファイルには、自分が実行したいことを実現するために必要な、上記の構成要素の設定を記載します。
例えば以下のような感じです。

name: CI/CD Pipeline # ワークフローの名前

on: [push] # ① Event:実行のトリガー。この場合はコードがプッシュされたときに実行する。

jobs: # ② Job: この階層以下ではジョブの定義を行う
  build_and_test: # ジョブ名
    runs-on: ubuntu-latest # ③ Runner: 実行する仮想マシンのOSを指定
    steps: # ④ Step: ステップの定義
      - uses: actions/checkout@v4 # ⑤ Step1: リポジトリのコードをチェックアウトするAcitonを実行
      - name: Set up Node.js # Step2: ステップ名
        uses: actions/setup-node@v4
        with:
          node-version: '20'
      - name: Install dependencies # ⑤ Step3: 依存関係をインストールするスクリプトを実行
        run: npm install
      - name: Run tests
        run: npm test

構成要素詳細

Workflow

GitHub Actionsにおける、自動化プロセス全体を定義するファイルそのものです。
実態は上述した例のようなコードが記載されたファイルです。
ワークフローには主に以下2種類があります。

種類 説明
通常のWorkflow 通常の独立したワークフロー
Reusable Workflow 他のワークフローからも使用可能なワークフロー

この時点ではReusable Workflowに関してはあまり深く理解しなくていいです。
実際に実装をするときに、ワークフローをDRYにする際などに使用を考えることになります。
詳細はその時にキャッチアップすればよいです。
以下の記事がわかりやすいのでぜひご参照ください。
https://zenn.dev/dzeyelid/articles/fc4bd999fbccd8

Event

ワークフローの実行を開始するトリガーとなる、GitHub上での特定のアクティビティです。
例えばpush(リポジトリにコードをプッシュ)、pull_request(特定のブランチへのプルリクエストの作成など)などがあります。
私が実務上でよく見るものはこちらに網羅されていたのでご参照ください。
https://zenn.dev/farstep/books/learn-github-actions/viewer/trigger-settings
また、実装時に詳細な仕様を確認するときは、公式ドキュメントをご参照ください。
https://docs.github.com/ja/actions/reference/workflows-and-actions/events-that-trigger-workflows

Runner

Jobの実行環境です。
例えば、最新のubuntuを実行環境として使う場合は、以下のように指定します(正確には、GitHubが現在、最新の安定版として指定しているUbuntuの長期サポート版(LTS))。

runs-on: ubuntu-latest

また、実行環境(Runner)の設定方法は以下の2つがあります。

  • ワークフローのJob全体に一括で設定する
  • Job単位で設定する

基本的にJob単位で設定するでよいと思います。

また、Runnerの種類には以下2種類があります。

種類 説明
GitHub-hosted GitHubによって提供される仮想環境。指定されたOS(Ubuntu, Windows, macOSなど)とバージョンで実行される。
Self-hosted ユーザー自身が管理するマシン。特定のハードウェアやソフトウェア要件がある場合に使用されます。

特別な理由がない場合は、基本的にGitHub-hostedのRunnerで問題ないと思います。

Job

一連のStepをまとめたものです。
Stepに関しては後述します。
Jobに関しては、主に以下3つを定義します。

  1. Job名
  2. Runner: 実行環境
  3. Step: Job内で実行する処理

例えば以下のような感じです。

jobs:
  first_job: # Job名
    runs-on: ubuntu-latest # Runner
    steps: # Step
      - run: echo "This runs on the default Linux runner."
      - run: echo "Hello World."

  second_job: # Job名
    runs-on: windows-latest # Runner
    needs: first_job # 依存関係のあるJob名を指定
    steps: # Step
      - run: echo "This explicitly runs on Windows."

Jobはデフォルトでは並列で実行されます。
依存関係があるJobを定義したい場合は、needsキーワードを使って依存関係を設定し、順番に実行させることが可能です。

その他の主要な設定項目に関しては、気になれば以下が参考になると思います。
https://zenn.dev/farstep/books/learn-github-actions/viewer/job-settings

またここで、一つ疑問が湧くのではないかと思います。
それは、Workflow/Job/Stepをどのような基準でまとめたり、分けたりすべきなのかということです。
これに関しては以下の記事にわかりやすく記載されているので、こちらをご参照いただければと思います。
https://zenn.dev/hsaki/articles/github-actions-component

Step

Job内で実行される最小のタスクです。
ステップではアクションを実行するか、シェルコマンドを実行するかのいずれかを行うことができます。
アクションに関しては次に記載します。
例えば以下のようにStepの定義を行います。

jobs:
  build_and_test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4 # Step1: リポジトリのコードをチェックアウトするAcitonを実行
      - name: Install dependencies # Step2: ステップ名
        run: npm install # Step2: 依存関係をインストールするシェルコマンドを実行

その他の主要な設定項目に関しては、こちらも以下が参考になると思います。
https://zenn.dev/farstep/books/learn-github-actions/viewer/step-settings

Action

ステップで利用できる再利用可能な部品です。
アクションには以下2種類が存在します。

種類 説明
GitHub Marketplaceで公開されているアクション GitHub Marketplaceで公開されているアクション。
カスタムアクション ユーザー自作のアクション。

これらに関しても以下にわかりやすく記載されているので、ぜひご参照ください。

https://zenn.dev/farstep/books/learn-github-actions/viewer/use-of-actions

https://zenn.dev/farstep/books/learn-github-actions/viewer/create-custom-actions

その他、必要になったときに学ぶべきこと

要素 参考サイト
環境変数とシークレット https://zenn.dev/farstep/books/learn-github-actions/viewer/environment-variables-and-secrets
アーティファクトとキャッシュ https://zenn.dev/farstep/books/learn-github-actions/viewer/artifacts-and-cache https://zenn.dev/osachi/articles/46a63d57622fd1 https://docs.github.com/en/actions/reference/workflows-and-actions/dependency-caching#default-limits
マトリックスビルド https://zenn.dev/farstep/books/learn-github-actions/viewer/matrix-build
セキュリティ https://zenn.dev/farstep/books/learn-github-actions/viewer/security-and-operations
変数 https://dev.classmethod.jp/articles/github-actions-configuration-variables-vs-environment-variables/

構築手順

ここまでくれば、基本的なことは理解できていると思います。
ぜひ実際に手を動かして見ていただきたいですが、どういう手順で行えばいいか迷うかもしれないので、Workflowを構築するために個人的に行っている手順を記載します。

  1. GitHub Actionsで行いたいことを洗い出す
  2. Workflow, Job, Stepをこちらの基準に従って設計する
  3. 実装
  4. 動作確認
  5. ブラッシュアップ
    1. DRY
      1. 複数のWorkflowで行っていることをカスタムアクションに切り出す
      2. 複数のWorkflowで行っていることをReusable Workflowに切り出す
    2. セキュリティの向上
      1. 最小権限の原則に従うように、権限設定をする
        1. ワークフローレベルで全パーミッションを無効化する(permissions: {} # 全パーミッションの無効化)
        2. 必要最小限のパーミッションをジョブレベルで定義する
    3. パフォーマンスの改善
      1. アーティファクトの利用を検討する
      2. キャッシュの利用を検討する
      3. 不要なワークフローの実行をキャンセルするようにする
    4. メンテナンス性の向上
      1. デフォルトシェルを明示的にBashで設定して、パイプエラーを拾うようにする
      2. actionlintを導入して、構文エラーがチェックされるようにする
      3. Bashトレーシングオプションでログを詳細に出力する
      4. カスタムアクションを使って、複雑な処理を抽象化・カプセル化する
      5. 動的な環境変数はrun: echo ENV_NAME=value >> GITHUB_ENVで設定して、{ENV_NAME}で参照する
    5. 不要なコストの削減
      1. ジョブのタイムアウトを設定する(デフォルトだと6時間まで実行できてしまう)
      2. 最安値のUbuntuランナーを優先する

参考

https://docs.github.com/ja/actions
https://zenn.dev/dzeyelid/articles/fc4bd999fbccd8
https://zenn.dev/farstep/books/learn-github-actions
https://dev.classmethod.jp/articles/github-actions-configuration-variables-vs-environment-variables/
https://qiita.com/chanhama/items/3f4c6461d28bdd1ae2d7
https://zenn.dev/hsaki/articles/github-actions-component
https://gihyo.jp/article/2024/10/good-practices-for-github-actions
https://qiita.com/kannkyo/items/dd8b11315b4433fda543
https://developers.cyberagent.co.jp/blog/archives/36423/
https://zenn.dev/osachi/articles/46a63d57622fd1

Discussion