現在、CIのなかで行なっている自動テスト、lintをする際、develop
blanchでbuildしたDocker imageを使用していた
当時作った僕は浅はかだったため、「テストの実行もできてるしよき!」と思っていた
しかし、今になって
「あれ?develop
の内容でbuildしたimageを使っているから作業ブランチで更新した内容が反映されていないんじゃね?」
と思った。
このことは当時の自分も若干感じていたのかdevelop
のimageでは作業ブランチで行なったgem
とかがインストールされていないと気づいておりworkflow内でbundle install
を実行していた
しかし、ソースコードはどうだろうか
develop
blanchのimageをそのまま使っていたとしたらソースコードはdevelop
blanchの内容のままなはず
そこで、rspecの内容をわざと失敗させて反映されているかどうか確認したところ
しっかりテストが失敗していた
どこで反映されたんだ?と思いworkflowで行われているjobのログを辿ってみた
そこにはしっかりソースコードが反映される様な処理が行われていた
そう、volume
である
まず、jobが実行されている仮想インスタンスの内部はどうなっているのだろうか
確認してみた
job実行後の現在のパス
pwd
=> /home/runner/work/choco_backend/choco_backend
repositoryの名前を参照してrepo/repo
というディレクトリが作成されている
次にGithub Actionsといえばactions/checkout@v2
だと思うが、これはPRのpushされた時の最新のコミットをfetchしてくるので
pwd
=> /home/runner/work/choco_backend/choco_backend
ls
=>
Gemfile.lock
README.md
Rakefile
app
appspec.yaml
bin
config
config.ru
db
docker-compose.development.yml
entrypoint.sh
lib
log
public
spec
storage
taskdef.json
tmp
vendor
の様にソースコードがfetchされている
これを念頭においてjobで行われているcontainer作成時のログを見てみよう
/usr/bin/docker create --name bf55af69c5bc485cb5c6b9fe9f329d5c_ghcrionysdinchoco_backenddevelop_7bd346 --label 6a6825 --workdir /__w/choco_backend/choco_backend --network github_network_2f593213afaf4a4088e9760be1f49aad -e "RAILS_ENV=test" -e "HOME=/github/home" -e GITHUB_ACTIONS=true -e CI=true -v "/var/run/docker.sock":"/var/run/docker.sock" -v "/home/runner/work":"/__w" -v "/home/runner/runners/2.285.1/externals":"/__e":ro -v "/home/runner/work/_temp":"/__w/_temp" -v "/home/runner/work/_actions":"/__w/_actions" -v "/opt/hostedtoolcache":"/__t" -v "/home/runner/work/_temp/_github_home":"/github/home" -v "/home/runner/work/_temp/_github_workflow":"/github/workflow" --entrypoint "tail" ghcr.io/nysdin/choco_backend:develop "-f" "/dev/null"
このログでは、コンテナの作成を行なっている。そのオプションで-v
が指定されているではないか!
注目すべきは以下のオプション指定
-v "/home/runner/work":"/__w"
これによってコンテナ内に/__w/choco_backend/choco_backend/<rails project>
が存在することになる
そして作業ディレクトリが--workdir /__w/choco_backend/choco_backend
と指定されているのでdocker exec <id> bundle exec rspec
などが実行できるというわけだ!!
ところでタイトルにもある様にこれのどこが効率が良いんだって話になるが、通常(?)新しい環境でDocker Containerを起動させる時ローカルにあるDockerfileからimageを1から作成してやると思う
しかし、今回の場合だとimageをdevelop
blanchで作成されたものを指定している
これにより、1からのimage
作成をすることなくdevelop
blanchとの差分(主に新しく追加したgem)だけ高速化できるというわけだ
当初の自分はここまで詳細を把握していたわけではなかったと思うが思わぬ産物!
Github Actionsで行われている挙動を把握することによりこれがいかに効率よかったのかを改めて実感できたよかった〜〜〜