source: Jenkinsfile@ e507c11

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

Jenkins now builds translator and libraries in several steps to improve stage view in jenkins

  • Property mode set to 100644
File size: 14.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 // build_stage('Build', true) {
109 // // Build outside of the src tree to ease cleaning
110 // dir (BuildDir) {
111 // //Configure the conpilation (Output is not relevant)
112 // //Use the current directory as the installation target so nothing escapes the sandbox
113 // //Also specify the compiler by hand
114 // targets=""
115 // if( Settings.RunAllTests || Settings.RunBenchmark ) {
116 // targets="--with-target-hosts='host:debug,host:nodebug'"
117 // } else {
118 // targets="--with-target-hosts='host:debug'"
119 // }
120
121 // sh "${SrcDir}/configure CXX=${Settings.Compiler.CXX} CC=${Settings.Compiler.CC} ${Settings.Architecture.flags} ${targets} --quiet"
122
123 // //Compile the project
124 // sh 'make -j 8 --no-print-directory'
125 // }
126 // }
127
128 debug = true
129 release = Settings.RunAllTests || Settings.RunBenchmark
130 build_stage('Build : configure', true) {
[50f2cfc]131 // Build outside of the src tree to ease cleaning
[5b8413b4]132 dir (BuildDir) {
[50f2cfc]133 //Configure the conpilation (Output is not relevant)
134 //Use the current directory as the installation target so nothing escapes the sandbox
135 //Also specify the compiler by hand
[3fc5f010]136 targets=""
[d4510ea]137 if( Settings.RunAllTests || Settings.RunBenchmark ) {
[6bde81d]138 targets="--with-target-hosts='host:debug,host:nodebug'"
[3fc5f010]139 } else {
[6bde81d]140 targets="--with-target-hosts='host:debug'"
[3fc5f010]141 }
142
[93fe3154]143 sh "${SrcDir}/configure CXX=${Settings.Compiler.CXX} CC=${Settings.Compiler.CC} ${Settings.Architecture.flags} ${targets} --quiet"
[e507c11]144 }
145 }
146
147 build_stage('Build : cfa-cpp', true) {
148 // Build outside of the src tree to ease cleaning
149 dir (BuildDir) {
150 // Build driver
151 sh 'make -j 8 --no-print-directory -C driver'
152
153 // Build translator
154 sh 'make -j 8 --no-print-directory -C src'
155 }
156 }
[1752d0e]157
[e507c11]158 build_stage('Build : libcfa(debug)', debug) {
159 // Build outside of the src tree to ease cleaning
160 dir (BuildDir) {
161 sh "make -j 8 --no-print-directory -C libcfa/${Settings.Architecture.name}-debug"
162 }
163 }
164
165 build_stage('Build : libcfa(nodebug)', release) {
166 // Build outside of the src tree to ease cleaning
167 dir (BuildDir) {
168 sh "make -j 8 --no-print-directory -C libcfa/${Settings.Architecture.name}-nodebug"
[50f2cfc]169 }
[620dd2b]170 }
[95fdb0a]171}
[24eecab]172
[95fdb0a]173def test() {
[ab8315f]174 build_stage('Test: short', !Settings.RunAllTests) {
175 dir (BuildDir) {
176 //Run the tests from the tests directory
177 sh 'make --no-print-directory -C tests'
178 }
179 }
[9e5f409]180
[f93f35a]181 build_stage('Test: full', Settings.RunAllTests) {
[5b8413b4]182 dir (BuildDir) {
[0dc3ac3]183 //Run the tests from the tests directory
[05c34c3]184 sh 'make --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=yes'
185 sh 'make --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=no '
[9beae23]186 }
[620dd2b]187 }
[95fdb0a]188}
189
190def benchmark() {
[6c55a3d]191 build_stage('Benchmark', Settings.RunBenchmark) {
[5b8413b4]192 dir (BuildDir) {
[0dc3ac3]193 //Append bench results
[f15fe0a]194 sh "make --no-print-directory -C benchmark jenkins"
[0dc3ac3]195 }
[620dd2b]196 }
[9beae23]197}
[efd60d67]198
[95fdb0a]199def build_doc() {
[6c55a3d]200 build_stage('Documentation', Settings.BuildDocumentation) {
[9beae23]201 dir ('doc/user') {
202 make_doc()
203 }
204
205 dir ('doc/refrat') {
206 make_doc()
207 }
[620dd2b]208 }
[9beae23]209}
210
[95fdb0a]211def publish() {
[6c55a3d]212 build_stage('Publish', true) {
[95fdb0a]213
[1b3eef8]214 if( Settings.Publish && !Settings.RunBenchmark ) { echo 'No results to publish!!!' }
[95fdb0a]215
[3898392]216 def groupCompile = new PlotGroup('Compilation', 'seconds', true)
217 def groupConcurrency = new PlotGroup('Concurrency', 'nanoseconds', false)
[a2a0065]218
[3898392]219 //Then publish the results
[8d63649]220 do_plot(Settings.RunBenchmark && Settings.Publish, 'compile' , groupCompile , 'Compilation')
221 do_plot(Settings.RunBenchmark && Settings.Publish, 'ctxswitch', groupConcurrency, 'Context Switching')
222 do_plot(Settings.RunBenchmark && Settings.Publish, 'mutex' , groupConcurrency, 'Mutual Exclusion')
223 do_plot(Settings.RunBenchmark && Settings.Publish, 'signal' , groupConcurrency, 'Internal and External Scheduling')
[620dd2b]224 }
[95fdb0a]225}
226
[29f4fe62]227//===========================================================================================================
228//Routine responsible of sending the email notification once the build is completed
229//===========================================================================================================
[a336d46]230def GitLogMessage() {
231 if (!Settings || !Settings.GitOldRef || !Settings.GitNewRef) return "\nERROR retrieveing git information!\n"
[e8a22a7]232
[9f5bb817]233 sh "${SrcDir}/tools/PrettyGitLogs.sh ${SrcDir} ${BuildDir} ${Settings.GitOldRef} ${Settings.GitNewRef}"
[6e31c43]234
[eda8175]235 def gitUpdate = readFile("${BuildDir}/GIT_UPDATE")
236 def gitLog = readFile("${BuildDir}/GIT_LOG")
237 def gitDiff = readFile("${BuildDir}/GIT_DIFF")
[7a927ed0]238
[a336d46]239 return """
[13c98a4]240<pre>
[848fb00]241The branch ${env.BRANCH_NAME} has been updated.
[7a927ed0]242${gitUpdate}
[13c98a4]243</pre>
244
245<p>Check console output at ${env.BUILD_URL} to view the results.</p>
[7b1a604]246
[13c98a4]247<p>- Status --------------------------------------------------------------</p>
[7b1a604]248
[13c98a4]249<p>BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}</p>
[7b1a604]250
[13c98a4]251<p>- Log -----------------------------------------------------------------</p>
[e8a22a7]252
[13c98a4]253<pre>
[7a927ed0]254${gitLog}
[13c98a4]255</pre>
256
257<p>-----------------------------------------------------------------------</p>
258<pre>
[7b1a604]259Summary of changes:
[7a927ed0]260${gitDiff}
[13c98a4]261</pre>
[7b1a604]262"""
[a336d46]263}
264
265//Standard build email notification
[13c98a4]266def email(boolean log) {
[a336d46]267 //Since tokenizer doesn't work, figure stuff out from the environnement variables and command line
268 //Configurations for email format
269 echo 'Notifying users of result'
270
271 def project_name = (env.JOB_NAME =~ /(.+)\/.+/)[0][1].toLowerCase()
272 def email_subject = "[${project_name} git][BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}] - branch ${env.BRANCH_NAME}"
[13c98a4]273 def email_body = """<p>This is an automated email from the Jenkins build machine. It was
[a336d46]274generated because of a git hooks/post-receive script following
[986e260]275a ref change which was pushed to the C\u2200 repository.</p>
[a336d46]276""" + GitLogMessage()
[e8a22a7]277
[13c98a4]278 def email_to = !Settings.IsSandbox ? "cforall@lists.uwaterloo.ca" : "tdelisle@uwaterloo.ca"
[e8a22a7]279
[13c98a4]280 if( Settings && !Settings.Silent ) {
[094a42c]281 //send email notification
282 emailext body: email_body, subject: email_subject, to: email_to, attachLog: log
283 } else {
284 echo "Would send email to: ${email_to}"
285 echo "With title: ${email_subject}"
286 echo "Content: \n${email_body}"
287 }
[e8a22a7]288}
[5b8413b4]289
290//===========================================================================================================
291// Helper classes/variables/routines
292//===========================================================================================================
293//Description of a compiler (Must be serializable since pipelines are persistent)
294class CC_Desc implements Serializable {
[93fe3154]295 public String name
296 public String CXX
[6ebc13f]297 public String CC
[93fe3154]298
[6ebc13f]299 CC_Desc(String name, String CXX, String CC) {
[93fe3154]300 this.name = name
301 this.CXX = CXX
[6ebc13f]302 this.CC = CC
[5b8413b4]303 }
304}
305
306//Description of an architecture (Must be serializable since pipelines are persistent)
307class Arch_Desc implements Serializable {
308 public String name
309 public String flags
[5307c33]310 public String node
[5b8413b4]311
[5307c33]312 Arch_Desc(String name, String flags, String node) {
[5b8413b4]313 this.name = name
314 this.flags = flags
[5307c33]315 this.node = node
[5b8413b4]316 }
317}
318
319class BuildSettings implements Serializable {
320 public final CC_Desc Compiler
321 public final Arch_Desc Architecture
322 public final Boolean RunAllTests
323 public final Boolean RunBenchmark
324 public final Boolean BuildDocumentation
325 public final Boolean Publish
326 public final Boolean Silent
327 public final Boolean IsSandbox
328 public final String DescLong
329 public final String DescShort
330
[a336d46]331 public String GitNewRef
332 public String GitOldRef
333
[490cb3c]334 BuildSettings(java.util.Collections$UnmodifiableMap param, String branch) {
[5b8413b4]335 switch( param.Compiler ) {
336 case 'gcc-6':
337 this.Compiler = new CC_Desc('gcc-6', 'g++-6', 'gcc-6')
338 break
339 case 'gcc-5':
340 this.Compiler = new CC_Desc('gcc-5', 'g++-5', 'gcc-5')
341 break
342 case 'gcc-4.9':
343 this.Compiler = new CC_Desc('gcc-4.9', 'g++-4.9', 'gcc-4.9')
344 break
345 case 'clang':
346 this.Compiler = new CC_Desc('clang', 'clang++', 'gcc-6')
347 break
348 default :
349 error "Unhandled compiler : ${cc}"
350 }
351
352 switch( param.Architecture ) {
353 case 'x64':
[a3e8281]354 this.Architecture = new Arch_Desc('x64', '--host=x86_64', 'x64')
[5b8413b4]355 break
356 case 'x86':
[a3e8281]357 this.Architecture = new Arch_Desc('x86', '--host=i386', 'x86')
[5b8413b4]358 break
359 default :
360 error "Unhandled architecture : ${arch}"
361 }
362
[f95e8f0]363 this.IsSandbox = (branch == "jenkins-sandbox")
[5b8413b4]364 this.RunAllTests = param.RunAllTests
[7a230fd]365 this.RunBenchmark = param.RunBenchmark
[5b8413b4]366 this.BuildDocumentation = param.BuildDocumentation
[7a230fd]367 this.Publish = param.Publish
[5b8413b4]368 this.Silent = param.Silent
369
370 def full = param.RunAllTests ? " (Full)" : ""
[490cb3c]371 this.DescShort = "${ this.Compiler.name }:${ this.Architecture.name }${full}"
[5b8413b4]372
[93fe3154]373 this.DescLong = """Compiler : ${ this.Compiler.name } (${ this.Compiler.CXX }/${ this.Compiler.CC })
[5b8413b4]374Architecture : ${ this.Architecture.name }
375Arc Flags : ${ this.Architecture.flags }
376Run All Tests : ${ this.RunAllTests.toString() }
377Run Benchmark : ${ this.RunBenchmark.toString() }
378Build Documentation : ${ this.BuildDocumentation.toString() }
379Publish : ${ this.Publish.toString() }
380Silent : ${ this.Silent.toString() }
381"""
[a336d46]382
383 this.GitNewRef = ''
384 this.GitOldRef = ''
[5b8413b4]385 }
386}
387
[490cb3c]388class PlotGroup implements Serializable {
389 public String name
390 public String unit
391 public boolean log
392
393 PlotGroup(String name, String unit, boolean log) {
394 this.name = name
395 this.unit = unit
396 this.log = log
397 }
398}
399
[5b8413b4]400def prepare_build() {
401 // prepare the properties
402 properties ([ \
403 [$class: 'ParametersDefinitionProperty', \
404 parameterDefinitions: [ \
405 [$class: 'ChoiceParameterDefinition', \
406 description: 'Which compiler to use', \
407 name: 'Compiler', \
408 choices: 'gcc-6\ngcc-5\ngcc-4.9\nclang', \
409 defaultValue: 'gcc-6', \
410 ], \
411 [$class: 'ChoiceParameterDefinition', \
412 description: 'The target architecture', \
413 name: 'Architecture', \
414 choices: 'x64\nx86', \
415 defaultValue: 'x64', \
416 ], \
417 [$class: 'BooleanParameterDefinition', \
418 description: 'If false, only the quick test suite is ran', \
419 name: 'RunAllTests', \
420 defaultValue: false, \
421 ], \
422 [$class: 'BooleanParameterDefinition', \
423 description: 'If true, jenkins also runs benchmarks', \
424 name: 'RunBenchmark', \
425 defaultValue: false, \
426 ], \
427 [$class: 'BooleanParameterDefinition', \
428 description: 'If true, jenkins also builds documentation', \
429 name: 'BuildDocumentation', \
430 defaultValue: true, \
431 ], \
432 [$class: 'BooleanParameterDefinition', \
433 description: 'If true, jenkins also publishes results', \
434 name: 'Publish', \
435 defaultValue: false, \
436 ], \
437 [$class: 'BooleanParameterDefinition', \
438 description: 'If true, jenkins will not send emails', \
439 name: 'Silent', \
440 defaultValue: false, \
441 ], \
442 ],
443 ]])
444
[4c55047]445 // It's unfortunate but it looks like we need to checkout the entire repo just to get the pretty git printer
446 checkout scm
[2407853]447
[490cb3c]448 final settings = new BuildSettings(params, env.BRANCH_NAME)
[5b8413b4]449
450 currentBuild.description = settings.DescShort
451 echo settings.DescLong
452
453 return settings
454}
455
[6c55a3d]456def build_stage(String name, boolean run, Closure block ) {
[5b8413b4]457 StageName = name
458 echo " -------- ${StageName} -------- "
[8ecb590]459 if(run) {
460 stage(name, block)
461 } else {
462 stage(name) { Utils.markStageSkippedForConditional(STAGE_NAME) }
463 }
[5b8413b4]464}
465
466def make_doc() {
467 def err = null
468 try {
469 sh 'make clean > /dev/null'
470 sh 'make > /dev/null 2>&1'
471 }
472 catch (Exception caughtError) {
473 err = caughtError //rethrow error later
[65f4a51]474 sh 'cat build/*.log'
[5b8413b4]475 }
476 finally {
477 if (err) throw err // Must re-throw exception to propagate error
478 }
[a2a0065]479}
480
[1b3eef8]481def do_plot(boolean new_data, String file, PlotGroup group, String title) {
[8d63649]482
[1b3eef8]483 if(new_data) {
484 echo "Publishing new data"
485 }
486
[cdcd53dc]487 def series = new_data ? [[
[df57a84]488 file: "${file}.csv",
[3c40dc2a]489 exclusionValues: '',
490 displayTableFlag: false,
491 inclusionFlag: 'OFF',
492 url: ''
[cdcd53dc]493 ]] : [];
[8d63649]494
495 echo "file is ${BuildDir}/benchmark/${file}.csv, group ${group}, title ${title}"
496 dir("${BuildDir}/benchmark/") {
497 plot csvFileName: "cforall-${env.BRANCH_NAME}-${file}.csv",
498 csvSeries: series,
[490cb3c]499 group: "${group.name}",
[3c40dc2a]500 title: "${title}",
501 style: 'lineSimple',
502 exclZero: false,
503 keepRecords: false,
[490cb3c]504 logarithmic: group.log,
[3c40dc2a]505 numBuilds: '120',
506 useDescr: true,
[490cb3c]507 yaxis: group.unit,
[3c40dc2a]508 yaxisMaximum: '',
509 yaxisMinimum: ''
[df57a84]510 }
511}
Note: See TracBrowser for help on using the repository browser.