3_AIで下駄を履いてなんかすごそうなゲームやらツールを作るのではなく、まずは再学習も兼ねて身の丈に合った開発から始めた話
前回↑までは、Zenn向けの記事自動整形ツールとして、
H2の整形
+
連続する空行の変換
+
引用ブロックの変換
+
実Markdownを使ったpytest
というところまで作った。
今回はツールそのものへ機能を追加するのではなく、
GitHubへpushする
↓
pytestが自動で実行される
↓
結果がGitHub上で分かる
という状態を作ることにした。
目標はかなり小さく、
GitHubにコードを送っただけで、pytestが勝手に緑になるところまで作れるか?
の、ここまで。
実際に作ったものはここに置いている。
1. 今回形にしたかったもの
作りたかったのは、GitHub Actionsを使った最小限のCI。
やりたいこと自体は単純で、
push
↓
GitHub Actions起動
↓
Pythonを用意
↓
必要なパッケージを入れる
↓
pytest
だけ。
Dockerやデプロイをやりたいわけではない。
複雑なWorkflowを組みたいわけでもない。
まずは、
手元で毎回
pytestを打たなくても、pushしたコードのテスト結果がGitHub上で分かる
状態を作ることにした。
2. まずは、覚えている範囲でWorkflowを書いてみた
最初は雛形を一度見たあと、
できるだけ思い出しながら書いてみた。
最初に書いたものはこんな感じだった。
name: run-pytest
on: push
jobs:
uses: ubuntu-latest
steps:
name: Checkout repo
uses: actions/checkout@7
steps:
name: Set up python
uses: actions/python-setup@7
steps:
name: install requirements
run: pip install requirments.txt
steps:
name: run pytest
run: python3 -m pytest
...当然、色々おかしい。
jobsの下にはjobを定義する必要があるし、
runs-on:
も必要。
stepsも、一つずつ何度も書くものではない。
Action名も、
actions/python-setup
ではなく、
actions/setup-python
だった。
正解(サンプル)を見ながら照らし合わせて、
少しずつ構造を直していった。
3. ubuntu 26と書いたら、永遠に待ち始めた
途中で、こんなWorkflowになった。
jobs:
test:
runs-on: ubuntu 26
これをpushしてみると、
Requested labels: ubuntu 26
Waiting for a runner to pick up this job...
という状態から進まなくなった。
しばらく待ってみたが始まる様子がないので、
一度手動で中断。
最終的には、
runs-on: ubuntu-latest
へ変更した。
ここで、
runs-on
→ Workflowを実行する環境を指定するもの
という意味が少し具体的になった。
適当なUbuntuのバージョン名を書けばいいわけではなく、
GitHub Actions側が使えるrunnerを指定する必要がある。
4. 次はpip installで二回転んだ
runnerが動くようになったあと、
今度は依存パッケージのインストールで失敗した。
まず単純に、
requirments.txt
とスペルを間違えた。
そしてこれを直したあとも、
pip install requirements.txt
としていたため、再び失敗。
ログを見ると、
Could not find a version that satisfies the requirement requirements.txt
と出ていた。
さらに、
You are attempting to install a package literally named "requirements.txt"
というヒントも表示された。
つまりこの書き方では、
requirements.txtという名前のパッケージをインストールする
という意味になってしまっていた。
必要だったのは、
pip install -r requirements.txt
だった。
最終的には、使用するPythonも明確になるように、
python -m pip install -r requirements.txt
へ変更した。
5. 最小のWorkflowが通った
最終的に、Workflowはこうなった。
name: run-pytest
on: push
permissions:
contents: read
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v7
- name: Set up python
uses: actions/setup-python@v7
with:
python-version: "3.14"
- name: Install requirements
run: python -m pip install -r requirements.txt
- name: Run pytest
run: python3 -m pytest -v
やっていることを並べると、
リポジトリの中身を取得
↓
Python 3.14を用意
↓
requirements.txtから依存関係を入れる
↓
pytestを実行
だけ。
これをpushしたところ、
一通りのstepが通り、
pytestも緑になった。
これで最初に置いていた、
GitHubにコードを送っただけで、pytestが勝手に緑になる
という状態までは作れた。
6. せっかくなので、わざとpytestを壊してみた
ただ、
緑になった
だけでは、
GitHub Actionsがテスト失敗をどう扱うのかをまだ見ていない。
そこで一つ、
必ず失敗するテストを追加してみた。
元の処理では、
formatted_text = ["foo", "bar", "hoge"]
を保存すると、
ファイルから読み込んだ値は、
"foo\nbar\nhoge"
という文字列になる。
そこをわざと、
assert target_path.read_text(encoding="utf-8") == formatted_text
として、
文字列とリストを比較するテストを追加した。
当然失敗する。
pushすると、GitHub Actions側でも、
9 passed
1 failed
となり、
Error: Process completed with exit code 1.
でRun pytestが赤くなった。
そのテストをコメントアウトしてもう一度pushすると、
今度は再び緑になった。
🟢
↓
わざと壊す
↓
🔴
↓
元へ戻す
↓
🟢
まで一通り確認できた。
7. GitHub Actionsがpytestを理解しているわけではなかった
今回の挙動を整理すると、
GitHub Actionsが、
pytestのテストが1個失敗した
という内容そのものを理解しているわけではない。
Workflowから、
python3 -m pytest -v
というコマンドを実行する。
pytestがテスト失敗を検知して、
exit code 1
で終了する。
それを受け取ったGitHub Actionsが、
このstepは失敗
↓
jobも失敗
↓
赤
と判定する。
逆にpytestがすべて通れば、
exit code 0
↓
step成功
↓
job成功
↓
緑
になる。
最初は、
GitHub Actions
→ pytestなどの何らかのテストを自動でやってくれるもの
くらいの認識だった。
今回実際に動かしてみてわかったのは、
「新しくまっさらな環境を立てて、
そこに作ったものを配置して、
テストする」
つまり
GitHub Actions
→ 別の環境を用意して
→ 指定したコマンドを順番に実行して
→ その成功・失敗を管理するもの
と捉えた方が分かりやすそうだった。
8. 今回の失敗は、全部違う場所で起きていた
今回だけでも、いくつか違う種類の失敗があった。
ubuntu 26
↓
実行するrunnerが決まらず待機
pip install requirements.txt
↓
依存関係のインストールで失敗
pytestに失敗するテストを追加
↓
pytestがexit code 1を返して失敗
全部画面上では最終的に「赤」になる。
ただ、
どこまで成功して、どのstepで止まったのか
を見ると原因は全然違う。
今回、
Checkout repo ✓
Set up python ✓
Install requirements ✓
Run pytest ✕
という状態を実際に見られたことで、
「CIが失敗した」
だけではなく、
pytestを実行するところまでは正常に到達して、そのpytestが失敗した
と切り分けられることも分かった。
9. 今日できたもの
今回の終了時点では、
- GitHub Actions用のWorkflow
- pushをきっかけにした自動実行
- Ubuntu runner上での実行
- Python 3.14のセットアップ
-
requirements.txtからの依存関係インストール - pytestの自動実行
- pytest成功時の緑
- pytest失敗時の赤
- Actions上でのpytest失敗ログ確認
までを実際に確認できた。
記事整形ツールそのものの機能は、
今回は一つも増えていない。
ただ、
自分のPCでpytestを実行する
だけだった状態から、
コードをGitHubへ送る
↓
別の環境でもpytestが実行される
↓
壊れていれば赤で分かる
というところまでは進んだ。
10. 終わりに
今回やりたかったのは、
GitHub Actionsを詳しく勉強することではなかった。
最初に必要だったのは、
pushしたらpytestが動く
という一番小さいところ。
実際には、
runnerの指定を間違える
↓
requirements.txtのスペルを間違える
↓
-rを付け忘れる
↓
ようやく緑になる
↓
わざとpytestを壊して赤にする
↓
元へ戻して再び緑にする
という流れになった。
最初から正しいWorkflowを貼り付けて終わるよりは、
どこで止まるのか
↓
ログには何と出るのか
↓
直すと次のstepへ進むのか
を一つずつ見られた。
前回までは、
コードが期待通り動くかをpytestで固定する
ところまでだった。
今回はそこから少し進んで、
そのpytest自体を、自分のPC以外でも自動的に走らせる
ところまで来た。
まだ最小構成ではある。
ただ、とりあえず今は、
GitHubへpushすると、pytestが勝手に結果を返してくれる。
まずはそれで十分な気がしている。
次の記事↓
Discussion