見出し画像

JenkinsAPIを用いたビルドの成否判定はresultだけでなくbuildingも見る

JenkinsAPIを用いてジョブのビルドを行い、ビルド状態を定期的にポーリングして終了待ちをする、という処理を組んだのですが、一点ハマったのでシェアします。

結論としては、JenkinsAPIでジョブの成功(失敗)判定をするときは、/<job path>/<build number>/api/json のレスポンスにおいてbuildingがfalseかつresultがSUCCESS(FAILED)などとする必要があります。以降はこの理由を説明します。

APIを用いたジョブのビルドの流れ

JenkinsのRemote Access APIを用いたジョブのビルドの流れは下図のようになります。

画像1

ビルド実行命令
APIを用いてビルドを行う場合、ビルド命令のためのAPIを呼びます。ビルド命令は即座に実行されるのではなく、キューに格納され、最大同時実行ビルド数の設定に応じてビルド待ち状態となります。ビルド命令のAPIのレスポンスからキューアイテムのIDを取得することができます。なお、ビルド実行時のパラメータはクエリパラメータとしてURLの中に埋め込みます。

ビルド待ち(キューイング)
キューに格納されたビルド命令は、順番が来ると自動でビルドされます。ビルドが実行されると、キューアイテムの情報を取得するAPIでビルド番号を取得することができます。

同時に実行できる最大ビルド数のパラメータ設定と環境の利用状況によっては必ずしもすぐにビルドされるわけではないので、ジョブ実行命令~ジョブ完了までを自動で行う場合、ビルド待ちのループを入れるのを忘れないようにします。

ビルド実行
ビルドが実行された後は、ビルドの情報を取得するAPIで完了を待ちます。このAPIを呼ぶと、下記のようなレスポンスが返ってきます。

レスポンス(json)
{
    ...(中略)...
    building: true
    id: 10
    queueId: 100
    result: "SUCCESS"
    timestamp: 1623488301
    url: "https://baseurl/job/<job path>/10"
    ...(中略)...
}

ぱっと見「result項目の値をチェックして終了判定すればいいのね」となるのですが、このresult項目に癖があり、注意が必要です。

ジョブ状態確認結果のresult項目の挙動

ジョブ状態確認API(/<job path>/<build number>/api/json)のレスポンス中のresult項目は、単一のジョブであれば単純にそのジョブの完了時に実行結果が入るのですが、他のジョブをビルドするジョブの場合は少し癖のある動きをします

例として、子ジョブ1、2をビルドして完了するジョブを考えます。

画像2

親ジョブをビルドした際、子ジョブ1がSUCCESS、子ジョブ2がFAILEDでビルド完了した場合、親ジョブのresultは下記の様に変化します。

画像4

重要なのは、子ジョブが完了するたびに、その結果に応じて親ジョブのresultが変更される点です。親ジョブのビルド開始時はビルド結果は空ですが、ジョブ1のビルドが完了した時点で、その結果が親ジョブに反映されます。(↑の例だと子ジョブ1のビルド結果がSUCCESSなので、親ジョブのビルド結果もSUCCESSとなる)そして、後続の子ジョブが完了するたびに、より悪い結果の場合上書きされていくようになっています。

そのため、result項目に値が入っているかどうか、という方法でビルドの完了判定をしようとすると、最初の子ジョブが終わった段階で終了したと判定してしまうため、うまく動きません

buildingがfalseかつresultがSUCCESSとする

そこで利用できるのが、(/<job path>/<build number>/api/json)のレスポンス中のbuildingという項目です。buildingは下図で示すように、子ジョブの状態に関係なく親ジョブのビルド中はずっとtrueとなり、親ジョブのビルドが完了するとfalseとなります。

画像4

そのため、JenkinsAPIでジョブの成功(失敗)判定をするときは、buildingがfalseかつresultがSUCCESS(FAILED)などとする必要があるということです。

なお、こちらは試せてはいませんが、親ジョブ側で子ジョブのビルド終了待ちをしない(非同期実行する)場合は、子ジョブの結果を待たずbuldingがfalseになってしまうと思うので、注意です。

いいなと思ったら応援しよう!