From e6881457b8089cfd2f388534ddba1029899e9d5a Mon Sep 17 00:00:00 2001 From: radupopa2010 Date: Tue, 1 Jun 2021 16:52:15 +0200 Subject: [PATCH] Make script usable from both pipeline and localhost (#3147) * Make script usable from both pipeline and localhost * use the new argument --simnet-version= * dummy, to trigger pipeline one more time * CI: optimize the script * No arg for help flag * CI: comment and unneded parameter Co-authored-by: Denis P --- polkadot/.gitlab-ci.yml | 7 +- polkadot/scripts/gitlab/trigger_pipeline.sh | 225 ++++++++++++++++---- 2 files changed, 190 insertions(+), 42 deletions(-) diff --git a/polkadot/.gitlab-ci.yml b/polkadot/.gitlab-ci.yml index 4fa4330377..079621cbdc 100644 --- a/polkadot/.gitlab-ci.yml +++ b/polkadot/.gitlab-ci.yml @@ -300,8 +300,7 @@ publish-adder-collator-image: after_script: - buildah logout "$IMAGE_NAME" # pass artifacts to the trigger-simnet job - - echo "COLLATOR_IMAGE=$IMAGE_NAME" > ./artifacts/collator.env - - echo "COLLATOR_IMAGE_TAG=$(cat ./artifacts/EXTRATAG)" >> ./artifacts/collator.env + - echo "COLLATOR_IMAGE_TAG=$(cat ./artifacts/EXTRATAG)" > ./artifacts/collator.env artifacts: reports: # this artifact is used in trigger-simnet job @@ -387,6 +386,6 @@ trigger-simnet: # simnet project ID DWNSTRM_ID: 332 script: - # API trigger for a simnet job - - ./scripts/gitlab/trigger_pipeline.sh + # API trigger for a simnet job, argument value is set in the project variables + - ./scripts/gitlab/trigger_pipeline.sh --simnet-version=${SIMNET_REF} allow_failure: true diff --git a/polkadot/scripts/gitlab/trigger_pipeline.sh b/polkadot/scripts/gitlab/trigger_pipeline.sh index de74cfc478..04e2954b98 100755 --- a/polkadot/scripts/gitlab/trigger_pipeline.sh +++ b/polkadot/scripts/gitlab/trigger_pipeline.sh @@ -1,31 +1,182 @@ #!/bin/bash -set -eu +set -eou pipefail -# API trigger another project's pipeline -echo "Triggering Simnet pipeline." +# This script is to trigger Simnet pipeline. +# See help article for more details. -curl --silent \ - -X POST \ - -F "token=${CI_JOB_TOKEN}" \ - -F "ref=v4" `# trigger the pinned version of simnet CI config` \ - -F "variables[TRGR_PROJECT]=${TRGR_PROJECT}" \ - -F "variables[TRGR_REF]=${TRGR_REF}" \ - -F "variables[IMAGE_NAME]=${IMAGE_NAME}" \ - -F "variables[IMAGE_TAG]=${IMAGE_TAG}" \ - -F "variables[COLLATOR_IMAGE_TAG]=${COLLATOR_IMAGE_TAG}" \ - "https://${CI_SERVER_HOST}/api/v4/projects/${DWNSTRM_ID}/trigger/pipeline" | \ - tee pipeline; +SCRIPT_NAME="$0" +SCRIPT_PATH=$(dirname "$0") # relative +SCRIPT_PATH=$(cd "${SCRIPT_PATH}" && pwd) # absolutized and normalized +SIMNET_VERSION="" -PIPELINE_ID=$(cat pipeline | jq ".id") -PIPELINE_URL=$(cat pipeline | jq ".web_url") -echo -echo "Simnet pipeline ${PIPELINE_URL} was successfully triggered." -echo "Now we're polling it to obtain the distinguished status." +function usage { + cat << EOF +This script is to trigger Simnet pipeline. +It's designed to be launched locally and from CI. +The required argumants for both cases are listed below. -# This is a workaround for a Gitlab bug, waits here until -# https://gitlab.com/gitlab-org/gitlab/-/issues/326137 gets fixed. -# The timeout is 360 curls with 8 sec interval, roughly an hour. +Usage: ${SCRIPT_NAME} OPTION + +OPTIONS + + -h, --help Print this help message. + + Mandatory in both cases: + + -s, --simnet-version Simnet version to trigger. + E.g.: v4 + + -u, --upstream-project Triggering project. + E.g.: polkadot + + -r, --upstream-ref The branch or tag name for which project is built. + E.g.: master + + -d, --downstream-id Downstream project's ID to trigger. + E.g.: 332 (simnet project id) + + -n, --image-name Name of image to test. + E.g.: docker.io/paritypr/synth-wave + + -i, --image-tag Tag of the image to test. + E.g.: master + + -c, --collator-image-tag Tag of collator image. Image name is hardcoded. + E.g.: master + + Required for local launch: + + -g, --ci-server-fqdn FQDN of your gitlab server. + E.g.: gitlab.parity.io + + -t, --trigger-token Gitlab trigger token. This must be defined in + project -> settings -> CI/CD -> Pipeline triggers + Defaults to CI_JOB_TOKEN + https://stackoverflow.com/questions/42746634/gitlab-trigger-api-returns-404 + + -a, --access-token Gitlab peronal access token or it defaults to + PIPELINE_TOKEN (gitlab variable) + https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html + +EXAMPLES + ${SCRIPT_NAME} -s v4 + ${SCRIPT_NAME} --simnet-version=v4 + + Local test example. You need to set the 2 vars before running: TR_TOKEN and PERS_TOKEN + ${SCRIPT_NAME} --simnet-version=v4 \\ + --upstream-project=polkadot \\ + --upstream-ref=master \\ + --image-name=docker.io/paritypr/synth-wave \\ + --image-tag=master \\ + --collator-image-tag=master \\ + --ci-server-fqdn=gitlab.parity.io \\ + --downstream-id=332 \\ + --trigger-token="\${TR_TOKEN}" \\ + --access-token="\${PERS_TOKEN}" +EOF +} + +function main { + # Main entry point for the script. + parse_args "$@" + check_args + trigger_pipeline + check_pipeline + poll_pipeline +} + +function parse_args { + # shellcheck disable=SC2214 + while getopts c:u:r:i:n:g:t:r:a:s:h-: OPT; do + # support long options: https://stackoverflow.com/a/28466267/519360 + if [ "${OPT}" = "-" ]; then # long option: reformulate OPT and OPTARG + OPT="${OPTARG%%=*}" # extract long option name + OPTARG="${OPTARG#$OPT}" # extract long option argument (may be empty) + OPTARG="${OPTARG#=}" # if long option argument, remove assigning `=` + fi + case "${OPT}" in + h | help ) usage ; exit 0 ;; + s | simnet-version ) needs_arg ; SIMNET_VERSION="${OPTARG}" ;; + u | upstream-project ) needs_arg ; TRGR_PROJECT="${OPTARG}" ;; + r | upstream-ref ) needs_arg ; TRGR_REF="${OPTARG}" ;; + n | image-name ) needs_arg ; IMAGE_NAME="${OPTARG}" ;; + i | image-tag ) needs_arg ; IMAGE_TAG="${OPTARG}" ;; + c | collator-image-tag ) needs_arg ; COLLATOR_IMAGE_TAG="${OPTARG}" ;; + g | ci-server-fqdn ) needs_arg ; CI_SERVER_HOST="${OPTARG}" ;; + d | downstream-id ) needs_arg ; DWNSTRM_ID="${OPTARG}" ;; + t | trigger-token ) needs_arg ; CI_JOB_TOKEN="${OPTARG}" ;; + a | access-token ) needs_arg ; PIPELINE_TOKEN="${OPTARG}" ;; + ??* ) log DIE "Illegal option --${OPT}" ;; # bad long option + ? ) exit 2 ;; # bad short option (error reported via getopts) + esac + done + shift $((OPTIND-1)) # remove parsed options and args from $@ list + +} + +function check_args { + if [[ -z "${SIMNET_VERSION}" ]] ; then + log DIE "Must specify value for mandatory argument -s,--simnet-version + +$(usage)" + fi +} + +function needs_arg { + if [ -z "${OPTARG}" ]; then + log DIE "No arg for --${OPT} option" + fi +} + +function trigger_pipeline { + # API trigger another project's pipeline. + log INFO "Triggering Simnet pipeline." + + curl --silent \ + -X POST \ + -F "token=${CI_JOB_TOKEN}" \ + -F "ref=${SIMNET_VERSION}" \ + -F "variables[TRGR_PROJECT]=${TRGR_PROJECT}" \ + -F "variables[TRGR_REF]=${TRGR_REF}" \ + -F "variables[IMAGE_NAME]=${IMAGE_NAME}" \ + -F "variables[IMAGE_TAG]=${IMAGE_TAG}" \ + -F "variables[COLLATOR_IMAGE_TAG]=${COLLATOR_IMAGE_TAG}" \ + "https://${CI_SERVER_HOST}/api/v4/projects/${DWNSTRM_ID}/trigger/pipeline" | \ + tee pipeline; +} + +function check_pipeline { + PIPELINE_ID=$(jq ".id" pipeline) + PIPELINE_URL=$(jq ".web_url" pipeline) + echo + log INFO "Simnet pipeline ${PIPELINE_URL} was successfully triggered." + log INFO "Now we're polling it to obtain the distinguished status." +} + +function poll_pipeline { + # This is a workaround for a Gitlab bug, waits here until + # https://gitlab.com/gitlab-org/gitlab/-/issues/326137 gets fixed. + # The timeout is 360 curls with 8 sec interval, roughly an hour. + log INFO "Waiting on ${PIPELINE_ID} status..." + +# shellcheck disable=SC2034 + for i in {1..360}; do + STATUS=$(get_status); + log INFO "Triggered pipeline status is ${STATUS}"; + if [[ ${STATUS} =~ ^(pending|running|created)$ ]]; then + echo; + elif [[ ${STATUS} =~ ^(failed|canceled|skipped|manual)$ ]]; then + log DIE "Something's broken in: ${PIPELINE_URL}"; + elif [[ ${STATUS} =~ ^(success)$ ]]; then + log INFO "Look how green it is: ${PIPELINE_URL}" + exit 0 + else + log DIE "Something else has happened in ${PIPELINE_URL}" + fi + sleep 8; + done +} function get_status() { curl --silent \ @@ -34,20 +185,18 @@ function get_status() { jq --raw-output ".status"; } -echo "Waiting on ${PIPELINE_ID} status..." +function log { + local lvl msg fmt + lvl=$1 msg=$2 + fmt='+%Y-%m-%d %H:%M:%S' + lg_date=$(date "${fmt}") + if [[ "${lvl}" = "DIE" ]] ; then + lvl="ERROR" + echo "${lg_date} - ${lvl} - ${msg}" + exit 1 + else + echo "${lg_date} - ${lvl} - ${msg}" + fi +} -for i in $(seq 1 360); do - STATUS=$(get_status); - echo "Triggered pipeline status is ${STATUS}"; - if [[ ${STATUS} =~ ^(pending|running|created)$ ]]; then - echo; - elif [[ ${STATUS} =~ ^(failed|canceled|skipped|manual)$ ]]; then - echo "Something's broken in: ${PIPELINE_URL}"; exit 1; - elif [[ ${STATUS} =~ ^(success)$ ]]; then - echo "Look how green it is: ${PIPELINE_URL}"; exit 0; - else - echo "Something else has happened in ${PIPELINE_URL}"; exit 1; - fi -sleep 8; -done -# dummy: delete me +main "$@"