#!groovy // authors: [email protected], [email protected], [email protected] import groovy.json.JsonBuilder import groovy.json.JsonOutput import groovy.json.JsonSlurper import groovy.json.JsonSlurperClassic def call(Map params) { pipeline { options { // add timestamp to all log entries timestamps() } environment { PEGA_HOME = "/home/jenkins/workspace/${JOB_BASE_NAME}/prpcServiceUtils722" ANT_HOME = '/usr/share/ant' SystemName = 'temp_system' PRPC_UTILS_DIR = "prpcServiceUtils722/scripts/utils" PRPC_LOGS_DIR = "${PRPC_UTILS_DIR}/logs" antBuildFile = "${WORKSPACE}/${PRPC_UTILS_DIR}/Jenkins-build.xml" antPropertiesFile_template = "./param_overrides_prpc/${Pega_Environment}_code_import.properties.tpl" antPropertiesFile = "./param_overrides_prpc/${Pega_Environment}_code_import.properties" NEXUS_SEARCH_URL = "${NEXUS_URL}/service/rest/v1/search/assets?repository=raw-hosted&group=/${params.NEXUS_REPO}/ongoing-deployments/${artifacts_folder}/pega-jars" NEXUS_LOGS_URL = "${NEXUS_URL}/repository/raw-hosted/${params.NEXUS_REPO}/deployment-logs/${Pega_Environment}" NEXUS_POST_DEPLOYMENT_ARCHIVE_URL = "${NEXUS_URL}/repository/raw-hosted/${params.NEXUS_REPO}/ongoing-deployments/${Pega_Environment}_archive/pega-jars" SMO_EMAIL = "[email protected]" temp_enforce_single_master_archive = "${params.enforce_single_master_archive}" NEXUS_EXTRA_URL = "${NEXUS_URL}/service/rest/v1/search/assets?repository=raw-hosted&group=/${params.NEXUS_REPO}/ongoing-deployments/${artifacts_folder}/extra" // CHANGE_DESCRIPTION = "{'description':'${params.static_description} ${params.variable_description}'}" testing_claims_sanity = "testing_claims_sanity" MANIFEST_DIR = "deployment-manifests" MANIFEST_FILE_NAME = "mainfest.json" NEXUS_MANIFEST_URL = "${NEXUS_URL}/repository/raw-hosted/${params.NEXUS_REPO}/${MANIFEST_DIR}/${Pega_Environment}" } agent { label 'ant' } stages { stage('Print input params') { steps { script { wrap([$class: 'MaskPasswordsBuildWrapper', varPasswordPairs: [[password: "${TargetPassword}", var: 'TargetPassword']]]) { printParams(params) } } } } stage('Set builders email') { steps { script { wrap([$class: 'BuildUser']) { env.SUBMITTER_EMAIL = "${BUILD_USER_EMAIL}" } } } } stage('Check mandatory params') { steps { script { if (params.artifacts_folder == '--select--') { echo 'No source selected. Cancelling build' error('No source selected') } else { echo "artifacts folder is: ${artifacts_folder} " } } } } stage('Print environment variables') { steps { script { wrap([$class: 'MaskPasswordsBuildWrapper', varPasswordPairs: [[password: "${TargetPassword}", var: 'TargetPassword']]]) { printEnv() } } } } stage('Create ServiceNow Change ') { when { expression { params.create_SN_change_request == 'true' } } steps { script { create = createServiceNowTicketWithCurl(instanceId: "${params.instanceId}", templateId: "${params.templateId}", credentialsId: "${params.credentialsId}", jsonDataString: "${params.jsonDataString}" ) println create def now = new Date() println now.format('yyyy-MM-dd HH:mm:ss') def date_start = now.format('yyyy-MM-dd HH:mm:ss') echo "${date_start}" def work_start = "{'work_start':'${date_start}'}" workStart = updateServiceNowTicketWithCurl(sys_id: "${sys_id}", instanceId: "${params.instanceId}", credentialsId: "${params.credentialsId}", updateJsonDataObject: "${work_start}" ) } } } stage('Attach Sign Off mail to SN Change'){ when { expression { params.create_SN_change_request == 'true' } } steps { script{ echo "Attach Sign Off files to serviceNow" def serviceNowPostCommandResult = attachZipToServiceNowTicketWithCurlLoop(instanceId: "${params.instanceId}", credentialsId: "${params.credentialsId}", sys_id: "${sys_id}") echo "result of curl command: ${serviceNowPostCommandResult}" } } } stage('retrieve deployment artifacts from nexus and store in temp dir in workspace') { steps { sh """ # turn off echo set +x echo 'removing temporary directories' rm -rf nexus_temp_master rm -rf nexus_temp rm -rf \$PRPC_LOGS_DIR echo 're-creating temporary directories' mkdir nexus_temp_master mkdir nexus_temp echo 'curl files from nexus to Jenkins workspace, in temp dir: nexus_temp_master' cd nexus_temp_master for f in \$(curl -s \$NEXUS_SEARCH_URL | jq -r .items[].downloadUrl) do curl -s -O -u \$NEXUS_USER:\$NEXUS_PASSWORD \$f done ls -lisa cd .. """ } } stage('Build ANT and set properties file') { steps { script { // interpret ImportMethod if ("${ImportMethod}" == 'sync') { env.ImportAsynctruefalse = 'false' } else { env.ImportAsynctruefalse = 'true' } // interpret ImportMode if ("${ImportModeDesc}" == 'import- import everything in package') { env.ImportMode = 'import' } else if ("${ImportModeDesc}" == 'install- import only new ruleset versions') { env.ImportMode = 'install' } else if ("${ImportModeDesc}" == 'hotfix- import everything in package with newer timestamp') { env.ImportMode = 'hotfix' } // interpret Import_from_master_zip_file if ("${Import_from_master_zip_file}" == 'yes- archives are zipped in a master zip file') { env.ImportFromMasterZipFile = 'true' } else { env.ImportFromMasterZipFile = 'false' } // following logic is for prepararing properties file. we first prepare a template file, and then write its content to // the actual file that will be used to build the final temp prpcServiceUtils.properties file. // read the template content from the file into a string. we will replace it with actual parameter values def String myText = readFile("${antPropertiesFile_template}") // prepare a new string consisting of the parameter values. This is what users supply to the pipeline in ui before running it. we are using build with parameter plugin. def myBinding = ['TargetPassword':"${TargetPassword}", 'ImportMode':"${ImportMode}", 'ImportExistingInstances':"${ImportExistingInstances}", 'ImportAsynctruefalse':"${ImportAsynctruefalse}"] wrap([$class: 'MaskPasswordsBuildWrapper', varPasswordPairs: [[password: "${TargetPassword}", var: 'TargetPassword']]]) { println myBinding // insert values into the template def configString = replaceVarsInString(text:myText, binding:myBinding) println configString // overwrite the file with the content of templatefile writeFile file: "${antPropertiesFile}", text: "${configString}", encoding: 'UTF-8' // read and display file def String myTextNew = readFile("${antPropertiesFile}") sh 'echo after file read' println myTextNew } wrap([$class: 'MaskPasswordsBuildWrapper', varPasswordPairs: [[password: "${TargetPassword}", var: 'TargetPassword']]]) { sh 'pwd' sh '$ANT_HOME/bin/ant -d -buildfile ${antBuildFile} -propertyfile ${antPropertiesFile} importprops' def props = readProperties file:"${antPropertiesFile}" def TargetHost= props['TargetHost'] echo "TargetHost=${TargetHost}" } } } } stage('Unzip master archive file') { when { // execute this stage only when ImportFromMasterZipFile is true expression { env.ImportFromMasterZipFile == 'true' } } steps { sh """ # If single source is enfored, ensure only one master zip file was provided. Throw error and exit otherwise cd nexus_temp_master ZipCount=\$(ls | wc -l) echo "ZipCount is: \${ZipCount}" echo "temp_enforce_single_master_archive is: ${env.temp_enforce_single_master_archive}" if [ "\${ZipCount}" -gt 1 ] && [ "\${temp_enforce_single_master_archive}" = "true" ] then echo "More than one master zip provided. This environment is configured to receive only a single master zip. Cancelling build" cd .. exit 100 else echo 'All good. Proceeding to unzipping...' fi # loop through the files, unzip them one by one and remove source files echo "following files were downloaded from Nexus" ls cd .. """ } } stage('Deploy Pega files') { steps { script { def now = new Date() println now.format('yyyyMMdd_HH-mm-ss') def LC_DAYANDTIME = now.format('yyyyMMdd_HH-mm-ss') // env.LOG_FILE_NAME="Logs_${LC_DAYANDTIME}.zip" env.LOG_FILE_NAME = "IMPORT_BUILD_ID_${env.BUILD_NUMBER}_Logs_${LC_DAYANDTIME}.zip" env.ARCHIVE_FILE_NAME = "IMPORT_BUILD_ID_${env.BUILD_NUMBER}_ARCHIVE_${LC_DAYANDTIME}.zip" sh """ echo 'inside deploy pega files' cd nexus_temp_master ls chmod -R 755 $PEGA_HOME # logic to sort the files and deploy them one after another. Reverse order can be enforced as: for f in `ls * |sort -nr` for f in `ls * | sort -V` do if [ \${f: -4} = ".zip" ] then echo "Unzipping file: \$f" unzip \$f -d ../nexus_temp elif [ \${f: -4} = ".jar" ] then echo "copying jar: \$f" cp \$f ../nexus_temp else echo "invalid file provided: \$f" exit 100 fi ls ../nexus_temp { $PEGA_HOME/scripts/utils/prpcServiceUtils.sh import --connPropFile ${PEGA_HOME}/scripts/utils/temp_system_import.properties && echo '================= \t \t \t \t \t text 1' } || { echo 'ERROR IN DEPLOYMENT. UPLOAD LOGS TO NEXUS AND EXIT \n========================= \n========================= \nCould not Deploy: \n' | ls --format=commas echo "upload execution logs to Nexus. Zip it into a single folder" cd .. cd \$PRPC_LOGS_DIR echo "log file name is: \${LOG_FILE_NAME}" zip -r \$LOG_FILE_NAME * # Nexus user and password come from the slave ENV variables curl -v -u \$NEXUS_USER:\$NEXUS_PASSWORD --upload-file \$LOG_FILE_NAME "\$NEXUS_LOGS_URL/\$LOG_FILE_NAME" cd ../../.. exit 1 } ls ../nexus_temp # echo "removing source file: \$f" rm -rf ../nexus_temp mkdir ../nexus_temp ls ../nexus_temp done cd .. echo "upload execution logs to Nexus. Zip it into a single folder" cd \$PRPC_LOGS_DIR echo "log file name is: \${LOG_FILE_NAME}" zip -r \$LOG_FILE_NAME * # Nexus user and password come from the slave ENV variables curl -v -u \$NEXUS_USER:\$NEXUS_PASSWORD --upload-file \$LOG_FILE_NAME "\$NEXUS_LOGS_URL/\$LOG_FILE_NAME" cd ../../.. """ // Close SN Change Release env.stage_status = "succeeded" echo "${stage_status}" if ( "${params.create_SN_change_request}" == "true" && "${stage_status}" == "failed" ) { println "Will try to attach the log files to SN Change Request" def serviceNowPostCommandResult = attachZipToServiceNowTicketWithCurl(instanceId: "${params.instanceId}", credentialsId: "${params.credentialsId}", sys_id: "${sys_id}", PRPC_LOGS_DIR: "$PRPC_LOGS_DIR", LogFileName: "$LOG_FILE_NAME") echo "result of curl command: ${serviceNowPostCommandResult}" closeCodeFailed = updateServiceNowTicketWithCurl(sys_id: "${sys_id}", instanceId: "${params.instanceId}", credentialsId: "${params.credentialsId}", updateJsonDataObject: "${params.closeFailedJsonDataObject}" ) println closeCodeFailed //def now = new Date() //println now.format('yyyy-MM-dd HH:mm:ss') def date_end = now.format('yyyy-MM-dd HH:mm:ss') echo "${date_end}" def work_end = "{'work_end':'${date_end}'}" workEnd = updateServiceNowTicketWithCurl(sys_id: "${sys_id}", instanceId: "${params.instanceId}", credentialsId: "${params.credentialsId}", updateJsonDataObject: "${work_end}" ) println "Will try to close-failed the Change Request" close = updateServiceNowTicketWithCurl(sys_id: "${sys_id}", instanceId: "${params.instanceId}", credentialsId: "${params.credentialsId}", updateJsonDataObject: "${params.closeJsonDataObject}" ) println close } else if ( "${params.create_SN_change_request}" == "true" && "${stage_status}" == "succeeded") { closeCodeCompleted = updateServiceNowTicketWithCurl(sys_id: "${sys_id}", instanceId: "${params.instanceId}", credentialsId: "${params.credentialsId}", updateJsonDataObject: "${params.closeCompletedJsonDataObject}" ) println closeCodeCompleted println "Will try to attach the log files to SN Change Request" def serviceNowPostCommandResult = attachZipToServiceNowTicketWithCurl(instanceId: "${params.instanceId}", credentialsId: "${params.credentialsId}", sys_id: "${sys_id}", PRPC_LOGS_DIR: "$PRPC_LOGS_DIR", LogFileName: "$LOG_FILE_NAME") echo "result of curl command: ${serviceNowPostCommandResult}" def date_end = now.format('yyyy-MM-dd HH:mm:ss') echo "${date_end}" def work_end = "{'work_end':'${date_end}'}" workEnd = updateServiceNowTicketWithCurl(sys_id: "${sys_id}", instanceId: "${params.instanceId}", credentialsId: "${params.credentialsId}", updateJsonDataObject: "${work_end}" ) println "Will try to close the Change Request" close = updateServiceNowTicketWithCurl(sys_id: "${sys_id}", instanceId: "${params.instanceId}", credentialsId: "${params.credentialsId}", updateJsonDataObject: "${params.closeJsonDataObject}" ) println close } } } stage('Retrieve Exising Manifest file') { steps { script { code = sh(returnStdout: true, script: "curl -L -s -O -u ${NEXUS_USER}:${NEXUS_PASSWORD} ${NEXUS_MANIFEST_URL}/${MANIFEST_FILE_NAME} -w \"%{http_code}\"") println "code is ${code}" if (code.equals("200")) { env.fileFound = true env.oldJson = readJSON file: "${MANIFEST_FILE_NAME}" // println "old json class is " + env.oldJson.getClass() println "Existing json formatted text\n" + JsonOutput.prettyPrint("${env.oldJson}") } else { env.fileFound = false } println "File found is ${env.fileFound}" } } } stage('Create New Manifest File') { steps { script { // assign the output of the script to artArr // retrive the components deployed def artList = [] def dir = new File('./nexus_temp') dir.eachFile() { file -> artList.add(file.getName()) } println "Files to be stored ${artList}" buildDate = new Date("${currentBuild.startTimeInMillis}".toLong()).format("yyyy-MM-dd'T'HH:mm:ss") jsonString = "[{'release':{'version': '1.0', 'notes': '${ReleaseNotes}', 'jobName': '${env.JOB_BASE_NAME}', 'buildId':'${env.BUILD_ID}', 'buildTimestamp': '${buildDate}', 'deployer': '${env.SUBMITTER_EMAIL}', 'artifactsDeployed': '${artList}'}}]" env.newJson = readJSON text: "${jsonString}" // println "new json class is " + env.newJson.getClass() println "New json formatted text\n" + JsonOutput.prettyPrint("${env.newJson}") } } } stage('Write Manifest File to Workspace') { steps { script { println "Found value = ${env.fileFound}" if ("${env.fileFound}".toString().equals("true")) { println "Going into file found code" // user JsonSlurperClassic because it is serializable, def slurper = new JsonSlurperClassic() def oldOne = slurper.parseText("${env.oldJson}") def newOne = slurper.parseText("${env.newJson}") def combined = oldOne+newOne env.final = new JsonBuilder(combined).toString() } else { env.final = "${env.newJson}" } println "Final json formatted text\n" + JsonOutput.prettyPrint("${env.final}") // write out the json string to a file using Jenkins method //writeFile file: "${MANIFEST_FILE_NAME}", text: "${env.final}", encoding: 'UTF-8' writeFile file: "${MANIFEST_FILE_NAME}", text: JsonOutput.prettyPrint("${env.final}"), encoding: 'UTF-8' } } } stage('Store file in Nexus') { steps { script { sh "curl -v -s -S -u $NEXUS_USER:$NEXUS_PASSWORD --upload-file $MANIFEST_FILE_NAME $NEXUS_MANIFEST_URL/$MANIFEST_FILE_NAME" } } } } stage("Verify Code Import") { steps { script { // if ( "${params.create_SN_change_request}" == "true" ) { // def serviceNowPostCommandResult = attachZipToServiceNowTicketWithCurl(instanceId: "${params.instanceId}", credentialsId: "${params.credentialsId}", sys_id: "${sys_id}", PRPC_LOGS_DIR: "$PRPC_LOGS_DIR", LogFileName: "$LOG_FILE_NAME") // echo "result of curl command: ${serviceNowPostCommandResult}" // } echo 'Code import verification requested. Click the below link to confirm if code import sanity was checked?' if (params.artifacts_folder == 'general') { def userInput = input(id: 'Proceed1', message: 'Import Verified?', parameters: [[$class: 'BooleanParameterDefinition', defaultValue: true, description: '', name: 'Select to confirm if all code was imported. Clicking Proceed will continue the build, while Abort will end it.']]) echo "Archiving stages will be skipped since source folder is general. User must self-archive the source files." if(userInput == true) { // do action } else { echo "User reported import sanity check failure. Initiating action Abort." error('Build aborted by user') } } else { def userInput = input(id: 'Proceed1', message: 'Archive files?', parameters: [[$class: 'BooleanParameterDefinition', defaultValue: true, description: '', name: 'Select to confirm if all code was imported. Clicking Proceed will archive the source files.']]) if(userInput == true) { // do action } else { echo "User reported import sanity check failure. Initiating action Abort." error('Build aborted by user') if (params.create_SN_change_request == 'true') { println "Will try to close-failed the Change Request" close = updateServiceNowTicketWithCurl(sys_id: "${sys_id}", updateSnowURL: "${params.updateSnowURL}", credentialsId: "${params.credentialsId}", updateJsonDataObject: "${params.updateJsonDataObject}" ) println close } } } } } } stage("Run Sanity checks") { when { expression { params.run_sanity_checks == 'true' } } steps { script { def props = readProperties file:"${antPropertiesFile_template}" def TargetHost = props['TargetHost'] echo "Target host is ${TargetHost}" build_info = build job: testing_claims_sanity, propagate: false, parameters: [string(name: 'projectKey', value: 'CLM'), string(name: 'mavenProject', value: 'claims'), string(name: 'jiraServer', value: 'd1000bf8-74bc-4611-827b-62242b81e6af'), string(name: 'TEST_TYPE', value: 'sanity'), string(name: 'TEST_URL', value: "${TargetHost}")] } } } stage('Copy files to Nexus Archives?') { when { // skip this stage if source folder was general expression { params.artifacts_folder != 'general' } } steps { sh """ echo "Upload jars to nexus archives" cd nexus_temp_master echo "archive file name is: \${ARCHIVE_FILE_NAME}" zip -r \$ARCHIVE_FILE_NAME * # Nexus user and password come from the slave ENV variables curl -v -u \$NEXUS_USER:\$NEXUS_PASSWORD --upload-file \$ARCHIVE_FILE_NAME "\$NEXUS_POST_DEPLOYMENT_ARCHIVE_URL/\$ARCHIVE_FILE_NAME" cd .. """ } } stage('Remove files from source folder') { when { // skip this stage if source folder was general expression { params.artifacts_folder != 'general' } } steps { sh """ echo "since deployment is successful and artifacts were also pushed to archives, remove the jars from current folder" # loop through the folder and delete all files within for f in \$(curl -s \$NEXUS_SEARCH_URL | jq -r .items[].downloadUrl) do curl -X DELETE -u \$NEXUS_USER:\$NEXUS_PASSWORD \$f done """ } } // stage('Close ServiceNow Change Request') { // when { // expression { params.create_SN_change_request == 'true' } // } // steps { // script { // close = updateServiceNowTicketWithCurl(sys_id: "${sys_id}", instanceId: "${params.instanceId}", credentialsId: "${params.credentialsId}", updateJsonDataObject: "${params.closeJsonDataObject}" ) // println close // } // } // } } post { always { script { switch("${Pega_Environment}") { case null: env.EMAIL_RECIPIENTS = "${SUBMITTER_EMAIL}" break case "": env.EMAIL_RECIPIENTS = "${SUBMITTER_EMAIL}" break case " ": env.EMAIL_RECIPIENTS = "${SUBMITTER_EMAIL}" break case "dev": env.EMAIL_RECIPIENTS = "${SUBMITTER_EMAIL}" break case "uat": env.EMAIL_RECIPIENTS = "${SUBMITTER_EMAIL}" break case "maint": env.EMAIL_RECIPIENTS = "${SUBMITTER_EMAIL}" break default: env.EMAIL_RECIPIENTS = "${SUBMITTER_EMAIL}, cc:${SMO_EMAIL}" break } echo "${EMAIL_RECIPIENTS}" } } // do a smooth exit and send email with logs to the pipeline executor on success, failure and unstable scenarios success { script { echo 'The pipeline completed successfully! :)' echo "${env.JOB_BASE_NAME} - Build # ${env.BUILD_NUMBER} - is completed successfully!" // echo "Sending email to '${SUBMITTER_EMAIL}'" echo "${env.LOG_FILE_NAME} - is the log file name" // emailext to: "${SUBMITTER_EMAIL}", subject: "Build for ${env.JOB_BASE_NAME} build ID ${env.BUILD_ID} is completed successfully", body: "Build for ${JOB_BASE_NAME} build ID ${BUILD_ID} is completed successfully", attachLog: true, attachmentsPattern: "${PRPC_LOGS_DIR}/${env.LOG_FILE_NAME}" if ( "${params.create_SN_change_request}" == "true") { emailext subject: "Build for ${env.JOB_BASE_NAME} build ID ${env.BUILD_ID} is completed successfully", body: "Build for ${JOB_BASE_NAME} build ID ${BUILD_ID} is completed successfully \n The Change Request number is ${chg_id}", attachLog: true, attachmentsPattern: "${PRPC_LOGS_DIR}/${env.LOG_FILE_NAME}", to: "${env.EMAIL_RECIPIENTS}" } else { emailext subject: "Build for ${env.JOB_BASE_NAME} build ID ${env.BUILD_ID} is completed successfully", body: "Build for ${JOB_BASE_NAME} build ID ${BUILD_ID} is completed successfully", attachLog: true, attachmentsPattern: "${PRPC_LOGS_DIR}/${env.LOG_FILE_NAME}", to: "${env.EMAIL_RECIPIENTS}" } } } unstable { script { echo 'The pipeline is unstable :(' echo "${env.JOB_BASE_NAME} - Build # ${env.BUILD_NUMBER} - is Unstable!" // mail to: "${SUBMITTER_EMAIL}", subject: "${env.JOB_BASE_NAME} - Build # ${env.BUILD_NUMBER} - is Unstable!", body: "${env.JOB_BASE_NAME} - Build # ${env.BUILD_NUMBER} - is Unstable: Check console output at ${env.BUILD_URL}console to view the results." if ( "${params.create_SN_change_request}" == "true") { emailext subject: "${env.JOB_BASE_NAME} - Build # ${env.BUILD_NUMBER} - is Unstable!", body: "${env.JOB_BASE_NAME} - Build # ${env.BUILD_NUMBER} - is Unstable: Check console output at ${env.BUILD_URL}console to view the results. \n The Change Request number is ${chg_id}", to: "${env.EMAIL_RECIPIENTS}" } else { emailext subject: "${env.JOB_BASE_NAME} - Build # ${env.BUILD_NUMBER} - is Unstable!", body: "${env.JOB_BASE_NAME} - Build # ${env.BUILD_NUMBER} - is Unstable: Check console output at ${env.BUILD_URL}console to view the results.", to: "${env.EMAIL_RECIPIENTS}" } } } failure { script { echo 'The pipeline failed! :(' // echo "Sending email to '${SUBMITTER_EMAIL}'" def msgText = "${env.JOB_BASE_NAME} - Build # ${env.BUILD_NUMBER} - Failed!" echo "Text of message: '${msgText}'" // emailext body: "${msgText}: Check console output at ${env.BUILD_URL}console to view the results.", subject: "${msgText}", to: "${SUBMITTER_EMAIL}", attachLog: true, attachmentsPattern: "${PRPC_LOGS_DIR}/${env.LOG_FILE_NAME}" if ( "${params.create_SN_change_request}" == "true") { emailext body: "${msgText}: Check console output at ${env.BUILD_URL}console to view the results. \n The Change Request number is ${chg_id}", subject: "${msgText}", attachLog: true, attachmentsPattern: "${PRPC_LOGS_DIR}/${env.LOG_FILE_NAME}", to: "${env.EMAIL_RECIPIENTS}" } else { emailext body: "${msgText}: Check console output at ${env.BUILD_URL}console to view the results.",subject: "${msgText}", attachLog: true, attachmentsPattern: "${PRPC_LOGS_DIR}/${env.LOG_FILE_NAME}", to: "${env.EMAIL_RECIPIENTS}" } } } } } }
Write, Run & Share Groovy code online using OneCompiler's Groovy online compiler for free. It's one of the robust, feature-rich online compilers for Groovy language, running the latest Groovy version 2.6. Getting started with the OneCompiler's Groovy editor is easy and fast. The editor shows sample boilerplate code when you choose language as Groovy and start coding.
OneCompiler's Groovy online editor supports stdin and users can give inputs to programs using the STDIN textbox under the I/O tab. Following is a sample Groovy program which takes name as input and prints hello message with your name.
def name = System.in.newReader().readLine()
println "Hello " + name
Groovy is an object-oriented programming language based on java. Apache Groovy is a dynamic and agile language which is similar to Python, Ruby, Smalltalk etc.
Data type | Description | Range |
---|---|---|
String | To represent text literals | NA |
char | To represent single character literal | NA |
int | To represent whole numbers | -2,147,483,648 to 2,147,483,647 |
short | To represent short numbers | -32,768 to 32,767 |
long | To represent long numbers | -9,223,372,036,854,775,808 to +9,223,372,036,854,775,807 |
double | To represent 64 bit floating point numbers | 4.94065645841246544e-324d to 1.79769313486231570e+308d |
float | To represent 32 bit floating point numbers | 1.40129846432481707e-45 to 3.40282346638528860e+38 |
byte | To represent byte value | -128 to 127 |
boolean | To represent boolean values either true or false | True or False |
You can define variables in two ways
data-type variable-name;
[or]
def variable-name;
0.upto(n) {println "$it"}
or
n.times{println "$it"}
where n is the number of loops and 0 specifies the starting index
When ever you want to perform a set of operations based on a condition or set of conditions, then If / Nested-If / If-Else is used.
if(conditional-expression) {
// code
} else {
// code
}
Switch is an alternative to If-Else-If ladder and to select one among many blocks of code.
switch(conditional-expression) {
case value1:
// code
break; // optional
case value2:
// code
break; // optional
...
default:
//code to be executed when all the above cases are not matched;
}
List allows you to store ordered collection of data values.
def mylist = [1,2,3,4,5];
List Methods | Description |
---|---|
size() | To find size of elements |
sort() | To sort the elements |
add() | To append new value at the end |
contains() | Returns true if this List contains requested value. |
get() | Returns the element of the list at the definite position |
pop() | To remove the last item from the List |
isEmpty() | Returns true if List contains no elements |
minus() | This allows you to exclude few specified elements from the elements of the original |
plus() | This allows you to add few specified elements to the elements of the original |
remove() | To remove the element present at the specific position |
reverse() | To reverse the elements of the original List and creates new list |