Nếu bạn cần kích hoạt một công việc từ CLI và chờ hoàn thành, bạn có thể sử dụng "Jenkins CLI" (xem tại đây ).
Tuy nhiên jenkins CLI không hỗ trợ các chương trình khuyến mãi nên đối với họ tôi đã đưa ra kịch bản sau:
#!/bin/bash
# Trigger a promotion and wait for its completion
#
# For triggering jobs jenkins cli is sufficient: https://support.cloudbees.com/hc/en-us/articles/228392127-How-to-wait-for-build-to-finish-when-triggering-from-CLI-
#
# The script is dependent on the current jenkins implementation of:
# - the promotion web page (links for triggering/re-executing the promotions)
# - the behaviour of the XML of the promotion status
#
# The behaviour of the job run status XML is:
# - if the the promotion is not yet been triggered than the response is 404 not found
# - is the the promotion has been triggered
# - ... but it's still waiting for an executor: the response is 404 not found or <duration> is empty
# - ... and has started: <duration> is empty or 0
# - ... and it's finished: <duration> is a non-zero number
#
#
# run syntax:
# ./trigger_promotion_and_wait_for_completion.sh \
# <job_name> \
# <job_run_number_to_promote> \
# <promotion_name> \
# <jenkins_user> \
# <jenkins_pwd> \
# <jenkins_url> \
# <script_workspace_folder> \
# '{"name": "prom_param_1", "value": "stringvalue" } , {"name": "prom_param_2", "value": true }'
#
# example:
# ./trigger_promotion_and_wait_for_completion.sh \
# job1 \
# 22 \
# promotion1 \
# admin \
# password \
# http://localhost:8080/jenkins/ \
# . \
# '{"name": "prom_param_1", "value": "stringvalue" } , {"name": "prom_param_2", "value": true }'
set -uexo pipefail
#other debug options:
#PS4='+\t '
#set -v
JOB_NAME="${1}"
JOB_RUN_NUMBER="${2}"
DEPLOY_PROMOTION_NAME="${3}"
BUILDER_USER="${4}"
BUILDER_PASSWORD="${5}"
JENKINS_URL="${6}"
WORKSPACE_FOLDER="${7}"
PROMOTION_ARGUMENTS="${8}"
TIMEOUT=900
echo "retrieving the promotion nextBuildNumber (so we can poll the promotion status and check if it's finished)..."
PROMOTION_RUN_NUMBER="$( curl -s -u${BUILDER_USER}:${BUILDER_PASSWORD} "${JENKINS_URL}job/${JOB_NAME}/promotion/process/${DEPLOY_PROMOTION_NAME}/api/xml" | grep -P '<nextBuildNumber>(.*)</nextBuildNumber' | sed -re 's/.*<nextBuildNumber>(.*)<\/nextBuildNumber.*/\1/g' )"
echo "running the promotion..."
echo 'only the first promotion can be triggered with "Approve", while subsequent promotions are triggered with "Re-execute promotion"'
echo 'so we check in the web page if the approve link is present'
#the link to search in the web page
PROMOTION_APPROVE_STRING="promotionProcess/${DEPLOY_PROMOTION_NAME}/promotionCondition/hudson.plugins.promoted_builds.conditions.ManualCondition/approve"
PROM_STATUS_URL="${JENKINS_URL}job/${JOB_NAME}/${JOB_RUN_NUMBER}/promotion/"
if curl -s -vvv -u${BUILDER_USER}:${BUILDER_PASSWORD} "${PROM_STATUS_URL}" | grep "${PROMOTION_APPROVE_STRING}" ; then
echo "The job has not yet been promoted, triggering it with 'Approve'"
WEB_PATH="job/${JOB_NAME}/${JOB_RUN_NUMBER}/promotion/promotionProcess/${DEPLOY_PROMOTION_NAME}/promotionCondition/hudson.plugins.promoted_builds.conditions.ManualCondition/approve"
SUBMIT="Approve"
else
echo "The job has already been promoted, triggering it with 'Re-execute promotion'"
WEB_PATH="job/${JOB_NAME}/${JOB_RUN_NUMBER}/promotion/${DEPLOY_PROMOTION_NAME}/build"
SUBMIT="Re-execute+promotion"
fi
#note for the troubleshooting: in case the following curl fails then the error cause can be found near the string "stack trace"
CURL_OUTPUT="$( curl -s -vvv -XPOST -u${BUILDER_USER}:${BUILDER_PASSWORD} "${JENKINS_URL}${WEB_PATH}" \
--data 'json={
"parameter": [
'"${PROMOTION_ARGUMENTS}"'
]
}&Submit='"${SUBMIT}" 2>&1 )"
if ( echo "${CURL_OUTPUT}" | grep -P "< HTTP/1.1 5\d\d" ) || ( echo "${CURL_OUTPUT}" | grep -P "< HTTP/1.1 4\d\d" ) ; then
echo 'error in triggering the job/promotion! exiting...'
exit 1
else
echo 'curl good'
fi
echo "checking promotion status until promotion is finished"
FINISHED=no
INITIAL_TIME="$(date +%s)"
while [ "${FINISHED}" != "ok" ]
do
sleep 2
#checking if promotion is finished (we check the value of <duration> XML element in the job run status)
ERROR="" ; DURATION="$(curl -s -u${BUILDER_USER}:${BUILDER_PASSWORD} "${JENKINS_URL}job/${JOB_NAME}/${JOB_RUN_NUMBER}/promotion/${DEPLOY_PROMOTION_NAME}/promotionBuild/${PROMOTION_RUN_NUMBER}/api/xml" | grep -Po '<duration>.*</duration>' | sed -re 's/<duration>(.*)<\/duration>/\1/g' )" || ERROR="yes"
if [[ $ERROR == "yes" ]] ; then
echo " the promotion has been queued but not yet started, waiting for it to start..."
curl -s -u${BUILDER_USER}:${BUILDER_PASSWORD} "${JENKINS_URL}job/${JOB_NAME}/${JOB_RUN_NUMBER}/promotion/${DEPLOY_PROMOTION_NAME}/promotionBuild/${PROMOTION_RUN_NUMBER}/api/xml"
ERROR=""
continue
fi ; ERROR=""
#we interrupt the polling of the job/promotion status if the promotion
# - is terminated
# - is taking too long (there is some problem)
#(in the XML of the job run status the <duration> XML element value is initially empty, than it is 0, and eventually is the number of seconds of the run duration )
POLLING_TIME="$(date +%s)"
let "ELAPSED_TIME=POLLING_TIME-INITIAL_TIME"
echo "ELAPSED_TIME=${ELAPSED_TIME}"
if (( ${ELAPSED_TIME} \> $TIMEOUT )) ; then
echo "error: the promotion has taken too long... exiting"
exit 1
fi
if [[ "${DURATION}" != "" ]] ; then
re='^[0-9]+$'
if [[ $DURATION =~ $re ]] ; then
if (( "${DURATION}" \> "0" )) ; then
FINISHED=ok
else
: #do nothing (the value of <duration> is 0 , that is the job/promotion has been started in a slave and is still running)
fi
else
echo "error: the promotion duration is not a number. exiting..."
exit 1
fi
else
: # the job/promotion has not yet started
fi
echo "waiting for the promotion to finish..."
done
echo "Promotion finished"
echo "Promotion output:"
curl -s -u${BUILDER_USER}:${BUILDER_PASSWORD} "${JENKINS_URL}job/${JOB_NAME}/${JOB_RUN_NUMBER}/promotion/${DEPLOY_PROMOTION_NAME}/promotionBuild/${PROMOTION_RUN_NUMBER}/consoleText" > ${WORKSPACE_FOLDER}/promotionOutput
cat ${WORKSPACE_FOLDER}/promotionOutput
if [[ ! "$(tail -n1 ${WORKSPACE_FOLDER}/promotionOutput)" =~ "SUCCESS" ]] ; then
echo "Promotion did not successfully terminate"
exit 1
else
echo "Promotion successfully terminated"
fi