LoginSignup
5
1

More than 1 year has passed since last update.

GithubActionsでrunにifを書かない方法で、ステップごとに実行判断をするロジックの書き方・使い方(実例あり)

Posted at

公式リファレンス

Github Docs

本稿ではstepsコンテキストを使っています

実行結果によって処理をする・しないを分岐する

先に結論を言うと、runでif文を書けるので、shellを書くのと同じ感覚で書けばやりたい事は実現できます。
ロギングがしたいならechoでログを出すか、ログファイルも更新してpushすればGithubActionsを探しに行かなくてよくなります。

が、ここではGithubActionsの流儀に則って制御を考えます。
また、runで実行すると、途中でエラーになった時にどこで失敗したのか特定するのが難しくなるので、運用を考えるならなるべく切り分けたいからです。

やり方は、if: 条件をいれるだけです。
問題は、条件に何を書くかです。

条件分岐で使えるもの

色々なものが使えますが、ここでやりたいのは「前回実行したステップの結果を受け取りたい」というものです。
たとえば、前回実行した結果が全て完了したとか、特定の処理をしたかどうか。
解決アプローチとして、3つのパターンがあります。

  1. そもそもstepをまとめてしまう
  2. 前stepの結果を判定するロジックをrunで書く
  3. 【今回採用】stepを実行する前にif条件を入れる

大事な事なのでもう一度繰り返します。
うまく行かない場合は、今回採用する方法にこだわる必要はありません。
実務で採用する場合にまで、後でできる事を今こだわるとハマって進捗率を下げてしまう、なんて事も考えられます。
状況に合わせて活用してください。

ソース例と解説

今回の制御で見る公式ドキュメントの位置

Thanks:

if: steps.(ステップのid).outcome == "success"が最もわかりやすいです。
以下のような使い方ができます。

成功.yml
- name: 確実に成功する処理
  id: test1
  continue-on-error: true  # 処理が失敗しても継続させる
  run: echo "成功"

- name: 実行される事を確認
  if: steps.test1.outcome == "success"
  run: echo "処理される"
失敗.yml
- name: 確実に失敗する処理
  id: test2
  continue-on-error: true  # 処理が失敗しても継続させる
  run: exit 1

- name: 実行される事を確認
  if: steps.test2.outcome == "success"
  run: echo "スキップ"
失敗した時でも処理したい.yml
- 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ではどうなるか気になるところです。

ソースコード

実践例.yml
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に入れる時に参考になりました。

ソースコード

応用例.yml
# 実行環境
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にはpython3python3.9か、どちらかが入っています。
重要なのは、実行するステップではpycに何が入っているか気にしなくても良い事です。
より厳密なチェックをするなら、which "${pyc}"のパスが有効である事を検証するのも良いかもしれません。

良い方法

環境構築系は自分で頑張るより、usesを探した方が楽です。
pythonのバージョンを指定する方法はあります。

良い方法.yml
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の勉強だけだと運用経験が積めず、なかなか学びが進まないので非常に時間がかかりましたが、ようやくここまで来れました。

本稿の内容を踏まえて、プログラマーを目指す方へ

ぶっちゃけ本題です。
冗長になりすぎたので、別記事にします。

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1