type t (* void *)

ソフトウエアのこととか

Github Actionsで分岐のある処理を書く

yamlで病める

前提

いま書いているプロダクトにはディレクトリが色々ある

Makefile
test_ab.sh
a/hoge
b/fuga
c/piyo

差分を見てテスト(test_a.sh)を実行するかどうか判断するCI機構を実現したい。
test_ab.shディレクトab がアップデートされたときだけ走らせれば十分で、そのために予めプロダクトのビルドを実行しておく必要がある。

ab ディレクトリがアップデートされたときだけworkflowが走れば十分ならば、on.push.paths 構文で実現できる。 が、プロダクトのビルド自体はアップデートされるファイルのディレクトリにかかわらず常に行いたい。 そのため on.push.paths では不十分。

docs.github.com

案1

一つのワークフローに2つのJobでなんとかする

  • build
  • conditional_test
name: ci

on:
  push:
    branches: [master]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - run: make
  conditional_test:
    runs-on: ubuntu-latest
    needs: [build]
    steps:
      - run: ./check_ab_dependencies.sh
        id: check
        continue_on_error: true
      - if: steps.check.outcome == 'success'
        run: ./test_ab.sh

欠点

  • テスト実行が複数のステップに分かれたりして複数stepが必要な場合に全てに if: steps.check.outcome == 'success' を書かないといけなくて辛い
  • CIのワークフローの画面からいまいちぱっと見で(中見ればわかるんですが)テストが発火したかどうかわかりづらい

案2

  • ワークフローのなかで3つのJobを用意し、conditional_test の依存jobとして check_condition を用意する。
  • check_condition 自身は continue-on-error とし、実際成功したかどうかは outputs として外に公開し job.if でチェックする
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - run: make
  check_condition:
    runs-on: ubuntu-latest
    outputs:
      real_success: ${{ steps.check.outcome }}
    steps:
      - uses: actions/checkout@v3
      - run ./check_ab_dependencies.sh
        continue-on-error: true
  conditional_test:
    runs-on: ubuntu-latest
    needs: [build, check_condition]
    if: needs.check_condition.outputs.real_success == 'success'
    steps:
      - uses: actions/checkout@v3
      - run: ./test_ab.sh