Bagaimana tidak "menembak dan melupakan" ketika melakukan pemicu jarak jauh dari bangunan Jenkins?

13

Saya mencoba untuk memicu Jenkins membangun parameter dari Bambu, melakukan hal berikut:

POST - http://jenkins-url.com/job/jobname/buildWithParameters?ENVIRONMENT=dev&APPLICATION=hello-world

Tapi saya akan mendapatkan 201 langsung yang memberitahu saya bahwa build itu dibuat. Bagaimana cara membuat permintaan ini menunggu dan mengembalikan status keberhasilan bangunan alih-alih api dan lupa?

Tampaknya dimungkinkan sesuai Parameter-Remote-Trigger-Plugin :

masukkan deskripsi gambar di sini

Sunting: buat ini pada akhirnya jika Anda membutuhkannya. https://github.com/owenmorgan/jenkins-remote-builder

osmorgan
sumber

Jawaban:

5

Saat menyiapkan pemicu jarak jauh, Anda harus mengklik "Blokir hingga proyek yang dipicu jarak jauh menyelesaikan pembangunannya."

Remote Parameterized Job

Travis Thompson
sumber
terima kasih, saya mungkin memiliki ujung tongkat yang salah .. yang plug in tampaknya untuk memicu membangun jarak jauh dari jenkins itu sendiri? Dalam skenario saya, build dipicu dari permintaan dari Bamboo, tapi kami ingin permintaan itu ditahan sampai build selesai dan mengembalikan status build.
osmorgan
Ah, saya mengerti sekarang. Sayangnya saya tidak berpikir API berfungsi seperti itu, jika Anda melihat bagaimana plugin untuk Jenkins dikembangkan, Anda akan melihatnya memicu pekerjaan jarak jauh dan kemudian jajak pendapat untuk status sampai selesai.
Travis Thompson
1
Terima kasih, saya akhirnya membuat github.com/owenmorgan/jenkins-remote-builder
osmorgan
1
@osmorgan: Anda harus menjelaskannya dalam jawaban (dengan sedikit ringkasan, bukan hanya tautannya) dan menerimanya.
Dan Cornilescu
sheesh .. nya di pertanyaan .. dan ada keterangan di link. sampai jumpa di stackoverflow.
osmorgan
5

Saya telah membuat skrip jenkins-remote-builder yang akan mengikuti build jarak jauh Anda hingga selesai.

Beberapa detail lebih lanjut tentang itu (dari README.md ):

Contoh

jenkins=https://user:[email protected]:8080
jenkins_job=MyApp-Deploy

environment=dev
application=myapp
revision=9fd71f63b351b8208264daf86d292ced580a2f60

./jenkins_remote_trigger.sh \
            -h ${jenkins} \
            -j ${jenkins_job} \
            -p "ENVIRONMENT=${environment}&APPLICATION=${application}&REVISION=${revision}"

Pemakaian:

-h HOST     | --host=HOST                       Jenkins host
-j JOBNAME  | --jobname=test-build-job          The name of the jenkins job to trigger
-p JOBPARAM | --jobparam=environment=uat&test=1 Jenkins job paramiters
-q          | --quiet                           Don't output any status messages
osmorgan
sumber
4
Sedikit ringkasan tentang cara kerjanya akan lebih baik;)
Tensibai
Harap tinjau hasil edit yang saya terapkan pada jawaban (menarik!) Anda, tetapi yang menurut saya beresiko terhapus (melalui moderasi) karena itu adalah jawaban tautan saja (seperti yang ditunjukkan oleh komentar dari @Tensibai juga ).
Pierre.Vriens
1

Jika Anda perlu memicu pekerjaan dari CLI dan menunggu penyelesaiannya Anda dapat menggunakan "Jenkins CLI" (lihat di sini ).

Namun jenkins CLI tidak mendukung promosi, jadi bagi mereka saya membuat skrip berikut:

#!/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
Giuliano
sumber