CodeBuildのbuildspec.ymlにまつわるexitいろいろ
概要
CodeBuildのexitの動きではまったので挙動をまとめる。
結論
私が達成したかったことは下記。
- あるコマンドを成功させた後、後続処理を行わないでSUCCEEDEDとしてCodeBuildを終了させたい
- 複数行にわたるシェルコマンドのどれかが失敗したら、そこでFAILEDとしてCodeBuildを終了させたい
前者は実現できず、後者はできた。
buildspec.ymlは以下のような構成になっているが、この記事では省略してcommands部分のみを記述している。
phases:
build:
commands:
# commands部分のみを記述
CodeBuildのexitいろいろ
まずは簡単な例から。
commands:
- echo first
- echo $? # -> 0
当たり前の挙動だが、これは最後まで実行されてSUCCEEDEDで終わる。
ではこうしたらどうなるか。
commands:
- exit 0 # CodeBuildは停止しない
- echo first # -> first
ふつうのシェルスクリプトならexit 0
の時点で処理は終了するが、CodeBuildの場合停止しないようだ。つまり、ある処理が成功したらもうCodeBuildを止めたい(SUCCEEDEDとして)としても、やめられないとまらない状態。exitしてるのだからとまって欲しいところ。
commands:
- ./success.sh && exit 0 # success.shが成功したら後続処理をしたくないが、続いてしまう。
- echo first
- echo second
- echo third
あるコマンドを成功させた後、後続処理を行わないでSUCCEEDEDとしてCodeBuildを終了させたい
この願いが叶わなかったところで、次は複数行のケースを試す。
まずはこちらの例(いきなり複数行じゃないが)。
commands:
- ./failure.sh # 失敗してCodeBuildは停止(後続処理は実行されない)
- echo $?
CodeBuildの場合、set -e
してなくても失敗を検知して終了してくれる。
commands:
- |
./failure.sh # 失敗してCodeBuildは停止(後続処理は実行されない)
- echo $?
複数行の書き方だろうと同じ結果。
ではこれはどうか。
commands:
- |
./failure.sh # 失敗させたにも関わらずCodeBuildは停止しない
echo $? # -> 1
- echo $? # -> 0
なぜか失敗した時点で終了してくれない。もしかしたら複数行の最後のコマンドが成功してるからかもしれない。
念のためこちらも試す。
commands:
- |
./failure.sh # 失敗するが、後続の処理は行われる
./failure.sh # 失敗してCodeBuildは停止(後続処理は実行されない)
- echo $?
やはり複数行の場合は途中で失敗してもCodeBuildは検知してくれないよう。あくまで複数行最後のコマンド次第だということ。
ではこれはどうなるか。
commands:
- |
exit 1 # 失敗してCodeBuildは停止(後続処理は実行されない)
echo first
- echo $?
exitを使うと途中で終了してくれるよう。
複数行にわたるシェルコマンドのどれかが失敗したら、そこでFAILEDとしてCodeBuildを終了させたい
私の願いはこれ。どうやったらできるか考えた結果。
commands:
- |
set -e
./failure.sh # 失敗してCodeBuildは停止(後続処理は実行されない)
echo $?
- echo $?
複数行の頭にset -e
を置くことで実現できた。
因みにset -e
をこんなふうに置くやり方もやってたが駄目だった。
commands:
- set -e
- |
./failure.sh # 失敗させたにも関わらずCodeBuildは停止しない
echo $? # -> 1
- echo $? # -> 0
Discussion