GitHub Actionsの複数Jobが全て成功ならslack通知する実装について記載します。
今までは下記の実装で動作させていたのですが、workflow-conclusion-action@v3
がNode 16で作成されており、既にサポート切れであるためNode 20に移行したい。でもv4
はリリースされていないので自前でなんとかするしかない・・・ということで擬似workflow-conclusion-action@v3
を作成してみました。
GitHub アクション: ノード 16 からノード 20 への移行
jobs:
preparation:
runs-on: ubuntu-latest
steps:
- run:・・・# 記載省略
build_api:
runs-on: ubuntu-latest
needs:
- preparation
needs: build
steps:
- run: ・・・# 記載省略
deploy_api:
runs-on: ubuntu-latest
needs:
- preparation
- build_api
steps:
- run: ・・・# 記載省略
slack_notification:
if: always()
needs:
- preparation
- build_api
- deploy_api
runs-on: ubuntu-latest
defaults:
run:
shell: bash
steps:
- name: Check build and deploy conclusion
uses: technote-space/workflow-conclusion-action@v3 # 今回改修する箇所
- name: Notify slack success
if: env.WORKFLOW_CONCLUSION == 'success'
uses: rtCamp/action-slack-notify@v2
env:
SLACK_TITLE: Success to build and deploy
SLACK_MESSAGE: "ビルド&デプロイに成功しました。"
SLACK_COLOR: '#5cb85c'
- name: Notify slack failure
if: env.WORKFLOW_CONCLUSION != 'success'
uses: rtCamp/action-slack-notify@v2
env:
SLACK_TITLE: Failure to build and deploy
SLACK_MESSAGE: "ビルド&デプロイに失敗しました。"
SLACK_COLOR: '#dc143c'
workflow-conclusion-action@v3書換え
workflow-conclusion-action@v3
の処理を削除してExecute Steps and Collect Results
とCheck if all results are success
の処理を追加しています。
workflow-conclusion-action@v3
の実行結果はenv.WORKFLOW_CONCLUSION
に出力されていたので、そちらもsteps.jobs_result_status.outputs.result
に書き換えています。
jobs:
preparation:
runs-on: ubuntu-latest
steps:
- run:・・・# 記載省略
build_api:
runs-on: ubuntu-latest
needs:
- preparation
needs: build
steps:
- run: ・・・# 記載省略
deploy_api:
runs-on: ubuntu-latest
needs:
- preparation
- build_api
steps:
- run: ・・・# 記載省略
slack_notification:
if: always()
needs:
- preparation
- build_api
- deploy_api
runs-on: ubuntu-latest
defaults:
run:
shell: bash
steps:
# --- 改修範囲 (始 ---
- name: Execute Steps and Collect Results
run: |
# needで指定したjobの実行結果を配列で取得する(取得結果例:"success\nsuccess\nsuccess\n")
RESULTS=$(echo '${{ toJSON(needs) }}' | jq 'to_entries | map(.value.result) | join("\n")')
RESULTS=`printf "${RESULTS}" | tr -d '"'` # 結果からダブルクウォートを消す
echo "${RESULTS}" > results.txt # 結果を改行した状態でファイルに書き出すf
- name: Check if all results are success
id: jobs_result_status
run: |
# 全ての結果が "success" であるかを確認
all_success="true"
while IFS= read -r result; do
if [[ "$result" != "success" ]]; then
all_success="false"
echo "job_result:${result}"
break
fi
echo "job_result:${result}"
done < results.txt
# 結果を出力
if [[ "$all_success" == "true" ]]; then
echo "All results are success!"
echo "result=ok" >> $GITHUB_OUTPUT
else
echo "Not all results are success."
echo "result=ng" >> $GITHUB_OUTPUT
fi
# --- 改修範囲 (終 ---
- name: Notify slack success
if: steps.jobs_result_status.outputs.result == 'ok' # 判定条件をjobs_result_statusから取得するよう修正
uses: rtCamp/action-slack-notify@v2
env:
SLACK_TITLE: Success to build and deploy
SLACK_MESSAGE: "ビルド&デプロイに成功しました。"
SLACK_COLOR: '#5cb85c'
- name: Notify slack failure
if: steps.jobs_result_status.outputs.result != 'ok' # 判定条件をjobs_result_statusから取得するよう修正
uses: rtCamp/action-slack-notify@v2
env:
SLACK_TITLE: Failure to build and deploy
SLACK_MESSAGE: "ビルド&デプロイに失敗しました。"
SLACK_COLOR: '#dc143c'
ポイントとしては、RESULTS=$(echo '${{ toJSON(needs) }}' | jq 'to_entries | map(.value.result) | join("\n")')
というふうに記載すると、needs
で指定したjobの実行結果が取得できるようになります。
今回でいうと、preparation
、build_api
、build_api
の実行結果が取得され、全て成功の場合は次のように出力されます。
"success\nsuccess\nsuccess\n"
build_api
のみ失敗した場合は次のようになります。
"success\nsuccess\nfailure\n"
あとはこれらの結果をもとにshellで結果を判定して全てのjobがsuccessならok、そうでないならngを出力し後続のslack通知処理で判定させています。