0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PytestのCIをGithub Actionsで書いていた時にハマった話

Last updated at Posted at 2025-01-31

はじめに

テストを自動化する際、GitHub Actions(GHA)でPytestを走らせるケースが多いと思います。今回は、Pydantic の BaseSettings を利用して環境変数を読み込む際に「GHA上でうまく読み込めずエラーになる」問題に直面したので、ハマりどころと解決策をまとめます。

想定読者・参考になる読者

  • Python + Pydantic で環境変数管理を行っている方
  • GHA を使ってCI/CDを構築している、またはこれから導入したいエンジニア
  • ローカルでは動くのに、GHA上でパスの扱いに困っている方

結論、パスの指定方法が問題だったということなので、先にディレクトリ構造のサンプルを描きます。
settings.py は app/ ディレクトリ内に置き、.env.xxxはすべて app/config/ 配下で管理します。

my_project/
├── .github/
│   └── workflows/
│       └── ci-test.yml        # GHAのワークフロー定義ファイル
├── app/
│   ├── config/
│   │   ├── .env.test         # テスト用環境変数ファイル
│   │   ├── .env.development  # 開発用環境変数ファイル
│   │   └── ...               # 他の環境ごとの.envファイル
│   └── settings.py           # PydanticのSettingsクラス
├── tests/
│   └── test_sample.py        # テストファイル
├── requirements.txt          # 必要に応じて依存関係リスト
└── README.md                 # プロジェクト概要

ハマった経緯

  • PydanticのBaseSettingsを継承したSettingsクラスで、class Configのenv_fileを使って.envファイルを読み込んでいた。
  • もともとローカルで動かす際はenv_file = f"config/.env.{env}"のように相対パスで指定していて問題なく動作していた。
  • しかし、GHAでテストを動かしたところ「Pydanticに環境変数が読み込めない」というエラーが発生。(このときは.envファイルが読み込めないみたいなエラーメッセージがでないのがハマらせたポイント)
python settings.py
import os
from pydantic import BaseSettings

class Settings(BaseSettings):
    # 例: 環境変数として読み込む項目
    SAMPLE_ENV: str

    # .envファイル用の設定。環境変数によって.envファイルを動的に読み込む
    class Config:
        # GitHub Actions から渡される SAMPLE_ENV が無ければ "development" にする
        env = os.getenv("SAMPLE_ENV", "development")
        env_file = f"config/.env.{env}" # ←ここがGHAから実行したときにenvファイルが読み込めなかった
        case_sensitive = True

結論

  • env_file = f"app/config/.env.{env}"のように絶対パスに変更したら問題なく読み込めるようになり、エラーが解消した。
  • env_fileの読み込みは相対パス、絶対パスの両方をサポートしている

https://docs.pydantic.dev/latest/concepts/pydantic_settings/#dotenv-env-support
In either case, the value of the passed argument can be any valid path or filename, either absolute or relative to the current working directory. From there, pydantic will handle everything for you by loading in your variables and validating them.

import os
from pydantic import BaseSettings

class Settings(BaseSettings):
    # 例: 環境変数として読み込む項目
    SAMPLE_ENV: str

    # .envファイル用の設定。環境変数によって.envファイルを動的に読み込む
    class Config:
        # GitHub Actions から渡される SAMPLE_ENV が無ければ "development" にする
        env = os.getenv("SAMPLE_ENV", "development")
-       env_file = f"config/.env.{env}"
+       env_file = f"app/config/.env.{env}" # ←絶対Path指定
        case_sensitive = True

解決策

1. ファイル構成を確認する

  • GHA上でチェックアウトされるディレクトリの構造を把握する。
  • env_fileに指定するパスは、GHAのプロジェクトルートで実行されることを考慮する。

2. 絶対パス(またはルート相対パス)を使う

  • env_fileにapp/config/.env.{env}のようにディレクトリ名を含めて指定する。
  • これにより、GHAで動かしても指定したディレクトリを参照できる。

まとめ

  • ローカル開発とCI/CD環境(特にGitHub Actions)の実行パスの違いにより、Pydanticのenv_fileの読み込みが上手くいかないことがある。
  • ハマりを回避するために絶対パスを指定することで問題が解決する場合が多い。
  • パスの読み込み方法を変えたら、大丈夫だと思うが一応実際にアプリケーションをテストして想定通り動くかテストすると安心。
  • 一度うまく動いていたとしても、ディレクトリ構成やワークフローが変わると再びハマる可能性があるため、定期的な確認や他環境でのテストを行うのがおすすめです。

以上が、PytestのCIをGithub Actionsで動かす際にPydanticのenvファイル読み込みでハマった話でした。同様の問題が起きた場合には参考にしてみてください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?