source: Jenkinsfile@ c57f59d

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr pthread-emulation qualifiedEnum stuck-waitfor-destruct
Last change on this file since c57f59d was c57f59d, checked in by Thierry Delisle <tdelisle@…>, 7 years ago

Tentative fix for call to eachLine which had some warnings

  • Property mode set to 100644
File size: 15.6 KB
RevLine 
[a63ad80]1#!groovy
2
[7a230fd]3import groovy.transform.Field
4
[8ecb590]5// For skipping stages
6import org.jenkinsci.plugins.pipeline.modeldefinition.Utils
7
[29f4fe62]8//===========================================================================================================
[9beae23]9// Main loop of the compilation
[29f4fe62]10//===========================================================================================================
[56a9ce6]11
[5307c33]12node('master') {
[5b8413b4]13 // Globals
[4c55047]14 BuildDir = pwd tmp: true
15 SrcDir = pwd tmp: false
[5b8413b4]16 Settings = null
17 StageName = ''
18
19 // Local variables
[9beae23]20 def err = null
21 def log_needed = false
[0ef06b6]22
23 currentBuild.result = "SUCCESS"
24
[9beae23]25 try {
[95fdb0a]26 //Wrap build to add timestamp to command line
27 wrap([$class: 'TimestamperBuildWrapper']) {
[23a14d86]28
[c431138]29 Settings = prepare_build()
[7aebc62]30
[5307c33]31 node(Settings.Architecture.node) {
[bf9d323]32 BuildDir = pwd tmp: true
33 SrcDir = pwd tmp: false
34
[5307c33]35 clean()
[0dc3ac3]36
[5307c33]37 checkout()
[fde808df]38
[5307c33]39 build()
[95fdb0a]40
[5307c33]41 test()
[95fdb0a]42
[5307c33]43 benchmark()
[95fdb0a]44
[5307c33]45 build_doc()
[7359098]46
[5307c33]47 publish()
48 }
[9beae23]49
[4c55047]50 // Update the build directories when exiting the node
51 BuildDir = pwd tmp: true
52 SrcDir = pwd tmp: false
[9beae23]53 }
[738cf8f]54 }
55
[9beae23]56 //If an exception is caught we need to change the status and remember to
57 //attach the build log to the email
[738cf8f]58 catch (Exception caughtError) {
59 //rethrow error later
60 err = caughtError
61
[e966ec0]62 echo err.toString()
63
[9beae23]64 //An error has occured, the build log is relevent
65 log_needed = true
66
67 //Store the result of the build log
[5b8413b4]68 currentBuild.result = "${StageName} FAILURE".trim()
[738cf8f]69 }
70
71 finally {
[9beae23]72 //Send email with final results if this is not a full build
[13c98a4]73 email(log_needed)
[9beae23]74
[734891d]75 echo 'Build Completed'
76
[738cf8f]77 /* Must re-throw exception to propagate error */
78 if (err) {
79 throw err
80 }
81 }
82}
[29f4fe62]83//===========================================================================================================
[9beae23]84// Main compilation routines
[29f4fe62]85//===========================================================================================================
[0dc3ac3]86def clean() {
[6c55a3d]87 build_stage('Cleanup', true) {
[0dc3ac3]88 // clean the build by wipping the build directory
[5b8413b4]89 dir(BuildDir) {
[d4cd491]90 deleteDir()
[ece8a80]91 }
[620dd2b]92 }
[95fdb0a]93}
[29f4fe62]94
[0dc3ac3]95//Compilation script is done here but environnement set-up and error handling is done in main loop
96def checkout() {
[6c55a3d]97 build_stage('Checkout', true) {
[0dc3ac3]98 //checkout the source code and clean the repo
[a336d46]99 final scmVars = checkout scm
100 Settings.GitNewRef = scmVars.GIT_COMMIT
101 Settings.GitOldRef = scmVars.GIT_PREVIOUS_COMMIT
[d3a4564a]102
[a336d46]103 echo GitLogMessage()
[0dc3ac3]104 }
105}
106
[95fdb0a]107def build() {
[e507c11]108 debug = true
109 release = Settings.RunAllTests || Settings.RunBenchmark
110 build_stage('Build : configure', true) {
[50f2cfc]111 // Build outside of the src tree to ease cleaning
[5b8413b4]112 dir (BuildDir) {
[50f2cfc]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
[3fc5f010]116 targets=""
[d4510ea]117 if( Settings.RunAllTests || Settings.RunBenchmark ) {
[6bde81d]118 targets="--with-target-hosts='host:debug,host:nodebug'"
[3fc5f010]119 } else {
[6bde81d]120 targets="--with-target-hosts='host:debug'"
[3fc5f010]121 }
122
[93fe3154]123 sh "${SrcDir}/configure CXX=${Settings.Compiler.CXX} CC=${Settings.Compiler.CC} ${Settings.Architecture.flags} ${targets} --quiet"
[f253e4a]124
125 // Configure libcfa
[e70e54e]126 sh 'make -j 8 --no-print-directory configure-libcfa'
[e507c11]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 }
[1752d0e]140
[e507c11]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"
[50f2cfc]152 }
[620dd2b]153 }
[95fdb0a]154}
[24eecab]155
[95fdb0a]156def test() {
[4c1b9ea8]157 try {
158 build_stage('Test: short', !Settings.RunAllTests) {
159 dir (BuildDir) {
[3e93c00]160 //Run the tests from the tests directory
[4c51aca]161 sh "make --no-print-directory -C tests archiveerrors=${BuildDir}/tests/crashes/short"
[3e93c00]162 }
[4c1b9ea8]163 }
164
165 build_stage('Test: full', Settings.RunAllTests) {
166 dir (BuildDir) {
167 //Run the tests from the tests directory
[4c51aca]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"""
[143e6f3]170 }
[9beae23]171 }
[620dd2b]172 }
[4c1b9ea8]173 catch (Exception err) {
174 echo "Archiving core dumps"
[c95fdc9]175 dir (BuildDir) {
176 archiveArtifacts artifacts: "tests/crashes/**/*", fingerprint: true
177 }
[4c1b9ea8]178 throw err
179 }
[95fdb0a]180}
181
182def benchmark() {
[6c55a3d]183 build_stage('Benchmark', Settings.RunBenchmark) {
[5b8413b4]184 dir (BuildDir) {
[0dc3ac3]185 //Append bench results
[c6f1f3e]186 sh "make --no-print-directory -C benchmark jenkins arch=${Settings.Architecture.name}"
[0dc3ac3]187 }
[620dd2b]188 }
[9beae23]189}
[efd60d67]190
[95fdb0a]191def build_doc() {
[6c55a3d]192 build_stage('Documentation', Settings.BuildDocumentation) {
[9beae23]193 dir ('doc/user') {
194 make_doc()
195 }
196
197 dir ('doc/refrat') {
198 make_doc()
199 }
[620dd2b]200 }
[9beae23]201}
202
[95fdb0a]203def publish() {
[6c55a3d]204 build_stage('Publish', true) {
[95fdb0a]205
[1b3eef8]206 if( Settings.Publish && !Settings.RunBenchmark ) { echo 'No results to publish!!!' }
[95fdb0a]207
[3221a2b]208 def groupCompile = new PlotGroup('Compilation', 'duration (s) - lower is better', true)
209 def groupConcurrency = new PlotGroup('Concurrency', 'duration (n) - lower is better', false)
[a2a0065]210
[3898392]211 //Then publish the results
[3221a2b]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)')
[620dd2b]220 }
[95fdb0a]221}
222
[29f4fe62]223//===========================================================================================================
224//Routine responsible of sending the email notification once the build is completed
225//===========================================================================================================
[a336d46]226def GitLogMessage() {
227 if (!Settings || !Settings.GitOldRef || !Settings.GitNewRef) return "\nERROR retrieveing git information!\n"
[e8a22a7]228
[fce01e7]229 def oldRef = Settings.GitOldRef
230 def newRef = Settings.GitNewRef
[6badd87]231
[c57f59d]232 def revisions = sh(returnStdout: true, script: "git rev-list ${oldRef}..${newRef}").trim().readLines()
[fce01e7]233 def gitUpdate = ""
[6e31c43]234
[c57f59d]235 revisions.each { rev ->
[249091f]236 def type = sh(returnStdout: true, script: "git cat-file -t ${rev}").trim()
[fce01e7]237 gitUpdate = gitUpdate + " via ${rev} (${type})"
238 }
239
240 def rev = oldRef
[249091f]241 def type = sh(returnStdout: true, script: "git cat-file -t ${rev}").trim()
242 gitUpdate = gitUpdate + " from ${rev} (${type})"
[fce01e7]243
[249091f]244 def gitLog = sh(returnStdout: true, script: "git rev-list --format=short ${oldRef}...${newRef}").trim()
[fce01e7]245
[249091f]246 def gitDiff = sh(returnStdout: true, script: "git diff --stat --color ${newRef} ${oldRef}").trim()
[fce01e7]247 gitDiff = gitDiff.replace('[32m', '<span style="color: #00AA00;">')
248 gitDiff = gitDiff.replace('[31m', '<span style="color: #AA0000;">')
249 gitDiff = gitDiff.replace('[m', '</span>')
[7a927ed0]250
[a336d46]251 return """
[13c98a4]252<pre>
[848fb00]253The branch ${env.BRANCH_NAME} has been updated.
[7a927ed0]254${gitUpdate}
[13c98a4]255</pre>
256
257<p>Check console output at ${env.BUILD_URL} to view the results.</p>
[7b1a604]258
[13c98a4]259<p>- Status --------------------------------------------------------------</p>
[7b1a604]260
[13c98a4]261<p>BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}</p>
[7b1a604]262
[13c98a4]263<p>- Log -----------------------------------------------------------------</p>
[e8a22a7]264
[13c98a4]265<pre>
[7a927ed0]266${gitLog}
[13c98a4]267</pre>
268
269<p>-----------------------------------------------------------------------</p>
270<pre>
[7b1a604]271Summary of changes:
[7a927ed0]272${gitDiff}
[13c98a4]273</pre>
[7b1a604]274"""
[a336d46]275}
276
277//Standard build email notification
[13c98a4]278def email(boolean log) {
[a336d46]279 //Since tokenizer doesn't work, figure stuff out from the environnement variables and command line
280 //Configurations for email format
281 echo 'Notifying users of result'
282
283 def project_name = (env.JOB_NAME =~ /(.+)\/.+/)[0][1].toLowerCase()
284 def email_subject = "[${project_name} git][BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}] - branch ${env.BRANCH_NAME}"
[13c98a4]285 def email_body = """<p>This is an automated email from the Jenkins build machine. It was
[a336d46]286generated because of a git hooks/post-receive script following
[986e260]287a ref change which was pushed to the C\u2200 repository.</p>
[a336d46]288""" + GitLogMessage()
[e8a22a7]289
[13c98a4]290 def email_to = !Settings.IsSandbox ? "cforall@lists.uwaterloo.ca" : "tdelisle@uwaterloo.ca"
[e8a22a7]291
[13c98a4]292 if( Settings && !Settings.Silent ) {
[094a42c]293 //send email notification
294 emailext body: email_body, subject: email_subject, to: email_to, attachLog: log
295 } else {
296 echo "Would send email to: ${email_to}"
297 echo "With title: ${email_subject}"
298 echo "Content: \n${email_body}"
299 }
[e8a22a7]300}
[5b8413b4]301
302//===========================================================================================================
303// Helper classes/variables/routines
304//===========================================================================================================
305//Description of a compiler (Must be serializable since pipelines are persistent)
306class CC_Desc implements Serializable {
[93fe3154]307 public String name
308 public String CXX
[6ebc13f]309 public String CC
[93fe3154]310
[6ebc13f]311 CC_Desc(String name, String CXX, String CC) {
[93fe3154]312 this.name = name
313 this.CXX = CXX
[6ebc13f]314 this.CC = CC
[5b8413b4]315 }
316}
317
318//Description of an architecture (Must be serializable since pipelines are persistent)
319class Arch_Desc implements Serializable {
320 public String name
321 public String flags
[5307c33]322 public String node
[5b8413b4]323
[5307c33]324 Arch_Desc(String name, String flags, String node) {
[5b8413b4]325 this.name = name
326 this.flags = flags
[5307c33]327 this.node = node
[5b8413b4]328 }
329}
330
331class BuildSettings implements Serializable {
332 public final CC_Desc Compiler
333 public final Arch_Desc Architecture
334 public final Boolean RunAllTests
335 public final Boolean RunBenchmark
336 public final Boolean BuildDocumentation
337 public final Boolean Publish
338 public final Boolean Silent
339 public final Boolean IsSandbox
340 public final String DescLong
341 public final String DescShort
342
[a336d46]343 public String GitNewRef
344 public String GitOldRef
345
[490cb3c]346 BuildSettings(java.util.Collections$UnmodifiableMap param, String branch) {
[5b8413b4]347 switch( param.Compiler ) {
348 case 'gcc-6':
349 this.Compiler = new CC_Desc('gcc-6', 'g++-6', 'gcc-6')
350 break
351 case 'gcc-5':
352 this.Compiler = new CC_Desc('gcc-5', 'g++-5', 'gcc-5')
353 break
354 case 'gcc-4.9':
355 this.Compiler = new CC_Desc('gcc-4.9', 'g++-4.9', 'gcc-4.9')
356 break
357 case 'clang':
358 this.Compiler = new CC_Desc('clang', 'clang++', 'gcc-6')
359 break
360 default :
361 error "Unhandled compiler : ${cc}"
362 }
363
364 switch( param.Architecture ) {
365 case 'x64':
[a3e8281]366 this.Architecture = new Arch_Desc('x64', '--host=x86_64', 'x64')
[5b8413b4]367 break
368 case 'x86':
[a3e8281]369 this.Architecture = new Arch_Desc('x86', '--host=i386', 'x86')
[5b8413b4]370 break
371 default :
372 error "Unhandled architecture : ${arch}"
373 }
374
[f95e8f0]375 this.IsSandbox = (branch == "jenkins-sandbox")
[5b8413b4]376 this.RunAllTests = param.RunAllTests
[7a230fd]377 this.RunBenchmark = param.RunBenchmark
[5b8413b4]378 this.BuildDocumentation = param.BuildDocumentation
[7a230fd]379 this.Publish = param.Publish
[5b8413b4]380 this.Silent = param.Silent
381
382 def full = param.RunAllTests ? " (Full)" : ""
[490cb3c]383 this.DescShort = "${ this.Compiler.name }:${ this.Architecture.name }${full}"
[5b8413b4]384
[93fe3154]385 this.DescLong = """Compiler : ${ this.Compiler.name } (${ this.Compiler.CXX }/${ this.Compiler.CC })
[5b8413b4]386Architecture : ${ this.Architecture.name }
387Arc Flags : ${ this.Architecture.flags }
388Run All Tests : ${ this.RunAllTests.toString() }
389Run Benchmark : ${ this.RunBenchmark.toString() }
390Build Documentation : ${ this.BuildDocumentation.toString() }
391Publish : ${ this.Publish.toString() }
392Silent : ${ this.Silent.toString() }
393"""
[a336d46]394
395 this.GitNewRef = ''
396 this.GitOldRef = ''
[5b8413b4]397 }
398}
399
[490cb3c]400class PlotGroup implements Serializable {
401 public String name
402 public String unit
403 public boolean log
404
405 PlotGroup(String name, String unit, boolean log) {
406 this.name = name
407 this.unit = unit
408 this.log = log
409 }
410}
411
[5b8413b4]412def prepare_build() {
413 // prepare the properties
414 properties ([ \
415 [$class: 'ParametersDefinitionProperty', \
416 parameterDefinitions: [ \
417 [$class: 'ChoiceParameterDefinition', \
418 description: 'Which compiler to use', \
419 name: 'Compiler', \
420 choices: 'gcc-6\ngcc-5\ngcc-4.9\nclang', \
421 defaultValue: 'gcc-6', \
422 ], \
423 [$class: 'ChoiceParameterDefinition', \
424 description: 'The target architecture', \
425 name: 'Architecture', \
426 choices: 'x64\nx86', \
427 defaultValue: 'x64', \
428 ], \
429 [$class: 'BooleanParameterDefinition', \
430 description: 'If false, only the quick test suite is ran', \
431 name: 'RunAllTests', \
432 defaultValue: false, \
433 ], \
434 [$class: 'BooleanParameterDefinition', \
435 description: 'If true, jenkins also runs benchmarks', \
436 name: 'RunBenchmark', \
437 defaultValue: false, \
438 ], \
439 [$class: 'BooleanParameterDefinition', \
440 description: 'If true, jenkins also builds documentation', \
441 name: 'BuildDocumentation', \
442 defaultValue: true, \
443 ], \
444 [$class: 'BooleanParameterDefinition', \
445 description: 'If true, jenkins also publishes results', \
446 name: 'Publish', \
447 defaultValue: false, \
448 ], \
449 [$class: 'BooleanParameterDefinition', \
450 description: 'If true, jenkins will not send emails', \
451 name: 'Silent', \
452 defaultValue: false, \
453 ], \
454 ],
455 ]])
456
[4c55047]457 // It's unfortunate but it looks like we need to checkout the entire repo just to get the pretty git printer
458 checkout scm
[2407853]459
[490cb3c]460 final settings = new BuildSettings(params, env.BRANCH_NAME)
[5b8413b4]461
462 currentBuild.description = settings.DescShort
463 echo settings.DescLong
464
465 return settings
466}
467
[6c55a3d]468def build_stage(String name, boolean run, Closure block ) {
[5b8413b4]469 StageName = name
470 echo " -------- ${StageName} -------- "
[8ecb590]471 if(run) {
472 stage(name, block)
473 } else {
474 stage(name) { Utils.markStageSkippedForConditional(STAGE_NAME) }
475 }
[5b8413b4]476}
477
478def make_doc() {
479 def err = null
480 try {
481 sh 'make clean > /dev/null'
482 sh 'make > /dev/null 2>&1'
483 }
484 catch (Exception caughtError) {
485 err = caughtError //rethrow error later
[65f4a51]486 sh 'cat build/*.log'
[5b8413b4]487 }
488 finally {
489 if (err) throw err // Must re-throw exception to propagate error
490 }
[a2a0065]491}
492
[3221a2b]493def do_plot(boolean new_data, String file, PlotGroup group, boolean relative, String title) {
[8d63649]494
[1b3eef8]495 if(new_data) {
496 echo "Publishing new data"
497 }
498
[cdcd53dc]499 def series = new_data ? [[
[df57a84]500 file: "${file}.csv",
[3c40dc2a]501 exclusionValues: '',
502 displayTableFlag: false,
503 inclusionFlag: 'OFF',
504 url: ''
[cdcd53dc]505 ]] : [];
[8d63649]506
507 echo "file is ${BuildDir}/benchmark/${file}.csv, group ${group}, title ${title}"
508 dir("${BuildDir}/benchmark/") {
509 plot csvFileName: "cforall-${env.BRANCH_NAME}-${file}.csv",
510 csvSeries: series,
[490cb3c]511 group: "${group.name}",
[3c40dc2a]512 title: "${title}",
513 style: 'lineSimple',
514 exclZero: false,
515 keepRecords: false,
[3221a2b]516 logarithmic: !relative && group.log,
[3c40dc2a]517 numBuilds: '120',
518 useDescr: true,
[490cb3c]519 yaxis: group.unit,
[3c40dc2a]520 yaxisMaximum: '',
521 yaxisMinimum: ''
[df57a84]522 }
523}
Note: See TracBrowser for help on using the repository browser.