かまたま日記3

プログラミングメイン、たまに日常

JenkinsでJobを起動して、終了まで待つシェルスクリプト

jqとcurlがインストールされている必要があります。Jenkinsのバージョンは 2.46.3 で認証を有効にしています。

#!/bin/bash
#
# Trigger a Jenkins build and wait for the build to finish.
#
set -eu

JENKINS_HOST="jenkins.kamatama41.com"
JENKINS_USER=kamatama41
JENKINS_TOKEN=xxxxxxxxxx
JENKINS_JOB="a-jenkins-job"
BODY=$(cat << EOS
{"parameter": [
  {"name":"FOO", "value":"BAR"}
]}
EOS
)

get_build_status() {
  local build_number=$1
  curl -sS --fail \
    --user ${JENKINS_USER}:${JENKINS_TOKEN} \
    https://${JENKINS_HOST}/job/${JENKINS_JOB}/${build_number}/api/json
}

echo "Start to build ${JENKINS_JOB} with ${BODY}"

last_build_id=$(get_build_status lastBuild | jq -r .id)
echo "Last build_id is #${last_build_id}"

# Trigger the Job
curl -sS --fail -X POST \
  --user ${JENKINS_USER}:${JENKINS_TOKEN} \
  --data-urlencode json="${BODY}" \
  https://${JENKINS_HOST}/job/${JENKINS_JOB}/build

# Wait for new build to start
build_id=$(get_build_status lastBuild | jq -r .id)
wait_seconds=3
while [ "${build_id}" == "${last_build_id}" ]; do
  echo "New build is not running yet, wait for ${wait_seconds} seconds..."
  sleep ${wait_seconds}
  build_id=$(get_build_status lastBuild | jq -r .id)
done

echo "A new build has been started."
echo "https://${JENKINS_HOST}/job/${JENKINS_JOB}/${build_id}/"

# Wait for the build to end
result=$(get_build_status ${build_id} | jq -r .result)
wait_seconds=30
while [ "${result}" == "null" ]; do
  echo "Build is not finished yet, wait for ${wait_seconds} seconds..."
  sleep ${wait_seconds}
  result=$(get_build_status ${build_id} | jq -r .result)
done

if [ "${result}" != "SUCCESS" ]; then
  echo "Not succeeded, result is ${result}."
  exit 1
else
  echo "Succeeded!"
fi

解説

  • /job/${JOB_NAME}/${BUILD_ID}/api/json でビルドのステータスをJSONで取得出来ます。 lastBuild をIDに指定すると、最後に実施された(or 実施中の)ビルド状態を取得できます
  • /job/${JOB_NAME}/build にPOSTすると、新しいビルドをトリガー出来ます、JSONでビルドパラメタを渡すことも可能です。 トリガーされたビルドは開始されるまで数秒のタイムラグがあるので、最初にlastBuildのidを取得しておき、ポーリングして番号が変わったらそれが今回起動されたビルドだと判断しています。*1
  • その後はビルドステータスをポーリングし、resultがnullで無くなったらビルド完了と判断します。

*1:並列にバンバンビルドが起動されている環境だとこのやり方は誤検知の可能性があります。厳密にチェックする方法も無くはないのですが、面倒なので今回のケースではこういう方法を選びました。