📋

3_AIで下駄を履いてなんかすごそうなゲームやらツールを作るのではなく、まずは再学習も兼ねて身の丈に合った開発から始めた話

に公開
2026/10/01

https://zenn.dev/sonnerie_9695/articles/fbacf6dd77373b

前回↑までは、Zenn向けの記事自動整形ツールとして、

H2の整形
+
連続する空行の変換
+
引用ブロックの変換
+
実Markdownを使ったpytest

というところまで作った。


今回はツールそのものへ機能を追加するのではなく、

GitHubへpushする
↓
pytestが自動で実行される
↓
結果がGitHub上で分かる

という状態を作ることにした。


目標はかなり小さく、

GitHubにコードを送っただけで、pytestが勝手に緑になるところまで作れるか?

の、ここまで。


実際に作ったものはここに置いている。

https://github.com/Sonnerie-9695/public_ArticleFormatter




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が勝手に結果を返してくれる。

まずはそれで十分な気がしている。

次の記事↓
https://zenn.dev/sonnerie_9695/articles/970968af9c7a6d

Discussion