実務でも使いそうなCI運用の話

Table of Content

個人・趣味で運用しているGithubActionsですが、思った以上に実務チック(?)なコードになってしまったので、後でメンテナンスする際に困らないように解説しておきます。
実務に耐えるレベルのエッセンスが多いので、解説ナシだと読み込むのが辛くなりました。

コード

https://github.com/shimajima-eiji/__Backup_Images/blob/main/.github/workflows/convert_webp.yml

メンテに困らない程度のコメントを残していますが、初見で理解するのは大変です。
一つずつ解説していきます。

解説

目的: Pythonのバージョンを3.9以上であることを担保する

これは後述のpythonスクリプトでPython3.9以上が必要なものがあり、しかしOSデフォルトのpythonが3.9未満の場合を想定しています。
執筆時点で使用しているのは、Ubuntu20.04で、バージョンも3.9未満なので該当します。

が、将来的に環境が変わったらpythonのバージョンも変わるはずなので、古いバージョンだった時だけ3.9を入れて環境構築するようにしました。
ここでのポイントは、if条件で小数点を判定するのではなくcutコマンドやawkコマンド他をうまく活用して「.(ドット)」でマイナーバージョンを取れば判定ができるという点です。
pythonも2系が使えないというのを明示する意味でpython3とコマンドでもバージョンを明記しています。

webp用のpythonスクリプトをcurlで取得し実施

pycとは、python3かpython3.9のどちらかですが、どの場合でもpipにインストールできるようにpython3(3.9) -m pip install…の形式を取る事で、パッケージインストールが確実に行われるようにしています。
また、pipインストールは1行にまとめて実行できるはずですが、この書き方だとうまくいかないので、1行1パッケージでインストールを進める事で解消しました。
これは何が違うんでしょうね?そこまでは調査していません。

ファイルの変更をgit statusで取得する

コードはシンプルな割に、GithubActionsのエッセンスが多いのもこのセクションです。
continue-on-errorでエラーを発生させても処理を継続させるようにしています。
ファイルを検出しなかった場合、以降のPush & Pull Requestのステップは実行しないようにしました。
スクリプトで言うと、`if [ “$(git status -s)” ]`の部分が該当します。

本来であれば面倒臭いので、これらのステップもまとめて1つに集約するところですが、なんで分けたのか忘れてしまいました。
たぶんロギングの都合かなぁ。デバッグが大変だったのは覚えています。

次以降のステップで変数を使いまわしたい

同一run上なら変数宣言をしたらshell scriptを作成するノリで完結できますが、ステップをまたぐ場合は変数を渡せません。
これを解決する方法が本項です。

上記はエッセンスを抽出したのですが、一連のスクリプトのnameには対応するidを入れており、ここでは「commit」という名前をつけています。
他(以降)のステップで参照したい場合は${{ steps.commit.outputs.OWNER }}とかで取得できます。
イメージとしては、JavaScriptの連想配列あるいはPythonのdictで、idが変数名で、OWNERがキーと考える事ができそうです。

プルリクエストの「判断」処理

PRはhubコマンドで実施しています。hubコマンドの解説はここではしません。

if: steps.commit(id).conclusion == 'success'がキモです。
前段で実施しているid: commitif [ "$(git status -s)" ]で成功・失敗を判定して終了ステータスを0(成功)または0以外(失敗)をさせている事がポイントです。
条件がわかっているので、ここでもこんな事をしないで、run内でif [ "$(git status -s)" ]と書けば同じ事ができます。
開発当時は、そもそもステップを分けるようなことはしていませんでしたが、ロギングができないので何とかできないか探したのが、本スクリプトです。

誤解を恐れずに言えば、最も簡単に動かすならステップを1つにまとめてrun内でifを使って制御する事です。
全ての処理が正常終了したらSuccessになるし、どこかで失敗したらFailedになります。
CI運用と考えれば、どこかで失敗したら処理をすぐに止めるのはフェイルセーフ設計の観点からも適切な挙動です。
ただし、どこで失敗したのかを知りたい場合はあまりにも不親切と言えます。

デバッグ時に苦労したので、こう言った作りにしています。

GithubActionsやCIに慣れていない方はrun, スキルアップするならステップを分けよう

これからCIを勉強する方は、これぐらいの感覚で考えていても良いと思います。
ただし、実務で使うならきちんとロギングできるように環境を整備しておきましょう。

シェアする