GitHub Actions入門|CI/CDの仕組みを「レストランの厨房」でまるごと理解する

Git

「GitHub Actionsという言葉は聞くけれど、ワークフロー・ジョブ・ステップ・アクション…用語が多すぎて頭に入ってこない」。この記事はそんな方のために書きました。


読み終わる頃には、①GitHub Actionsが何をしてくれるのか、②登場人物どうしがどうつながっているのか、③自分のリポジトリで実際に動かすYAMLの読み方、④お金はいくらかかるのか、⑤個人の定期バッチを無料で回せるのか、までが順番につながって理解できる状態になります。


専門用語には必ずその場で補足を入れていますので、前提知識ゼロでも大丈夫です。


そもそもCI/CDとは何か

GitHub Actionsを理解する前に、CI/CDという言葉を押さえておきます。

CI(Continuous Integration/継続的インテグレーション)とは、書いたコードを頻繁に共有場所へ持ち寄り、そのたびに自動で「ちゃんと動くか」を検査する開発のやり方です。「インテグレーション」は統合、つまり複数人が書いたコードを1つにまとめることを指します。

CD(Continuous Delivery/Deployment=継続的デリバリー/継続的デプロイ)とは、検査を通ったコードを、いつでもリリースできる状態に自動で整える(デリバリー)、あるいは本番環境まで自動で届ける(デプロイ)ことです。

イメージしにくい場合は、レストランの厨房を思い浮かべてください。料理人(開発者)が作った皿を、出す前に必ず「味見係」がチェックし、問題なければホールへ運ぶ。この味見と配膳を毎回・自動で・同じ手順でやる仕組みがCI/CDです。人間がやると「今日は忙しいから味見を飛ばそう」が起きますが、機械は絶対に飛ばしません。ここがCI/CDの最大の価値です。

CI/CDの中では、次の3つの作業が繰り返し登場します。

  • ビルド(build):人間が書いたソースコードを、実行できる形(アプリのファイル、実行ファイル、Dockerイメージなど)に組み立てる作業です。料理でいう「調理」。
  • テスト(test):組み立てたものが期待通りに動くかを自動で検査する作業です。料理でいう「味見」。
  • デプロイ(deploy):完成したものを、実際に使われる場所(サーバー、クラウド、アプリストアなど)へ配置して動かす作業です。料理でいう「配膳」。


GitHub Actionsとは何者か

GitHub Actionsは、GitHubが公式に提供しているCI/CDプラットフォームです。GitHubのドキュメントでは「ビルド、テスト、デプロイのパイプラインを自動化できる継続的インテグレーションと継続的デリバリー (CI/CD) のプラットフォーム」と説明されています。

リポジトリ(repository)とは、GitHub上でソースコードとその変更履歴を保管する箱のことです。プロジェクト1つにつき1つ用意するのが基本で、GitHub Actionsもこのリポジトリの中に住みます。

ポイントは、GitHub ActionsがCI/CD専用ツールではないことです。公式ドキュメントも明言しているとおり、「新しいIssue(課題チケット)が作られたら自動でラベルを付ける」といった、開発以外の雑務の自動化にも使えます。

「GitHubで何かが起きたら、GitHubが用意したサーバーで好きな処理を走らせられる仕組み」と捉えると応用範囲が見えてきます。


【図解】ワークフロー→イベント→ジョブ→ステップ→アクション→ランナーの関係

6つの用語は並列に並んでいるのではなく、入れ子(マトリョーシカ)の関係です。まず全体像を一文でまとめると、こうなります。


リポジトリで「イベント」が起きると「ワークフロー」が起動し、その中の「ジョブ」が「ランナー」という使い捨てのサーバー上で動き、ジョブは「ステップ」の並びでできていて、各ステップは「アクション」を呼ぶかシェルコマンドを実行します。

階層要素説明
イベントワークフローを起動するきっかけ(push / schedule など)
ワークフロー.github/workflows/ 内のYAMLファイル
ジョブランナー1台を占有する作業のかたまり。既定では並列実行
ステップジョブ内の1手順。上から順に実行され、ファイルを引き継げる
アクションステップから呼び出す再利用可能な部品
ランナージョブを実際に実行するサーバー(使い捨ての仮想マシン)



ジョブ間の依存関係は needs キーワードで指定します。needs を書いた場合のみ、指定したジョブの成功を待ってから実行されます。ジョブが異なればランナー(マシン)も別物になるため、ジョブAで作ったファイルはジョブBには引き継がれません。


用語をひとつずつ丁寧に

① イベント(events)

イベントとは、ワークフローを起動させるきっかけとなるリポジトリ上の出来事です。「自動販売機のボタン」だと思ってください。ボタンが押されない限り、何も出てきません。

イベント名起動タイミング
pushコードがリポジトリに送られたとき
pull_requestプルリクエストが作られたとき
issuesIssue(課題チケット)が作られたときなど
schedule決まった日時(cron形式で指定)に自動で
workflow_dispatchGitHubの画面から人が手動でボタンを押したとき

cron(クーロン)形式:「分 時 日 月 曜日」の5つの数字で定期実行のタイミングを表す書き方です。「0 9 * * 1」なら「毎週月曜の9:00」を意味します。


② ワークフロー(workflows)

ワークフローは、自動化したい処理全体をまとめた手順書です。実体はYAML(ヤムル)ファイルで、リポジトリの中に一緒に保存されます。

YAML:設定を書くためのファイル形式です。インデント(行頭の半角スペース)で階層を表すのが最大の特徴で、タブ文字は使えません。初心者がハマる原因の第1位がこのインデントずれです。

ワークフローのYAMLファイルは、リポジトリ直下の .github/workflows というフォルダに置く決まりです。GitHubはこのフォルダだけを見に行くので、場所が1文字でも違うと何も起きません。

あなたのリポジトリ/
├── .github/
│   └── workflows/
│       ├── ci.yml          # ワークフロー1つめ
│       └── nightly.yml     # ワークフロー2つめ
├── src/
└── README.md

先頭のドット(.)を忘れないでください。1つのリポジトリに複数のワークフローを置けます。


③ ジョブ(jobs)

ジョブは、ワークフローの中の作業の大きなかたまりで、1台のランナー(サーバー)を丸ごと1つ占有して動きます。厨房でいう「調理場ひとつ」に相当します。初心者がとくに間違えやすいのは次の2点です。

  • ジョブは既定では並列(同時)に実行される:順番に動かしたい場合は needs で依存関係を書きます。
  • ジョブが違えばマシンも別物:ジョブAで作ったファイルはジョブBには残っていません。渡したい場合は「アーティファクト」(後述)を使います。

④ ステップ(steps)

ステップは、ジョブの中の1つ1つの作業です。「材料を出す」「切る」「焼く」といった単位で、書いた順に上から実行され、同じランナー上で動くのでファイルや状態を引き継げます。途中のステップが失敗すると、そのジョブは原則そこで停止します。ステップの書き方は2種類だけです。

  • run: … シェルコマンドをそのまま書く(例:run: npm test
  • uses: … 誰かが作ったアクションを呼び出す(例:uses: actions/checkout@v6

⑤ アクション(actions)

アクションは、よく使う処理をパッケージ化した再利用可能な部品です。「リポジトリのコードを取得する」「Node.jsをインストールする」といった、誰もが毎回書くことになる定型処理を1行で呼び出せます。料理でいう市販の合わせ調味料で、自分で一から配合しなくてよくなります。

アクション名用途
actions/checkout@v6リポジトリのコードをランナー上にダウンロードする。ほぼ全ワークフローの1行目
actions/setup-node@v6指定バージョンのNode.jsを用意する(Python版・Java版なども同様に存在)
actions/upload-artifact成果物を保存し、他のジョブやダウンロードで使えるようにする
actions/cacheライブラリなどをキャッシュして次回の実行を高速化する

バージョン指定(@v6の部分)は必ず書きましょう。省略や@main指定にすると、アクション側の更新でいきなり自分のワークフローが壊れることがあります。

GitHub Marketplaceは、世界中の開発者が公開したアクションを検索・入手できる公式の部品カタログです。「Slackに通知したい」「AWSにデプロイしたい」といった用途は、たいてい既製のアクションが見つかります。もちろん自分でアクションを作って公開することもできます。

Marketplaceのアクションは第三者製です。自分のリポジトリの中身やシークレットに触れるため、利用前にスター数・更新頻度・提供元を確認する習慣をつけてください。


⑥ ランナー(runners)

ランナーは、ジョブを実際に実行するサーバーです。1台のランナーは同時に1つのジョブだけを担当します。GitHub公式が用意するランナー(GitHubホストランナー)には、Linux・Windows・macOSの3種類があり、ワークフローが実行されるたびに新しくプロビジョニング(用意)された仮想マシンが割り当てられます。

つまり毎回まっさらな状態から始まるため、「自分のPCでは動くのに…」という環境差のトラブルが起きにくくなります。

仮想マシンコンテナ
例え一戸建て(土地から建てる)マンションの一室(建物は共有)
OSゲストOSを丸ごと持つホストのカーネルを共有
起動速度遅め(秒〜分)速い(ミリ秒〜秒)
Actionsでの位置ランナーそのものランナーの上で使う道具

コンテナ:OSの本体(カーネル)はホストと共有しつつ、アプリと必要なライブラリだけを箱詰めして隔離する軽量な実行環境です。仮想マシンより起動が速く軽いのが特徴で、Dockerが代表格です。GitHub Actionsでは、ジョブ全体をコンテナ内で動かしたり、テスト用のデータベースをコンテナで一時的に立ち上げたりできます。

GitHubが用意したマシンではなく、自分の会社のサーバーや自宅PCをランナーとして登録することもできます。これをセルフホストランナーと呼びます。特殊なハードウェアが必要な場合や、社内ネットワークからしかアクセスできない環境へデプロイしたい場合に使われます。


実際のYAMLを読んでみる

Node.jsアプリをテストする最小構成のYAMLです。各行のコメントと照らし合わせながら読んでみてください。

# .github/workflows/ci.yml

name: CI                        # ワークフローの表示名

on:                             # ① イベント(起動のきっかけ)
  push:
    branches: [ main ]          #   mainブランチにpushされたとき
    pull_request:               #   プルリクエストが作られたとき
    workflow_dispatch:          #   画面から手動実行したいとき

jobs:                           # ③ ジョブの定義開始
  build-and-test:               #   ジョブのID(自由に決めてよい)
    name: ビルドとテスト
    runs-on: ubuntu-latest      # ⑥ ランナーの指定

    steps:                      # ④ ステップの並び
      - name: コードを取得する
        uses: actions/checkout@v6        # ⑤ アクションを使う

      - name: Node.js を用意する
        uses: actions/setup-node@v6      # ⑤ アクションを使う
        with:                            #   アクションへの入力パラメータ
          node-version: '22'

      - name: 依存パッケージを入れる(ビルド準備)
        run: npm ci                      # シェルコマンドを直接実行

      - name: テストを走らせる
        run: npm test

読み方のコツは次のとおりです。

  • on: を見れば「いつ動くか」がわかる
  • jobs: の直下の名前が「何個の作業単位があるか」
  • runs-on: が「どのOSで動くか」
  • steps: の「-」の数が「何手順あるか」


ジョブを2つに分け、テストが通ったときだけデプロイする形にすると、こうなります。

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - run: npm ci && npm test

  deploy:
    needs: test                 # testジョブが成功するまで待つ
    if: github.ref == 'refs/heads/main'   # mainのときだけ実行
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - run: ./deploy.sh
        env:
          API_TOKEN: ${{ secrets.API_TOKEN }}   # シークレットを渡す


環境変数とシークレット

環境変数(environment variables)とは、プログラムの外側から渡す設定値の入れ物です。「本番用かテスト用か」「どのURLに接続するか」といった、コードに直接書きたくない値を保持します。GitHub Actionsでは env: で定義し、${{ env.名前 }}$名前 で参照します。

env:
  NODE_ENV: production          # ワークフロー全体で有効

jobs:
  build:
    runs-on: ubuntu-latest
    env:
      APP_NAME: my-app          # このジョブだけで有効
    steps:
      - run: echo "$APP_NAME を $NODE_ENV モードでビルドします"



シークレット(secrets)とは、他人に見られてはいけない機密値(APIキー、パスワード、クラウドの認証情報など)を安全に保管する仕組みです。GitHubの画面上で登録すると暗号化して保存され、登録後は本人でも中身を読み出せません。ワークフローからは ${{ secrets.名前 }} で参照します。実行ログに出力しようとしても、GitHubが自動で *** にマスクします。

登録方法:リポジトリの Settings → Secrets and variables → Actions → New repository secret

絶対にやってはいけないこと:APIキーやパスワードをYAMLファイルやソースコードに直書きすること。リポジトリをうっかり公開した瞬間に流出しますし、Gitは履歴を残すため後から消しても消えません。機密値は必ずシークレットに置いてください。

GITHUB_TOKEN:GitHubがワークフロー実行ごとに自動発行してくれる一時的な認証トークンです。自分のリポジトリにコメントを書く、Issueにラベルを付けるといった操作は、これを使えば自前のシークレットを用意せずに実現できます。実行が終わると無効になります。


料金プランと無料枠

大原則は次の1行です。パブリックリポジトリ(誰でも見られる公開リポジトリ)で標準のGitHubホストランナーを使う限り、GitHub Actionsは無料です。料金が発生するのは、原則としてプライベートリポジトリ(非公開)で使った場合です。


プライベートリポジトリの場合、プランごとに毎月の無料枠が付与され、それを超えた分が課金されます(2026年7月時点、公式ドキュメント記載の値)。

プラン実行時間(分/月)アーティファクト保存キャッシュ(リポジトリごと)
GitHub Free(個人・無料)2,000分500 MB10 GB
GitHub Pro(個人・有料)3,000分1 GB10 GB
GitHub Free(組織向け)2,000分500 MB10 GB
GitHub Team3,000分2 GB10 GB
GitHub Enterprise Cloud50,000分50 GB10 GB

無料枠は毎月の請求サイクルの開始時にリセットされます。また、消費した分は「実行した人」ではなくリポジトリの所有者に課金される点も覚えておいてください。

OSによって消費が変わる(超過後の単価)

無料枠を超えた分の単価は、OSと構成によって大きく違います(2026年1月1日改定後の標準ランナー)。

ランナーの種類1分あたり(USD)
Linux 1コア(x64)$0.002
Linux 2コア(x64)$0.006
Windows 2コア(x64)$0.010
macOS 3〜4コア$0.062
※ GitHubは2025年12月に価格改定を発表し、2026年1月1日からGitHubホストランナーの価格を最大39%引き下げました。また、セルフホストランナーへの新課金(1分あたり$0.002のActionsクラウドプラットフォーム料金)については、当初2026年3月1日開始と案内された後、GitHubが適用を延期してアプローチを再検討すると表明しています。最新の状況は必ず公式ドキュメントでご確認ください。

なお、支払い方法を登録していないアカウントは、無料枠を使い切った時点で実行がブロックされます。意図せず高額請求される心配はありませんが、逆にワークフローが突然動かなくなるので注意してください。


個人の定期バッチを無料で自動化することは可能か?

結論:可能です。ただし、いくつか押さえるべき条件と落とし穴があります。

無料で回すための条件

  1. パブリックリポジトリを使う:これが最重要です。公開リポジトリでの標準GitHubホストランナー利用は無料なので、実行時間を気にせず回せます。処理内容を公開したくない場合はプライベートリポジトリになり、無料枠(Freeなら月2,000分)の中でのやりくりになります。
  2. Linuxランナーを使うruns-on: ubuntu-latestが最も安価です。プライベートで運用する場合、Windowsは約1.7倍、macOSは約10倍の消費として計算されます。
  3. scheduleイベントで定期実行する:cron形式で日時を指定します。

実際のコード例:毎日9時(日本時間)に処理を回す

# .github/workflows/daily-batch.yml
name: 毎日のバッチ処理

on:
  schedule:
    - cron: '0 0 * * *'     # UTCの毎日0:00 = 日本時間の毎朝9:00
  workflow_dispatch:         # 手動実行もできるようにしておくと便利

jobs:
  batch:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-python@v6
        with:
          python-version: '3.12'
      - run: pip install -r requirements.txt
      - name: バッチ本体を実行
        run: python main.py
        env:
          API_KEY: ${{ secrets.API_KEY }}


知っておくべき落とし穴

  1. cronの時刻はUTC(協定世界時)が既定:日本時間はUTC+9なので、「日本時間 − 9時間」で書きます。日本時間の朝9時なら0 0 * * *です。
    ※ 現在はtimezone:を併記してタイムゾーンを指定する記法も用意されています。
  2. 指定時刻ぴったりには動かない:公式ドキュメントは「scheduleイベントはGitHub Actionsの高負荷時に遅延することがあり、負荷が十分に高い場合はキューに入ったジョブが破棄される可能性がある」と明記しています。とくに毎時0分は世界中のジョブが集中するため、7 0 * * *のように中途半端な分を指定するのが実践的な回避策です。厳密な時刻保証が必要な処理には向きません。
  3. ワークフローファイルはデフォルトブランチに置くscheduleはデフォルトブランチ(通常main)に存在するファイルしか実行しません。また実行もデフォルトブランチ上で行われます。
  4. パブリックリポジトリは60日放置で自動停止:公式ドキュメントによれば、リポジトリに60日間何の活動もないと、スケジュール実行されるワークフローは自動的に無効化されます。個人の放置しがちなバッチではこれが最大の罠です。定期的にコミットするか、無効化された際に画面から手動で再有効化する必要があります。
  5. 状態の保存には工夫がいる:ランナーは毎回まっさらな使い捨てです。前回の実行結果を引き継ぎたい場合は、リポジトリにファイルをコミットして戻す、アーティファクトに保存する、外部のデータベースを使うといった手段が必要です。



向いている用途・向かない用途

向いている向いていない
・毎日のスクレイピングとデータ収集
・RSSやAPIを定期取得して通知
・データの定期バックアップ
・静的サイトの定期ビルド・再公開
・古いIssueの自動クローズ
・秒単位の正確さが要る処理
・数時間かかる重い処理(1ジョブ6時間の上限あり)
・常時起動が必要な常駐サーバー
・大量の状態をランナー上に持ちたい処理

まとめると、「1日1回〜数回、数分で終わる、多少時刻がずれても困らない処理」であれば、GitHub Actionsは個人の定期バッチ基盤として極めて優秀です。サーバー代ゼロ、監視ゼロ、コードとスケジュールを同じ場所で管理できるという利点は、レンタルサーバーのcronにはない大きな魅力です。


次に覚えると強い追加知識

基本を押さえたら、次はこのあたりを知っておくと一気に実用度が上がります。

アーティファクト(artifact):ワークフローが生み出した成果物ファイル(ビルド済みアプリ、テストレポート、ログなど)を保存し、後からダウンロードしたり別のジョブへ受け渡したりする仕組みです。ジョブ間でファイルを共有する標準的な方法です。


キャッシュ(cache):npmやpipでインストールするライブラリなど、毎回同じものを再取得するのは時間の無駄です。キャッシュを使うと2回目以降の実行が劇的に速くなります(実行時間=コストなので節約にもなります)。


マトリックス(matrix):「Node.js 20と22の両方」「WindowsとLinuxの両方」のように、条件を変えて同じジョブを複数回まとめて実行する機能です。1つの定義で組み合わせ全パターンを検証できます。


再利用可能ワークフロー(reusable workflows):共通のワークフローを1か所に定義し、複数のリポジトリやワークフローから呼び出す仕組みです。同じ内容のコピペが増えてきたら導入を検討します。


環境(environments):「ステージング」「本番」といったデプロイ先を定義し、承認者のレビューを必須にしたり、環境ごとに専用のシークレットを持たせたりできます。本番デプロイの事故防止に有効です。


実行の制限:ジョブは最大6時間、ワークフロー全体は最大35日といった上限があります。長時間処理を組む前に公式の制限一覧を確認しておくと安心です。


まとめ

  • CI/CDは、ビルド・テスト・デプロイという繰り返し作業を自動化する考え方です。
  • GitHub ActionsはGitHub公式のCI/CDプラットフォームで、CI/CD以外の雑務自動化にも使えます。
  • 用語の関係は「イベント → ワークフロー → ジョブ → ステップ → アクション」で、ジョブを実行する場所がランナーという入れ子構造です。
  • ワークフローは.github/workflowsにYAMLで置きます。この場所は固定です。
  • ランナーは毎回まっさらな仮想マシン。ジョブが違えばマシンも別です。
  • 機密値は必ずシークレットに。コードへの直書きは厳禁です。
  • パブリックリポジトリなら標準ランナーは無料。プライベートはプランごとの無料枠(Freeで月2,000分)内。
  • 個人の定期バッチの無料自動化は十分可能。ただし「UTC基準」「実行時刻の遅延」「パブリックリポジトリの60日無操作で自動停止」の3点には要注意です。

まずは自分のリポジトリに.github/workflows/hello.ymlを作り、run: echo "Hello Actions"だけのワークフローを動かしてみてください。GitHubのActionsタブに緑のチェックが付く体験をすると、ここまでの用語が一気に立体的につながります。


参考リソース

※本記事の料金・バージョン情報は2026年7月時点のものです。GitHubの仕様や価格は変更されることがあるため、最新情報は必ず公式ドキュメントをご確認ください。

コメント

タイトルとURLをコピーしました