【第1回】GitHub Actions × Python 自動化入門 — はじめてのワークフロー作成とCI/CDの基本を理解しよう

プログラミング

GitHub Actionsを「名前は知ってるけどちゃんと使ったことない」状態で放置してたんですが、ある日 main にpushしたらテストが全部落ちてることに気づかず数時間溶かしまして。さすがに「自動でテスト走らせる仕組みが必要だな」と重い腰を上げました。

この記事は全4回シリーズ「GitHub Actions × Python 自動化入門」の第1回です。シリーズ全体の構成はざっくりこんな感じです。

  • 第1回(本記事):GitHub Actionsの基本概念と、Pythonプロジェクト向けのはじめてのワークフロー作成
  • 第2回:pytest連携・複数バージョンのマトリクステスト
  • 第3回:Linter(flake8 / black)とコード品質チェックの自動化
  • 第4回:S3やLambdaへの自動デプロイ(AWS連携)

第1回はCI/CDの概念とワークフローの書き方を丁寧に整理します。「設定ファイルが何を意味してるのかよくわからない」という状態から抜け出すのが目標です。

  • GitHub Actions・CI/CDの基本的な概念がわかる
  • Pythonプロジェクト向けの最小構成ワークフローが書ける
  • トリガーの種類と使い分けがわかる
  • SecretsをYAMLから安全に参照する方法がわかる
  • ワークフローの実行結果の確認方法がわかる

GitHub Actionsって何をするものか

一言でいうと、「GitHubリポジトリ上のイベントをトリガーにして、任意の処理を自動実行できる仕組み」です。

トリガーになるイベントの例:

  • main ブランチへのpush
  • プルリクエストの作成・更新
  • スケジュール実行(cron形式)
  • Issueのオープン、など

処理の内容はYAMLファイルに書くだけで、GitHub側のサーバー(Hosted Runner)で実行してくれます。自前のサーバーは原則不要。

よく使われる用途は「テストを自動実行するCI」と「本番環境へのデプロイを自動化するCD」の2つ。CI/CDという言葉はここから来ています。Continuous Integration(継続的インテグレーション)とContinuous Delivery(継続的デリバリー)の略です。まあ、最初は概念より「pushしたら自動でテストが走る」という感覚のほうが掴みやすいと思います。

料金について(個人開発なら気にしなくていいケースが多い)

GitHub Actionsの料金体系、「結局いくらなの?」ってなりがちなので現時点の情報で整理しておきます。

  • パブリックリポジトリ:標準のGitHubホストランナー(いわゆる “standard runners”)を使う限り、Actionsの実行は無料です
  • プライベートリポジトリ(GitHub Free):月2,000分の無料枠があります(超えると課金、ただし支払い設定がない場合はそこで止まります)
  • セルフホストランナー:プライベート/内部リポジトリでは別途料金が発生する場合があります(最新の料金はGitHub公式ドキュメントで確認してください)

個人の学習用・個人開発用だと、プライベートでも月2,000分あればだいたい足ります。地味に大事なのが「支払い方法を設定してない場合、無料枠を超えたらワークフローがブロックされる」点で、うっかり無限に課金される感じではないです(とはいえ、CIが突然止まると困るので、必要なら予算上限も含めて見ておくのが安心)。

余談ですが、料金の話って「後で読もう」で放置しがちなんですが、Actionsが生活導線に入ると地味に効いてくるので、最初に1回だけ把握しておくと精神的にラクです。

ワークフローの構造を理解する

GitHub Actionsの設定はYAMLファイルとして定義し、リポジトリの .github/workflows/ ディレクトリ以下に置きます。ファイル名は何でもOK(例:ci.yml)。

構造はこんな感じです。

name: ワークフローの名前(GitHub上で表示される)

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

jobs:        # 実行する処理のまとまり
  job名:
    runs-on: ubuntu-latest   # 実行環境
    steps:                   # 具体的な処理ステップ
      - ...

主要な概念を整理するとこうなります。

  • Workflow(ワークフロー):YAMLファイル1つ = 1ワークフロー
  • Job(ジョブ):ワークフロー内の処理単位。複数のジョブは並列実行が基本
  • Step(ステップ):ジョブ内の処理を並べたもの。上から順番に実行される
  • Action(アクション)uses: actions/checkout@v4 のような、再利用可能な処理ブロック

uses: で使えるアクションはGitHub Marketplaceで検索できます。公式・サードパーティのものが大量にあって、正直なんでもあります。

Pythonプロジェクト向けのはじめてのワークフローを書く

実際に動くYAMLを見たほうが早いので、シンプルなものから始めます。

プロジェクト構成の前提

myproject/
├── .github/
│   └── workflows/
│       └── ci.yml        ← ここに書く
├── src/
│   └── calculator.py
├── tests/
│   └── test_calculator.py
└── requirements.txt

サンプルとして使う calculator.pytest_calculator.py も一応載せておきます。

# src/calculator.py
def add(a, b):
    return a + b

def divide(a, b):
    if b == 0:
        raise ValueError("0では割れません")
    return a / b
# tests/test_calculator.py
import pytest
from src.calculator import add, divide

def test_add():
    assert add(2, 3) == 5

def test_divide():
    assert divide(10, 2) == 5.0

def test_divide_by_zero():
    with pytest.raises(ValueError):
        divide(1, 0)
# requirements.txt
pytest

ワークフローファイル(ci.yml)

# .github/workflows/ci.yml
name: Python CI

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

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.13'
          cache: 'pip'   # 依存関係をキャッシュしてビルドを速くする

      - name: Install dependencies
        run: pip install -r requirements.txt

      - name: Run tests
        run: python -m pytest tests/ -v

各ステップを順番に見ていきます。

actions/checkout@v4:リポジトリのコードをRunner上にチェックアウトします。これがないとコードが存在しない状態で始まるので、ほぼ必須のステップ。

actions/setup-python@v5:GitHubホストランナーにはPythonが事前インストールされているため、追加でインストールしなくても使えます。とはいえ、バージョンを明示的に固定したいケースがほとんどなので、このアクションを使うのがお決まりのパターンです。cache: 'pip' を指定すると依存パッケージをキャッシュしてくれて、2回目以降のビルドが速くなります。これは地味に便利。

python-versionの指定'3.13' のように具体的に書くか、'3.x' で最新の3系を使うこともできます。本番環境のバージョンに合わせるのが無難です。

このYAMLを .github/workflows/ci.yml として保存してpushすると、GitHubのActionsタブでワークフローが走るのを確認できます。

トリガーの書き方をもう少し詳しく

on: セクションはけっこうバリエーションがあるので、よく使うパターンだけ整理しておきます。

# パターン1: 特定ブランチへのpushとPR
on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

# パターン2: 特定のファイルが変わったときだけ実行
on:
  push:
    paths:
      - 'src/**'
      - 'tests/**'
      - 'requirements.txt'

# パターン3: スケジュール実行(毎朝9時 JST)
on:
  schedule:
    - cron: '0 0 * * *'   # UTCで指定するので注意

# パターン4: 手動実行(GitHub UI上のボタンで起動できる)
on:
  workflow_dispatch:

paths: を使うと、関係ないファイルが変更されたときにワークフローが無駄に走るのを防げます。ドキュメントだけ更新したときにテストが走る必要はないので、慣れてきたら設定すると良いかと。

schedule: のcronはUTC基準で、スケジュールトリガー自体にタイムゾーン指定はできません。なのでJSTに直すと+9時間です。ここは正直ハマりポイントで、最初「なんか時間がズレる」と思ったらUTC指定でした。

環境変数とSecretsの使い方

APIキーなどの機密情報は直接YAMLに書いてはいけません。GitHubのSecrets機能を使います。

設定場所:リポジトリの Settings → Secrets and variables → Actions → New repository secret

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Run with secrets
        env:
          API_KEY: ${{ secrets.MY_API_KEY }}   # SecretsはこのようにYAMLから参照
        run: python script.py

環境変数として渡す方法と、env: をjobレベルで定義する方法があります。スコープの違いがあって、jobレベルに書くとそのjob内の全stepで使えます。個人的にはstepごとに明示的に渡すほうがわかりやすいかなと思っています。

ちなみに、Secretsの値はログに出力されても自動でマスキングされるので安心です(ただ、完全に事故がゼロというわけでもないので、変な echo とかはしないのが無難)。

ワークフローの実行結果を確認する

pushしたあとは、GitHubリポジトリの「Actions」タブを見ます。ワークフローが実行中・成功・失敗のいずれかで表示されます。失敗した場合はどのステップで何のエラーが出たかをログで確認できます。

テストが失敗した場合、プルリクエスト画面にも「×」マークが表示されるので、レビュー前にCIが落ちてることが一目でわかります。これが地味にうれしい。コードを見る前に「あ、テスト落ちてますね」って言えるようになります。

また、pull_request トリガーを設定しておくと、ブランチ保護ルールと組み合わせて「CIが通らないとmergeできない」設定にすることもできます。チームで使う場合はこれが特に効いてくる機能です。

まとめ

第1回では、GitHub Actions・CI/CDの基本的な概念(Workflow / Job / Step / Action)と、Python向けの最小構成ワークフローを整理しました。actions/setup-python@v5 + pytestの組み合わせだけでも、pushするたびに自動でテストが走る環境が作れます。

  • GitHub ActionsはYAMLファイル1つで自動化ワークフローを定義できる
  • Workflow → Job → Step の階層構造で処理を組み立てる
  • on: でトリガー条件を細かく制御できる(push / PR / スケジュール / 手動)
  • APIキーなどはSecretsに登録してYAMLから参照する
  • 実行結果はActionsタブとプルリクエスト画面で確認できる

マトリクス機能を使うと複数のPythonバージョンで同時にテストを回せたりして、CIっぽさが一気に出てきます。第2回ではそのあたりを掘り下げていきます。

📚 シリーズ「GitHub Actions × Python 自動化入門」(第1回 / 全4回)

→ 次回の記事: 【第2回】GitHub Actions × Python 自動化入門 — テストの自動化(pytest連携とカバレッジレポートの設定)

参考になったらクリックしてもらえると嬉しいです!

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