source: Jenkinsfile@ 6badd87

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 6badd87 was 6badd87, checked in by Thierry Delisle <tdelisle@…>, 6 years ago

Testing calls to git from Jenkinsfile rather than PrettyGitLog.sh, in an effort to not run inside a node

  • Property mode set to 100644
File size: 15.1 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
[6badd87]229 // sh "${SrcDir}/tools/PrettyGitLogs.sh ${SrcDir} ${BuildDir} ${Settings.GitOldRef} ${Settings.GitNewRef}"
230
231 def result = sh(returnStdout: true, script: "git rev-list ${Settings.GitOldRef}..${Settings.GitNewRef}")
232 echo result
[6e31c43]233
[eda8175]234 def gitUpdate = readFile("${BuildDir}/GIT_UPDATE")
[6badd87]235 def gitLog = sh(returnStdout: true, script: "git rev-list --format=short ${Settings.GitOldRef}...${Settings.GitNewRef}")
[eda8175]236 def gitDiff = readFile("${BuildDir}/GIT_DIFF")
[7a927ed0]237
[a336d46]238 return """
[13c98a4]239<pre>
[848fb00]240The branch ${env.BRANCH_NAME} has been updated.
[7a927ed0]241${gitUpdate}
[13c98a4]242</pre>
243
244<p>Check console output at ${env.BUILD_URL} to view the results.</p>
[7b1a604]245
[13c98a4]246<p>- Status --------------------------------------------------------------</p>
[7b1a604]247
[13c98a4]248<p>BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}</p>
[7b1a604]249
[13c98a4]250<p>- Log -----------------------------------------------------------------</p>
[e8a22a7]251
[13c98a4]252<pre>
[7a927ed0]253${gitLog}
[13c98a4]254</pre>
255
256<p>-----------------------------------------------------------------------</p>
257<pre>
[7b1a604]258Summary of changes:
[7a927ed0]259${gitDiff}
[13c98a4]260</pre>
[7b1a604]261"""
[a336d46]262}
263
264//Standard build email notification
[13c98a4]265def email(boolean log) {
[a336d46]266 //Since tokenizer doesn't work, figure stuff out from the environnement variables and command line
267 //Configurations for email format
268 echo 'Notifying users of result'
269
270 def project_name = (env.JOB_NAME =~ /(.+)\/.+/)[0][1].toLowerCase()
271 def email_subject = "[${project_name} git][BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}] - branch ${env.BRANCH_NAME}"
[13c98a4]272 def email_body = """<p>This is an automated email from the Jenkins build machine. It was
[a336d46]273generated because of a git hooks/post-receive script following
[986e260]274a ref change which was pushed to the C\u2200 repository.</p>
[a336d46]275""" + GitLogMessage()
[e8a22a7]276
[13c98a4]277 def email_to = !Settings.IsSandbox ? "cforall@lists.uwaterloo.ca" : "tdelisle@uwaterloo.ca"
[e8a22a7]278
[13c98a4]279 if( Settings && !Settings.Silent ) {
[094a42c]280 //send email notification
281 emailext body: email_body, subject: email_subject, to: email_to, attachLog: log
282 } else {
283 echo "Would send email to: ${email_to}"
284 echo "With title: ${email_subject}"
285 echo "Content: \n${email_body}"
286 }
[e8a22a7]287}
[5b8413b4]288
289//===========================================================================================================
290// Helper classes/variables/routines
291//===========================================================================================================
292//Description of a compiler (Must be serializable since pipelines are persistent)
293class CC_Desc implements Serializable {
[93fe3154]294 public String name
295 public String CXX
[6ebc13f]296 public String CC
[93fe3154]297
[6ebc13f]298 CC_Desc(String name, String CXX, String CC) {
[93fe3154]299 this.name = name
300 this.CXX = CXX
[6ebc13f]301 this.CC = CC
[5b8413b4]302 }
303}
304
305//Description of an architecture (Must be serializable since pipelines are persistent)
306class Arch_Desc implements Serializable {
307 public String name
308 public String flags
[5307c33]309 public String node
[5b8413b4]310
[5307c33]311 Arch_Desc(String name, String flags, String node) {
[5b8413b4]312 this.name = name
313 this.flags = flags
[5307c33]314 this.node = node
[5b8413b4]315 }
316}
317
318class BuildSettings implements Serializable {
319 public final CC_Desc Compiler
320 public final Arch_Desc Architecture
321 public final Boolean RunAllTests
322 public final Boolean RunBenchmark
323 public final Boolean BuildDocumentation
324 public final Boolean Publish
325 public final Boolean Silent
326 public final Boolean IsSandbox
327 public final String DescLong
328 public final String DescShort
329
[a336d46]330 public String GitNewRef
331 public String GitOldRef
332
[490cb3c]333 BuildSettings(java.util.Collections$UnmodifiableMap param, String branch) {
[5b8413b4]334 switch( param.Compiler ) {
335 case 'gcc-6':
336 this.Compiler = new CC_Desc('gcc-6', 'g++-6', 'gcc-6')
337 break
338 case 'gcc-5':
339 this.Compiler = new CC_Desc('gcc-5', 'g++-5', 'gcc-5')
340 break
341 case 'gcc-4.9':
342 this.Compiler = new CC_Desc('gcc-4.9', 'g++-4.9', 'gcc-4.9')
343 break
344 case 'clang':
345 this.Compiler = new CC_Desc('clang', 'clang++', 'gcc-6')
346 break
347 default :
348 error "Unhandled compiler : ${cc}"
349 }
350
351 switch( param.Architecture ) {
352 case 'x64':
[a3e8281]353 this.Architecture = new Arch_Desc('x64', '--host=x86_64', 'x64')
[5b8413b4]354 break
355 case 'x86':
[a3e8281]356 this.Architecture = new Arch_Desc('x86', '--host=i386', 'x86')
[5b8413b4]357 break
358 default :
359 error "Unhandled architecture : ${arch}"
360 }
361
[f95e8f0]362 this.IsSandbox = (branch == "jenkins-sandbox")
[5b8413b4]363 this.RunAllTests = param.RunAllTests
[7a230fd]364 this.RunBenchmark = param.RunBenchmark
[5b8413b4]365 this.BuildDocumentation = param.BuildDocumentation
[7a230fd]366 this.Publish = param.Publish
[5b8413b4]367 this.Silent = param.Silent
368
369 def full = param.RunAllTests ? " (Full)" : ""
[490cb3c]370 this.DescShort = "${ this.Compiler.name }:${ this.Architecture.name }${full}"
[5b8413b4]371
[93fe3154]372 this.DescLong = """Compiler : ${ this.Compiler.name } (${ this.Compiler.CXX }/${ this.Compiler.CC })
[5b8413b4]373Architecture : ${ this.Architecture.name }
374Arc Flags : ${ this.Architecture.flags }
375Run All Tests : ${ this.RunAllTests.toString() }
376Run Benchmark : ${ this.RunBenchmark.toString() }
377Build Documentation : ${ this.BuildDocumentation.toString() }
378Publish : ${ this.Publish.toString() }
379Silent : ${ this.Silent.toString() }
380"""
[a336d46]381
382 this.GitNewRef = ''
383 this.GitOldRef = ''
[5b8413b4]384 }
385}
386
[490cb3c]387class PlotGroup implements Serializable {
388 public String name
389 public String unit
390 public boolean log
391
392 PlotGroup(String name, String unit, boolean log) {
393 this.name = name
394 this.unit = unit
395 this.log = log
396 }
397}
398
[5b8413b4]399def prepare_build() {
400 // prepare the properties
401 properties ([ \
402 [$class: 'ParametersDefinitionProperty', \
403 parameterDefinitions: [ \
404 [$class: 'ChoiceParameterDefinition', \
405 description: 'Which compiler to use', \
406 name: 'Compiler', \
407 choices: 'gcc-6\ngcc-5\ngcc-4.9\nclang', \
408 defaultValue: 'gcc-6', \
409 ], \
410 [$class: 'ChoiceParameterDefinition', \
411 description: 'The target architecture', \
412 name: 'Architecture', \
413 choices: 'x64\nx86', \
414 defaultValue: 'x64', \
415 ], \
416 [$class: 'BooleanParameterDefinition', \
417 description: 'If false, only the quick test suite is ran', \
418 name: 'RunAllTests', \
419 defaultValue: false, \
420 ], \
421 [$class: 'BooleanParameterDefinition', \
422 description: 'If true, jenkins also runs benchmarks', \
423 name: 'RunBenchmark', \
424 defaultValue: false, \
425 ], \
426 [$class: 'BooleanParameterDefinition', \
427 description: 'If true, jenkins also builds documentation', \
428 name: 'BuildDocumentation', \
429 defaultValue: true, \
430 ], \
431 [$class: 'BooleanParameterDefinition', \
432 description: 'If true, jenkins also publishes results', \
433 name: 'Publish', \
434 defaultValue: false, \
435 ], \
436 [$class: 'BooleanParameterDefinition', \
437 description: 'If true, jenkins will not send emails', \
438 name: 'Silent', \
439 defaultValue: false, \
440 ], \
441 ],
442 ]])
443
[4c55047]444 // It's unfortunate but it looks like we need to checkout the entire repo just to get the pretty git printer
445 checkout scm
[2407853]446
[490cb3c]447 final settings = new BuildSettings(params, env.BRANCH_NAME)
[5b8413b4]448
449 currentBuild.description = settings.DescShort
450 echo settings.DescLong
451
452 return settings
453}
454
[6c55a3d]455def build_stage(String name, boolean run, Closure block ) {
[5b8413b4]456 StageName = name
457 echo " -------- ${StageName} -------- "
[8ecb590]458 if(run) {
459 stage(name, block)
460 } else {
461 stage(name) { Utils.markStageSkippedForConditional(STAGE_NAME) }
462 }
[5b8413b4]463}
464
465def make_doc() {
466 def err = null
467 try {
468 sh 'make clean > /dev/null'
469 sh 'make > /dev/null 2>&1'
470 }
471 catch (Exception caughtError) {
472 err = caughtError //rethrow error later
[65f4a51]473 sh 'cat build/*.log'
[5b8413b4]474 }
475 finally {
476 if (err) throw err // Must re-throw exception to propagate error
477 }
[a2a0065]478}
479
[3221a2b]480def do_plot(boolean new_data, String file, PlotGroup group, boolean relative, String title) {
[8d63649]481
[1b3eef8]482 if(new_data) {
483 echo "Publishing new data"
484 }
485
[cdcd53dc]486 def series = new_data ? [[
[df57a84]487 file: "${file}.csv",
[3c40dc2a]488 exclusionValues: '',
489 displayTableFlag: false,
490 inclusionFlag: 'OFF',
491 url: ''
[cdcd53dc]492 ]] : [];
[8d63649]493
494 echo "file is ${BuildDir}/benchmark/${file}.csv, group ${group}, title ${title}"
495 dir("${BuildDir}/benchmark/") {
496 plot csvFileName: "cforall-${env.BRANCH_NAME}-${file}.csv",
497 csvSeries: series,
[490cb3c]498 group: "${group.name}",
[3c40dc2a]499 title: "${title}",
500 style: 'lineSimple',
501 exclZero: false,
502 keepRecords: false,
[3221a2b]503 logarithmic: !relative && group.log,
[3c40dc2a]504 numBuilds: '120',
505 useDescr: true,
[490cb3c]506 yaxis: group.unit,
[3c40dc2a]507 yaxisMaximum: '',
508 yaxisMinimum: ''
[df57a84]509 }
510}
Note: See TracBrowser for help on using the repository browser.