pipeline { agent { label 'jjb' } options { timestamps() ansiColor('xterm') } stages { stage('Prepare Metadata') { steps { script { wrap([$class: 'BuildUser']) { env.RUN_TRIGGER_USER = env.BUILD_USER_ID ?: env.BUILD_USER ?: 'system' env.RUN_TRIGGER_NAME = env.BUILD_USER ?: env.BUILD_USER_ID ?: 'system' } currentBuild.displayName = "#${env.BUILD_NUMBER} runner" currentBuild.description = "by=${env.RUN_TRIGGER_NAME}; qaRef=${params.QA_REPO_REF}; mobileRef=${params.MOBILE_REPO_REF}" } } } stage('Run Jobs In Parallel') { steps { script { def fanout = [:] fanout['selenium'] = { def run = build job: 'qa-selenium-tests', wait: true, propagate: false, parameters: [ string(name: 'QA_REPO_URL', value: params.QA_REPO_URL), string(name: 'QA_REPO_REF', value: params.QA_REPO_REF), string(name: 'BROWSER', value: params.BROWSER), string(name: 'BASE_URL', value: params.BASE_URL), string(name: 'EXECUTION_MODE', value: params.EXECUTION_MODE), string(name: 'SELENOID_URL', value: params.SELENOID_URL), string(name: 'HEADLESS', value: params.HEADLESS) ] writeFile file: 'downstream-selenium.txt', text: "${run.number}|${run.result}\n" } fanout['mobile'] = { def run = build job: 'qa-mobile-appium-tests', wait: true, propagate: false, parameters: [ string(name: 'MOBILE_REPO_URL', value: params.MOBILE_REPO_URL), string(name: 'MOBILE_REPO_REF', value: params.MOBILE_REPO_REF), string(name: 'MOBILE_MAX_EMULATORS', value: params.MOBILE_MAX_EMULATORS), string(name: 'JUNIT_PARALLELISM', value: params.JUNIT_PARALLELISM), string(name: 'APP_URL', value: params.APP_URL), string(name: 'DB_URL', value: params.DB_URL), string(name: 'DB_USER', value: params.DB_USER), string(name: 'DB_PASSWORD', value: params.DB_PASSWORD), string(name: 'WISHLISTS_USERNAME', value: params.WISHLISTS_USERNAME), string(name: 'WISHLISTS_PASSWORD', value: params.WISHLISTS_PASSWORD), string(name: 'GIFTS_USERNAME', value: params.GIFTS_USERNAME), string(name: 'GIFTS_PASSWORD', value: params.GIFTS_PASSWORD), string(name: 'RESERVATION_USERNAME', value: params.RESERVATION_USERNAME), string(name: 'RESERVATION_PASSWORD', value: params.RESERVATION_PASSWORD), string(name: 'RESERVATION_OWNER', value: params.RESERVATION_OWNER) ] writeFile file: 'downstream-mobile.txt', text: "${run.number}|${run.result}\n" } fanout['api'] = { def run = build job: 'qa-api-citrus-tests', wait: true, propagate: false, parameters: [ string(name: 'QA_REPO_URL', value: params.QA_REPO_URL), string(name: 'QA_REPO_REF', value: params.QA_REPO_REF) ] writeFile file: 'downstream-api.txt', text: "${run.number}|${run.result}\n" } parallel fanout def parseRun = { String fileName -> if (!fileExists(fileName)) { return [number: 'n/a', result: 'NOT_BUILT'] } def parts = readFile(fileName).trim().tokenize('|') return [ number: parts ? parts[0] : 'n/a', result: parts.size() > 1 ? parts[1] : 'UNKNOWN' ] } def seleniumRun = parseRun('downstream-selenium.txt') def mobileRun = parseRun('downstream-mobile.txt') def apiRun = parseRun('downstream-api.txt') def lines = [] lines << "job=${env.JOB_NAME}" lines << "build=${env.BUILD_NUMBER}" lines << "trigger_user=${env.RUN_TRIGGER_USER}" lines << "trigger_name=${env.RUN_TRIGGER_NAME}" lines << "qa_repo_url=${params.QA_REPO_URL}" lines << "qa_repo_ref=${params.QA_REPO_REF}" lines << "mobile_repo_url=${params.MOBILE_REPO_URL}" lines << "mobile_repo_ref=${params.MOBILE_REPO_REF}" lines << "selenium_build=${seleniumRun.number}" lines << "selenium_result=${seleniumRun.result}" lines << "mobile_build=${mobileRun.number}" lines << "mobile_result=${mobileRun.result}" lines << "api_build=${apiRun.number}" lines << "api_result=${apiRun.result}" lines << "selenium_link=/job/qa-selenium-tests/${seleniumRun.number}/" lines << "mobile_link=/job/qa-mobile-appium-tests/${mobileRun.number}/" lines << "api_link=/job/qa-api-citrus-tests/${apiRun.number}/" lines << "selenium_link_abs=${env.JENKINS_URL}job/qa-selenium-tests/${seleniumRun.number}/" lines << "mobile_link_abs=${env.JENKINS_URL}job/qa-mobile-appium-tests/${mobileRun.number}/" lines << "api_link_abs=${env.JENKINS_URL}job/qa-api-citrus-tests/${apiRun.number}/" writeFile file: 'runner-summary.txt', text: lines.join('\n') + '\n' archiveArtifacts allowEmptyArchive: false, artifacts: 'runner-summary.txt' def failed = [seleniumRun, mobileRun, apiRun].any { it.result != 'SUCCESS' } if (failed) { error("One or more downstream QA jobs failed. See runner-summary.txt for build links and statuses.") } } } } } }