あらすじ
- こちらやこちらでテトリスを題材にpythonを学べるプログラムを自作していた
- プログラムが大きくなるにつれて動作確認が大変になってきた(ミスも多くなってきた)
- プログラムはgithubで管理しており、
github actions
が便利そうなので動作確認に使った。
github actions
とは
https://docs.github.com/ja/actions/learn-github-actions/understanding-github-actions
GitHub Actions は、ビルド、テスト、デプロイのパイプラインを自動化できる継続的インテグレーションと継続的デリバリー (CI/CD) のプラットフォームです。 リポジトリに対するすべての pull request をビルドしてテストしたり、マージされた pull request を運用環境にデプロイしたりするワークフローを作成できます。
ワークフローの作り方
ワークフローはリポジトリ内の .github/workflows ディレクトリで定義され、リポジトリには複数のワークフローを含めることができます。各ワークフローは、それぞれ異なる一連のタスクを実行できます。 たとえば、あるワークフローでは、pull request をビルドしてテストし、別のワークフローでは、リリースが作成されるたびにアプリケーションをデプロイし、さらに別のワークフローでは、新しい issue が開かれるたびにラベルを追加することができます。
テトリスを題材にpythonを学べるプログラム
以下のようなものを作成していました
Tetris Game
プログラミング学習を目的とした、ブロックを操作してスコアを競うゲームです。
作成背景は以下の通り
動作確認が大変になってきた
- プログラムをアップデートするにつれて実行オプションが増えてきた(難易度変数、サンプルコード増加、その他)
- 想定すべき実行環境が増えてきた(
ubuntu18.04,20.04
,python3.x
系) - プログラムの中身を変えた時に思わぬ箇所に影響が出てバグって動かない事態にしばしば直面
- ほぼ全てに影響するバグが潜在した場合、顕在化するまで潜伏期間1週間〜掛かり気付いた時には超特急で修正必要になる事にしばしば直面、夜中に泣きながら修正することが発生して精神衛生上良くない。
以下のような対策をした
- プログラムを変えた際は、主要な実行オプションは網羅的にテストする。
- 細かい動作はテストやりきれない事があるが、クラッシュしない確認だけでも平穏が訪れる。
- AIが動いている部分については学習と評価を簡易でも良いので実行しておく。
実際に使ったgithub actions
のワークフロー(.github/workflow/test.yaml
)
push時
及びpull request時に
github actionsを発動させ、致命的な不具合が発生していないことのテストを行った。
github actions
の設定ファイル
name: test-ubuntu
on:
# push/pullrequest時にci実行
push:
branches: [master] # masterへのpush時に発動
pull_request:
paths-ignore: # ここのファイルの更新時は不要なのでworkflow発動させない
- '.gitignore'
- 'LICENSE'
- '**.md'
# 環境変数
env:
BRANCH_NAME : "master" # workflow上で使う環境変数
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.9', '3.10'] # "python-version"の変数リスト('3.9', '3.10'で微妙に動作に違いが出たので念のため両バージョンでチェック)
steps:
- name: checkout repository
uses: actions/checkout@v3
with:
path: target_dir
- name: Set up Python ${{ matrix.python-version }} # "python-version"の変数リスト分workflowを立ち上げる
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies # 依存ライブラリをインストールしておく
run: |
sudo apt-get update
python -m pip install --upgrade pip
pip install flake8 pytest
sudo apt-get install -y python3-pip
pip3 install --upgrade pip
sudo apt-get install -y git
sudo apt-get install -y jq
- name: tetris_sample # 基本となるサンプルコードの確認
working-directory: target_dir
# tetrisが動くかどうか確認(SCOREが入ればOK)
run: |
# QT display off
export QT_QPA_PLATFORM=offscreen
# run tetris
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
python start.py -m sample -t 3 -f $HOME/result.json
# check result
jq . $HOME/result.json
SCORE=`jq ."judge_info"."score" $HOME/result.json`
echo "SCORE: $SCORE"
if [ $SCORE -lt 0 ]; then echo "error";exit 1; fi
- name: tetris_DQN_sample # DeepQNetwork版サンプルコードの動作確認
working-directory: target_dir
run: |
# QT display off
export QT_QPA_PLATFORM=offscreen
# run tetris
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
if [ -f requirements.pytorch.txt ]; then pip install -r requirements.pytorch.txt; fi
python start.py -m predict_sample -l 2 -t 5 --predict_weight weight/DQN/sample_weight.pt -f $HOME/result_dqn.json
# check result
jq . $HOME/result_dqn.json
SCORE=`jq ."judge_info"."score" $HOME/result_dqn.json`
echo "SCORE: $SCORE"
if [ $SCORE -lt 0 ]; then echo "error";exit 1; fi
- name: tetris_MLP_sample # Multilayer perceptron版サンプルコードの動作確認
working-directory: target_dir
run: |
# QT display off
export QT_QPA_PLATFORM=offscreen
# run tetris
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
if [ -f requirements.pytorch.txt ]; then pip install -r requirements.pytorch.txt; fi
python start.py -m predict_sample2 -l 2 -t 5 --predict_weight weight/MLP/sample_weight.pt -f $HOME/result_mlp.json
# check result
jq . $HOME/result_mlp.json
SCORE=`jq ."judge_info"."score" $HOME/result_mlp.json`
echo "SCORE: $SCORE"
if [ $SCORE -lt 0 ]; then echo "error";exit 1; fi
- name: tetris_DQN_sample3 # DeepQNetwork版サンプルコード2の動作確認
working-directory: target_dir
run: |
# QT display off
export QT_QPA_PLATFORM=offscreen
# run tetris
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
if [ -f requirements.pytorch.txt ]; then pip install -r requirements.pytorch.txt; fi
python start.py -m predict_sample3 -l 2 -t 5 --predict_weight weight/DQN/sample_weight.pt -f $HOME/result_dqn.json
# check result
jq . $HOME/result_dqn.json
SCORE=`jq ."judge_info"."score" $HOME/result_dqn.json`
echo "SCORE: $SCORE"
if [ $SCORE -lt 0 ]; then echo "error";exit 1; fi
工夫したことがあるとすれば
GUI表示の無効化
今回ディスプレイを使うのはpyqt
のみだったのでexport QT_QPA_PLATFORM=offscreen
でQT displayオフにした
# QT display off
export QT_QPA_PLATFORM=offscreen
場合によっては仮想ディスプレイを使っても良いかもしれない(Qt以外を使う場合など)
# xvfbのインストールと起動
- name: Xvfb install and run
run: |
sudo apt-get install -y xvfb
Xvfb -ac ${{ env.DISPLAY }} -screen 0 1280x780x24 &
エラー発生時(クラッシュなど)はエラー側に倒しまくる
echo $?
や結果が期待通りかどうか(スコアが更新されているか等)を少しでもチェックして、期待通りでなければエラー側に倒して気づけるようにする。が現状は努力目標となっている。
ubuntu
だけでなくwindows
のpowershell
でも動くことを想定してworkflowを記載
自分で使う限りではubuntuマシンのみを想定すればよいが、周囲に布教させようとする場合はたとえ開発系の職場であってもwindowsマシン(のpowershell)で動かすことを想定せざるを得ない場合が往々にして存在する。なぜならば誰もが自宅にubuntuマシンを所持しているわけではないためである。(体感8割の人が自宅にubuntuマシンを所持していない。ubuntuマシンを自宅に所持している人はどちらかというとマイノリティのはずである。一般的にはそのはずである。)
windowsマシン(のpowershell)を想定してgithub actions
を記載する場合は以下のようにjobs:
欄にruns-on: windows-latest
と記載すればOK。
ただし以降の構文はpowershell
ライクな感じになるので気をつける必要がある。
https://github.com/seigot/tetris/blob/master/.github/workflows/test-windows.yaml
... jobs: build: name: MSBuild runs-on: windows-latest ...
今後の課題
- テストを拡張させたいが、仮想マシンの月当たりの利用時間に制限がある。必要なテスト優先で追加する。
-
長時間の処理が必要な場合は、別途テスト用のPCを用意もしくはパブリックリポジトリの場合はCI/CD時間は無料でした。githubさんありがとうございます。github
に課金する(テストしないよりはまし、時間リソースは大切である) -
github actions
のワークフローの良い書き方、ベストプラクティスを継続して調べる。
参考
https://github.com/seigot/tetris
プログラミング学習を目的とした、ブロックを操作してスコアを競うゲームをpythonで作成する試み
Xvfb を使って仮想ディスプレイを作る
https://github.com/marketplace/actions/url-checker