Changeset b067d9b for Jenkinsfile
- Timestamp:
- Oct 29, 2019, 4:01:24 PM (6 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum, stuck-waitfor-destruct
- Children:
- 773db65, 9421f3d8
- Parents:
- 7951100 (diff), 8364209 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - File:
-
- 1 edited
-
Jenkinsfile (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
-
Jenkinsfile
r7951100 rb067d9b 1 1 #!groovy 2 2 3 import groovy.transform.Field 4 5 // For skipping stages 6 import org.jenkinsci.plugins.pipeline.modeldefinition.Utils 7 3 8 //=========================================================================================================== 4 9 // Main loop of the compilation 5 10 //=========================================================================================================== 6 node ('master'){ 7 8 boolean bIsSandbox = env.BRANCH_NAME == "jenkins-sandbox" 11 12 node('master') { 13 // Globals 14 BuildDir = pwd tmp: true 15 SrcDir = pwd tmp: false 16 Settings = null 17 StageName = '' 18 19 // Local variables 9 20 def err = null 10 21 def log_needed = false 11 12 stage_name = ''13 14 compiler = null15 arch_name = ''16 architecture = ''17 18 do_alltests = false19 do_benchmark = false20 do_doc = false21 do_publish = false22 do_sendemail = true23 22 24 23 currentBuild.result = "SUCCESS" … … 28 27 wrap([$class: 'TimestamperBuildWrapper']) { 29 28 30 notify_server(0) 31 32 prepare_build() 33 34 checkout() 35 36 notify_server(0) 37 38 build() 39 40 test() 41 42 benchmark() 43 44 clean() 45 46 build_doc() 47 48 publish() 49 50 notify_server(45) 29 Settings = prepare_build() 30 31 node(Settings.Architecture.node) { 32 BuildDir = pwd tmp: true 33 SrcDir = pwd tmp: false 34 35 clean() 36 37 checkout() 38 39 build() 40 41 test() 42 43 benchmark() 44 45 build_doc() 46 47 publish() 48 } 49 50 // Update the build directories when exiting the node 51 BuildDir = pwd tmp: true 52 SrcDir = pwd tmp: false 51 53 } 52 54 } … … 58 60 err = caughtError 59 61 62 echo err.toString() 63 60 64 //An error has occured, the build log is relevent 61 65 log_needed = true 62 66 63 67 //Store the result of the build log 64 currentBuild.result = "${ stage_name} FAILURE".trim()68 currentBuild.result = "${StageName} FAILURE".trim() 65 69 } 66 70 67 71 finally { 68 72 //Send email with final results if this is not a full build 69 if( do_sendemail && !bIsSandbox ) { 70 echo 'Notifying users of result' 71 email(currentBuild.result, log_needed) 72 } 73 email(log_needed) 73 74 74 75 echo 'Build Completed' … … 80 81 } 81 82 } 83 //=========================================================================================================== 84 // Main compilation routines 85 //=========================================================================================================== 86 def clean() { 87 build_stage('Cleanup', true) { 88 // clean the build by wipping the build directory 89 dir(BuildDir) { 90 deleteDir() 91 } 92 } 93 } 94 95 //Compilation script is done here but environnement set-up and error handling is done in main loop 96 def checkout() { 97 build_stage('Checkout', true) { 98 //checkout the source code and clean the repo 99 final scmVars = checkout scm 100 Settings.GitNewRef = scmVars.GIT_COMMIT 101 Settings.GitOldRef = scmVars.GIT_PREVIOUS_COMMIT 102 103 echo GitLogMessage() 104 } 105 } 106 107 def build() { 108 debug = true 109 release = Settings.RunAllTests || Settings.RunBenchmark 110 build_stage('Build : configure', true) { 111 // Build outside of the src tree to ease cleaning 112 dir (BuildDir) { 113 //Configure the conpilation (Output is not relevant) 114 //Use the current directory as the installation target so nothing escapes the sandbox 115 //Also specify the compiler by hand 116 targets="" 117 if( Settings.RunAllTests || Settings.RunBenchmark ) { 118 targets="--with-target-hosts='host:debug,host:nodebug'" 119 } else { 120 targets="--with-target-hosts='host:debug'" 121 } 122 123 sh "${SrcDir}/configure CXX=${Settings.Compiler.CXX} CC=${Settings.Compiler.CC} ${Settings.Architecture.flags} ${targets} --quiet" 124 125 // Configure libcfa 126 sh 'make -j 8 --no-print-directory configure-libcfa' 127 } 128 } 129 130 build_stage('Build : cfa-cpp', true) { 131 // Build outside of the src tree to ease cleaning 132 dir (BuildDir) { 133 // Build driver 134 sh 'make -j 8 --no-print-directory -C driver' 135 136 // Build translator 137 sh 'make -j 8 --no-print-directory -C src' 138 } 139 } 140 141 build_stage('Build : libcfa(debug)', debug) { 142 // Build outside of the src tree to ease cleaning 143 dir (BuildDir) { 144 sh "make -j 8 --no-print-directory -C libcfa/${Settings.Architecture.name}-debug" 145 } 146 } 147 148 build_stage('Build : libcfa(nodebug)', release) { 149 // Build outside of the src tree to ease cleaning 150 dir (BuildDir) { 151 sh "make -j 8 --no-print-directory -C libcfa/${Settings.Architecture.name}-nodebug" 152 } 153 } 154 } 155 156 def test() { 157 try { 158 build_stage('Test: short', !Settings.RunAllTests) { 159 dir (BuildDir) { 160 //Run the tests from the tests directory 161 sh "make --no-print-directory -C tests archiveerrors=${BuildDir}/tests/crashes/short" 162 } 163 } 164 165 build_stage('Test: full', Settings.RunAllTests) { 166 dir (BuildDir) { 167 //Run the tests from the tests directory 168 sh """make --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=yes archiveerrors=${BuildDir}/tests/crashes/full-debug""" 169 sh """make --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=no archiveerrors=${BuildDir}/tests/crashes/full-nodebug""" 170 } 171 } 172 } 173 catch (Exception err) { 174 echo "Archiving core dumps" 175 dir (BuildDir) { 176 archiveArtifacts artifacts: "tests/crashes/**/*", fingerprint: true 177 } 178 throw err 179 } 180 } 181 182 def benchmark() { 183 build_stage('Benchmark', Settings.RunBenchmark) { 184 dir (BuildDir) { 185 //Append bench results 186 sh "make --no-print-directory -C benchmark jenkins arch=${Settings.Architecture.name}" 187 } 188 } 189 } 190 191 def build_doc() { 192 build_stage('Documentation', Settings.BuildDocumentation) { 193 dir ('doc/user') { 194 make_doc() 195 } 196 197 dir ('doc/refrat') { 198 make_doc() 199 } 200 } 201 } 202 203 def publish() { 204 build_stage('Publish', true) { 205 206 if( Settings.Publish && !Settings.RunBenchmark ) { echo 'No results to publish!!!' } 207 208 def groupCompile = new PlotGroup('Compilation', 'duration (s) - lower is better', true) 209 def groupConcurrency = new PlotGroup('Concurrency', 'duration (n) - lower is better', false) 210 211 //Then publish the results 212 do_plot(Settings.RunBenchmark && Settings.Publish, 'compile' , groupCompile , false, 'Compilation') 213 do_plot(Settings.RunBenchmark && Settings.Publish, 'compile.diff' , groupCompile , true , 'Compilation (relative)') 214 do_plot(Settings.RunBenchmark && Settings.Publish, 'ctxswitch' , groupConcurrency, false, 'Context Switching') 215 do_plot(Settings.RunBenchmark && Settings.Publish, 'ctxswitch.diff', groupConcurrency, true , 'Context Switching (relative)') 216 do_plot(Settings.RunBenchmark && Settings.Publish, 'mutex' , groupConcurrency, false, 'Mutual Exclusion') 217 do_plot(Settings.RunBenchmark && Settings.Publish, 'mutex.diff' , groupConcurrency, true , 'Mutual Exclusion (relative)') 218 do_plot(Settings.RunBenchmark && Settings.Publish, 'signal' , groupConcurrency, false, 'Internal and External Scheduling') 219 do_plot(Settings.RunBenchmark && Settings.Publish, 'signal.diff' , groupConcurrency, true , 'Internal and External Scheduling (relative)') 220 } 221 } 222 223 //=========================================================================================================== 224 //Routine responsible of sending the email notification once the build is completed 225 //=========================================================================================================== 226 @NonCPS 227 def SplitLines(String text) { 228 def list = [] 229 230 text.eachLine { 231 list += it 232 } 233 234 return list 235 } 236 237 def GitLogMessage() { 238 if (!Settings || !Settings.GitOldRef || !Settings.GitNewRef) return "\nERROR retrieveing git information!\n" 239 240 def oldRef = Settings.GitOldRef 241 def newRef = Settings.GitNewRef 242 243 def revText = sh(returnStdout: true, script: "git rev-list ${oldRef}..${newRef}").trim() 244 def revList = SplitLines( revText ) 245 246 def gitUpdate = "" 247 revList.each { rev -> 248 def type = sh(returnStdout: true, script: "git cat-file -t ${rev}").trim() 249 gitUpdate = gitUpdate + " via ${rev} (${type})" 250 } 251 252 def rev = oldRef 253 def type = sh(returnStdout: true, script: "git cat-file -t ${rev}").trim() 254 gitUpdate = gitUpdate + " from ${rev} (${type})" 255 256 def gitLog = sh(returnStdout: true, script: "git rev-list --format=short ${oldRef}...${newRef}").trim() 257 258 def gitDiff = sh(returnStdout: true, script: "git diff --stat --color ${newRef} ${oldRef}").trim() 259 gitDiff = gitDiff.replace('[32m', '<span style="color: #00AA00;">') 260 gitDiff = gitDiff.replace('[31m', '<span style="color: #AA0000;">') 261 gitDiff = gitDiff.replace('[m', '</span>') 262 263 return """ 264 <pre> 265 The branch ${env.BRANCH_NAME} has been updated. 266 ${gitUpdate} 267 </pre> 268 269 <p>Check console output at ${env.BUILD_URL} to view the results.</p> 270 271 <p>- Status --------------------------------------------------------------</p> 272 273 <p>BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}</p> 274 275 <p>- Log -----------------------------------------------------------------</p> 276 277 <pre> 278 ${gitLog} 279 </pre> 280 281 <p>-----------------------------------------------------------------------</p> 282 <pre> 283 Summary of changes: 284 ${gitDiff} 285 </pre> 286 """ 287 } 288 289 //Standard build email notification 290 def email(boolean log) { 291 //Since tokenizer doesn't work, figure stuff out from the environnement variables and command line 292 //Configurations for email format 293 echo 'Notifying users of result' 294 295 def project_name = (env.JOB_NAME =~ /(.+)\/.+/)[0][1].toLowerCase() 296 def email_subject = "[${project_name} git][BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}] - branch ${env.BRANCH_NAME}" 297 def email_body = """<p>This is an automated email from the Jenkins build machine. It was 298 generated because of a git hooks/post-receive script following 299 a ref change which was pushed to the C\u2200 repository.</p> 300 """ + GitLogMessage() 301 302 def email_to = !Settings.IsSandbox ? "cforall@lists.uwaterloo.ca" : "tdelisle@uwaterloo.ca" 303 304 if( Settings && !Settings.Silent ) { 305 //send email notification 306 emailext body: email_body, subject: email_subject, to: email_to, attachLog: log 307 } else { 308 echo "Would send email to: ${email_to}" 309 echo "With title: ${email_subject}" 310 echo "Content: \n${email_body}" 311 } 312 } 82 313 83 314 //=========================================================================================================== 84 315 // Helper classes/variables/routines 85 316 //=========================================================================================================== 86 //Helper routine to collect information about the git history 87 def collect_git_info() { 88 89 checkout scm 90 91 //create the temporary output directory in case it doesn't already exist 92 def out_dir = pwd tmp: true 93 sh "mkdir -p ${out_dir}" 94 95 //parse git logs to find what changed 96 gitRefName = env.BRANCH_NAME 97 sh "git reflog > ${out_dir}/GIT_COMMIT" 98 git_reflog = readFile("${out_dir}/GIT_COMMIT") 99 gitRefOldValue = (git_reflog =~ /moving from (.+) to (.+)/)[0][1] 100 gitRefNewValue = (git_reflog =~ /moving from (.+) to (.+)/)[0][2] 317 //Description of a compiler (Must be serializable since pipelines are persistent) 318 class CC_Desc implements Serializable { 319 public String name 320 public String CXX 321 public String CC 322 323 CC_Desc(String name, String CXX, String CC) { 324 this.name = name 325 this.CXX = CXX 326 this.CC = CC 327 } 328 } 329 330 //Description of an architecture (Must be serializable since pipelines are persistent) 331 class Arch_Desc implements Serializable { 332 public String name 333 public String flags 334 public String node 335 336 Arch_Desc(String name, String flags, String node) { 337 this.name = name 338 this.flags = flags 339 this.node = node 340 } 341 } 342 343 class BuildSettings implements Serializable { 344 public final CC_Desc Compiler 345 public final Arch_Desc Architecture 346 public final Boolean RunAllTests 347 public final Boolean RunBenchmark 348 public final Boolean BuildDocumentation 349 public final Boolean Publish 350 public final Boolean Silent 351 public final Boolean IsSandbox 352 public final String DescLong 353 public final String DescShort 354 355 public String GitNewRef 356 public String GitOldRef 357 358 BuildSettings(java.util.Collections$UnmodifiableMap param, String branch) { 359 switch( param.Compiler ) { 360 case 'gcc-6': 361 this.Compiler = new CC_Desc('gcc-6', 'g++-6', 'gcc-6') 362 break 363 case 'gcc-5': 364 this.Compiler = new CC_Desc('gcc-5', 'g++-5', 'gcc-5') 365 break 366 case 'gcc-4.9': 367 this.Compiler = new CC_Desc('gcc-4.9', 'g++-4.9', 'gcc-4.9') 368 break 369 case 'clang': 370 this.Compiler = new CC_Desc('clang', 'clang++', 'gcc-6') 371 break 372 default : 373 error "Unhandled compiler : ${cc}" 374 } 375 376 switch( param.Architecture ) { 377 case 'x64': 378 this.Architecture = new Arch_Desc('x64', '--host=x86_64', 'x64') 379 break 380 case 'x86': 381 this.Architecture = new Arch_Desc('x86', '--host=i386', 'x86') 382 break 383 default : 384 error "Unhandled architecture : ${arch}" 385 } 386 387 this.IsSandbox = (branch == "jenkins-sandbox") 388 this.RunAllTests = param.RunAllTests 389 this.RunBenchmark = param.RunBenchmark 390 this.BuildDocumentation = param.BuildDocumentation 391 this.Publish = param.Publish 392 this.Silent = param.Silent 393 394 def full = param.RunAllTests ? " (Full)" : "" 395 this.DescShort = "${ this.Compiler.name }:${ this.Architecture.name }${full}" 396 397 this.DescLong = """Compiler : ${ this.Compiler.name } (${ this.Compiler.CXX }/${ this.Compiler.CC }) 398 Architecture : ${ this.Architecture.name } 399 Arc Flags : ${ this.Architecture.flags } 400 Run All Tests : ${ this.RunAllTests.toString() } 401 Run Benchmark : ${ this.RunBenchmark.toString() } 402 Build Documentation : ${ this.BuildDocumentation.toString() } 403 Publish : ${ this.Publish.toString() } 404 Silent : ${ this.Silent.toString() } 405 """ 406 407 this.GitNewRef = '' 408 this.GitOldRef = '' 409 } 410 } 411 412 class PlotGroup implements Serializable { 413 public String name 414 public String unit 415 public boolean log 416 417 PlotGroup(String name, String unit, boolean log) { 418 this.name = name 419 this.unit = unit 420 this.log = log 421 } 101 422 } 102 423 103 424 def prepare_build() { 425 // prepare the properties 104 426 properties ([ \ 105 427 [$class: 'ParametersDefinitionProperty', \ … … 107 429 [$class: 'ChoiceParameterDefinition', \ 108 430 description: 'Which compiler to use', \ 109 name: ' pCompiler',\431 name: 'Compiler', \ 110 432 choices: 'gcc-6\ngcc-5\ngcc-4.9\nclang', \ 111 433 defaultValue: 'gcc-6', \ … … 113 435 [$class: 'ChoiceParameterDefinition', \ 114 436 description: 'The target architecture', \ 115 name: ' pArchitecture', \437 name: 'Architecture', \ 116 438 choices: 'x64\nx86', \ 117 439 defaultValue: 'x64', \ … … 119 441 [$class: 'BooleanParameterDefinition', \ 120 442 description: 'If false, only the quick test suite is ran', \ 121 name: ' pRunAllTests', \443 name: 'RunAllTests', \ 122 444 defaultValue: false, \ 123 445 ], \ 124 446 [$class: 'BooleanParameterDefinition', \ 125 447 description: 'If true, jenkins also runs benchmarks', \ 126 name: ' pRunBenchmark', \127 defaultValue: true, \448 name: 'RunBenchmark', \ 449 defaultValue: false, \ 128 450 ], \ 129 451 [$class: 'BooleanParameterDefinition', \ 130 452 description: 'If true, jenkins also builds documentation', \ 131 name: ' pBuildDocumentation', \453 name: 'BuildDocumentation', \ 132 454 defaultValue: true, \ 133 455 ], \ 134 456 [$class: 'BooleanParameterDefinition', \ 135 457 description: 'If true, jenkins also publishes results', \ 136 name: ' pPublish',\458 name: 'Publish', \ 137 459 defaultValue: false, \ 138 460 ], \ 139 461 [$class: 'BooleanParameterDefinition', \ 140 462 description: 'If true, jenkins will not send emails', \ 141 name: ' pSilent', \463 name: 'Silent', \ 142 464 defaultValue: false, \ 143 465 ], \ … … 145 467 ]]) 146 468 147 compiler = compiler_from_params( pCompiler ) 148 arch_name = pArchitecture 149 architecture = architecture_from_params( arch_name ) 150 151 do_alltests = (pRunAllTests == 'true') 152 do_benchmark = (pRunBenchmark == 'true') 153 do_doc = (pBuildDocumentation == 'true') 154 do_publish = (pPublish == 'true') 155 do_sendemail = ! (pSilent == 'true') 156 157 echo """Compiler : ${compiler.cc_name} (${compiler.cpp_cc}/${compiler.cfa_cc}) 158 Architecture : ${arch_name} 159 Arc Flags : ${architecture} 160 Run All Tests : ${ pRunAllTests.toString() } 161 Run Benchmark : ${ pRunBenchmark.toString() } 162 Build Documentation : ${ pBuildDocumentation.toString() } 163 Publish : ${ pPublish.toString() } 164 Silent : ${ pSilent.toString() } 165 """ 166 167 collect_git_info() 168 } 169 170 def build_stage(String name, Closure block ) { 171 stage_name = name 172 stage(name, block) 173 } 174 175 def notify_server(int wait) { 176 sh """curl --data "wait=${wait}" -X POST https://cforall.uwaterloo.ca:8082/jenkins/notify > /dev/null || true""" 177 return 469 // It's unfortunate but it looks like we need to checkout the entire repo just to get the pretty git printer 470 checkout scm 471 472 final settings = new BuildSettings(params, env.BRANCH_NAME) 473 474 currentBuild.description = settings.DescShort 475 echo settings.DescLong 476 477 return settings 478 } 479 480 def build_stage(String name, boolean run, Closure block ) { 481 StageName = name 482 echo " -------- ${StageName} -------- " 483 if(run) { 484 stage(name, block) 485 } else { 486 stage(name) { Utils.markStageSkippedForConditional(STAGE_NAME) } 487 } 178 488 } 179 489 … … 186 496 catch (Exception caughtError) { 187 497 err = caughtError //rethrow error later 188 sh 'cat *.log'498 sh 'cat build/*.log' 189 499 } 190 500 finally { … … 193 503 } 194 504 195 //Description of a compiler (Must be serializable since pipelines are persistent) 196 class CC_Desc implements Serializable { 197 public String cc_name 198 public String cpp_cc 199 public String cfa_cc 200 201 CC_Desc(String cc_name, String cpp_cc, String cfa_cc) { 202 this.cc_name = cc_name 203 this.cpp_cc = cpp_cc 204 this.cfa_cc = cfa_cc 205 } 206 } 207 208 def compiler_from_params(cc) { 209 switch( cc ) { 210 case 'gcc-6': 211 return new CC_Desc('gcc-6', 'g++-6', 'gcc-6') 212 break 213 case 'gcc-5': 214 return new CC_Desc('gcc-5', 'g++-5', 'gcc-5') 215 break 216 case 'gcc-4.9': 217 return new CC_Desc('gcc-4.9', 'g++-4.9', 'gcc-4.9') 218 break 219 case 'clang': 220 return new CC_Desc('clang', 'clang++', 'gcc-6') 221 break 222 default : 223 error "Unhandled compiler : ${cc}" 224 } 225 } 226 227 def architecture_from_params( arch ) { 228 switch( arch ) { 229 case 'x64': 230 return '--host=x86_64' 231 break 232 case 'x86': 233 return '--host=i386' 234 break 235 default : 236 error "Unhandled architecture : ${arch}" 237 } 238 } 239 240 //=========================================================================================================== 241 // Main compilation routines 242 //=========================================================================================================== 243 //Compilation script is done here but environnement set-up and error handling is done in main loop 244 def checkout() { 245 build_stage('Checkout') { 246 //checkout the source code and clean the repo 247 checkout scm 248 249 //Clean all temporary files to make sure no artifacts of the previous build remain 250 sh 'git clean -fdqx' 251 252 //Reset the git repo so no local changes persist 253 sh 'git reset --hard' 254 } 255 } 256 257 def build() { 258 build_stage('Build') { 259 260 def install_dir = pwd tmp: true 261 262 //Output compiler version to help with debug 263 echo """C++ Compiler :""" 264 sh "which ${compiler.cpp_cc} && ${compiler.cpp_cc} --version" 265 echo """C Compiler :""" 266 sh "which ${compiler.cfa_cc} && ${compiler.cfa_cc} --version" 267 268 //Configure the conpilation (Output is not relevant) 269 //Use the current directory as the installation target so nothing escapes the sandbox 270 //Also specify the compiler by hand 271 sh "./configure CXX=${compiler.cpp_cc} ${architecture} --with-backend-compiler=${compiler.cfa_cc} --prefix=${install_dir} --enable-silent-rules --quiet" 272 273 //Compile the project 274 sh 'make -j 8 --no-print-directory V=0 install' 275 } 276 } 277 278 def test() { 279 build_stage('Test') { 280 281 //Run the tests from the tests directory 282 if ( do_alltests ) { 283 sh 'make -C src/tests all-tests debug=yes --no-print-directory' 284 sh 'make -C src/tests all-tests debug=no --no-print-directory' 285 } 286 else { 287 sh 'make -C src/tests --no-print-directory' 288 } 289 } 290 } 291 292 def benchmark() { 293 build_stage('Benchmark') { 294 295 if( !do_benchmark ) return 296 297 //Append bench results 298 sh 'make -C src/benchmark --no-print-directory jenkins githash=' + gitRefNewValue + ' arch=' + arch_name + ' | tee bench.json' 299 } 300 } 301 302 def clean() { 303 build_stage('Cleanup') { 304 305 //do a maintainer-clean to make sure we need to remake from scratch 306 sh 'make maintainer-clean > /dev/null' 307 } 308 } 309 310 def build_doc() { 311 build_stage('Documentation') { 312 313 if( !do_doc ) return 314 315 dir ('doc/user') { 316 make_doc() 317 } 318 319 dir ('doc/refrat') { 320 make_doc() 321 } 322 } 323 } 324 325 def publish() { 326 build_stage('Publish') { 327 328 if( !do_publish ) return 329 330 //Then publish the results 331 sh 'curl -H \'Content-Type: application/json\' --data @bench.json https://cforall.uwaterloo.ca:8082/jenkins/publish > /dev/null || true' 332 } 333 } 334 335 //=========================================================================================================== 336 //Routine responsible of sending the email notification once the build is completed 337 //=========================================================================================================== 338 //Standard build email notification 339 def email(String status, boolean log) { 340 //Since tokenizer doesn't work, figure stuff out from the environnement variables and command line 341 //Configurations for email format 342 def project_name = (env.JOB_NAME =~ /(.+)\/.+/)[0][1].toLowerCase() 343 344 def gitLog = 'Error retrieving git logs' 345 def gitDiff = 'Error retrieving git diff' 346 347 try { 348 349 sh "git rev-list --format=short ${gitRefOldValue}...${gitRefNewValue} > GIT_LOG" 350 gitLog = readFile('GIT_LOG') 351 352 sh "git diff --stat ${gitRefNewValue} ${gitRefOldValue} > GIT_DIFF" 353 gitDiff = readFile('GIT_DIFF') 354 } 355 catch (Exception error) {} 356 357 def email_subject = "[${project_name} git][BUILD# ${env.BUILD_NUMBER} - ${status}] - branch ${env.BRANCH_NAME}" 358 def email_body = """This is an automated email from the Jenkins build machine. It was 359 generated because of a git hooks/post-receive script following 360 a ref change was pushed to the repository containing 361 the project "UNNAMED PROJECT". 362 363 The branch ${env.BRANCH_NAME} has been updated. 364 via ${gitRefOldValue} (commit) 365 from ${gitRefNewValue} (commit) 366 367 Check console output at ${env.BUILD_URL} to view the results. 368 369 - Status -------------------------------------------------------------- 370 371 BUILD# ${env.BUILD_NUMBER} - ${status} 372 373 - Log ----------------------------------------------------------------- 374 ${gitLog} 375 ----------------------------------------------------------------------- 376 Summary of changes: 377 ${gitDiff} 378 """ 379 380 def email_to = "cforall@lists.uwaterloo.ca" 381 382 //send email notification 383 emailext body: email_body, subject: email_subject, to: email_to, attachLog: log 384 } 505 def do_plot(boolean new_data, String file, PlotGroup group, boolean relative, String title) { 506 507 if(new_data) { 508 echo "Publishing new data" 509 } 510 511 def series = new_data ? [[ 512 file: "${file}.csv", 513 exclusionValues: '', 514 displayTableFlag: false, 515 inclusionFlag: 'OFF', 516 url: '' 517 ]] : []; 518 519 echo "file is ${BuildDir}/benchmark/${file}.csv, group ${group}, title ${title}" 520 dir("${BuildDir}/benchmark/") { 521 plot csvFileName: "cforall-${env.BRANCH_NAME}-${file}.csv", 522 csvSeries: series, 523 group: "${group.name}", 524 title: "${title}", 525 style: 'lineSimple', 526 exclZero: false, 527 keepRecords: false, 528 logarithmic: !relative && group.log, 529 numBuilds: '120', 530 useDescr: true, 531 yaxis: group.unit, 532 yaxisMaximum: '', 533 yaxisMinimum: '' 534 } 535 }
Note:
See TracChangeset
for help on using the changeset viewer.