GithubActionsでrunにifを書かない方法で、ステップごとに実行判断をするロジックの書き方・使い方(実例あり)
公式リファレンス
Github Docs
本稿ではstepsコンテキストを使っています
実行結果によって処理をする・しないを分岐する
先に結論を言うと、runでif文を書けるので、shellを書くのと同じ感覚で書けばやりたい事は実現できます。
ロギングがしたいならechoでログを出すか、ログファイルも更新してpushすればGithubActionsを探しに行かなくてよくなります。
が、ここではGithubActionsの流儀に則って制御を考えます。
また、runで実行すると、途中でエラーになった時にどこで失敗したのか特定するのが難しくなるので、運用を考えるならなるべく切り分けたいからです。
やり方は、if: 条件
をいれるだけです。
問題は、条件に何を書くかです。
条件分岐で使えるもの
色々なものが使えますが、ここでやりたいのは「前回実行したステップの結果を受け取りたい」というものです。
たとえば、前回実行した結果が全て完了したとか、特定の処理をしたかどうか。
解決アプローチとして、3つのパターンがあります。
- そもそもstepをまとめてしまう
- 前stepの結果を判定するロジックをrunで書く
- 【今回採用】stepを実行する前にif条件を入れる
大事な事なのでもう一度繰り返します。
うまく行かない場合は、今回採用する方法にこだわる必要はありません。
実務で採用する場合にまで、後でできる事を今こだわるとハマって進捗率を下げてしまう、なんて事も考えられます。
状況に合わせて活用してください。
ソース例と解説
今回の制御で見る公式ドキュメントの位置
Thanks:
if: steps.(ステップのid).outcome == "success"
が最もわかりやすいです。
以下のような使い方ができます。
- name: 確実に成功する処理
id: test1
continue-on-error: true # 処理が失敗しても継続させる
run: echo "成功"
- name: 実行される事を確認
if: steps.test1.outcome == "success"
run: echo "処理される"
- name: 確実に失敗する処理
id: test2
continue-on-error: true # 処理が失敗しても継続させる
run: exit 1
- name: 実行される事を確認
if: steps.test2.outcome == "success"
run: echo "スキップ"
- name: 確実に失敗する処理
id: test2
continue-on-error: true # 処理が失敗しても継続させる
run: exit 1
- name: 実行される事を確認
if: steps.test2.outcome == "success"
run: echo "スキップ"
適当なリポジトリを作って、.github/workflows
以下に置いて検証してみてください。
実践例
この方法は、Ubuntu20.04にデフォルトで入っているpythonのバージョンが古くて動かないスクリプトがある場合、処理をしないための例です。
参考
Ubuntu22.04 LTSではどうなるか気になるところです。
ソースコード
runs-on: ubuntu-latest
steps:
# 以下、ステップ
- name: PosixPath.with_stemが使えないので、スクリプトを実行できるか判断する
id: check_python
continue-on-error: true
run: |
# python3のマイナーバージョンが9未満か判定
if [ "$(python3 --version | cut -d"." -f2)" -lt "${minor}" ]
then
exit 1
fi
- name: スクリプトを実行
if: steps.check_python.outcome == 'success'
run: python3 (実行スクリプト)
check_pythonでexit 1
を実行しなければスクリプトを実行します。
応用例
この方法は、Ubuntu20.04にデフォルトで入っているpythonのバージョンが古くて動かないスクリプトを動かすための例です。
もっといい方法があるので、以下はあくまで実践例です。
今回のGAとは関係ないですが、WSLに入れる時に参考になりました。
ソースコード
# 実行環境
runs-on: ubuntu-latest
steps:
# 以下、ステップ
- name: 判定ロジックは同じ。上記では`exit 1`で終わらせたが、こちらはインストールする
id: check_python
env:
minor: 9
run: |
pyc=$(python3)
# python3のマイナーバージョンが9未満の時だけ実施する
if [ "$(python3 --version | cut -d"." -f2)" -lt "${minor}" ]
then
sudo apt update && sudo apt install software-properties-common
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt install python3.${minor}
pyc=python3.${minor}
sudo apt update && sudo apt install python3.${minor}-distutils
fi
echo "::set-output name=pyc::${pyc}"
- name: pythonスクリプト実行
env:
# id: check_pythonの出力からpycを取得してenvに入れる
pyc: ${{ steps.check_python.outputs.pyc }}
run: |
${pyc} -m pip install --upgrade pip
${pyc} -m pip install pathlib
${pyc} (実行スクリプト)
pyc
にはpython3
かpython3.9
か、どちらかが入っています。
重要なのは、実行するステップではpyc
に何が入っているか気にしなくても良い事です。
より厳密なチェックをするなら、which "${pyc}"
のパスが有効である事を検証するのも良いかもしれません。
良い方法
環境構築系は自分で頑張るより、uses
を探した方が楽です。
pythonのバージョンを指定する方法はあります。
steps:
- uses: actions/setup-python@v3
with:
python-version: '3.9'
- name: pythonスクリプト実行
run: |
python -m pip install --upgrade pip
python -m pip install pathlib
python (実行スクリプト)
あれだけ長いコードが、こんなに圧縮できるのでuses
は非常に優秀です。
uses
で使えるものは以下の通り
今回使ったもの
使えるもの
自分でuses
を作れます
uses
を見ると、Githubユーザー/リポジトリ
の関係であることに気付きます。
これは具体例を挙げるのが難しい(私が具体例を知らないため)ですが、オリジナルの環境構築ができるのは便利です。
メンテナンスを考えると決して楽な選択ではありませんが、どうしてもという場合には使えそうです。
使用例
私がやりたかったこと
pushされるたびにCHANGELOG.mdを自動で生成してPRを出すスクリプトを書きたかったんですが、
- github-changelogs(node)
- github-changelog-generator(ruby)
を使って自動生成する仕組みを作ろうとしていました。
わざわざ自前で環境構築をやってコマンド打ち込んで…とやると大変なので、CIでなんとかならないかと思っていたところでした。
いきなり難しい事をやると手がつかないので、手始めに上記のように簡単なCIを色々作ってみてGithubActionsのナレッジも蓄積してきたので、そろそろ挑戦しようと思っていました。
実務ではなく趣味でやっているCIだと、CIの勉強だけだと運用経験が積めず、なかなか学びが進まないので非常に時間がかかりましたが、ようやくここまで来れました。
本稿の内容を踏まえて、プログラマーを目指す方へ
ぶっちゃけ本題です。
冗長になりすぎたので、別記事にします。
Author And Source
この問題について(GithubActionsでrunにifを書かない方法で、ステップごとに実行判断をするロジックの書き方・使い方(実例あり)), 我々は、より多くの情報をここで見つけました https://qiita.com/nomurasan/items/90cc5288bb65988a578a著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .