source: Jenkinsfile@ 7a230fd

ADT arm-eh ast-experimental cleanup-dtors 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 7a230fd was 7a230fd, checked in by Thierry Delisle <tdelisle@…>, 7 years ago

Tentative fix for global variable usage

  • Property mode set to 100644
File size: 12.6 KB
RevLine 
[a63ad80]1#!groovy
2
[7a230fd]3import groovy.transform.Field
4
[29f4fe62]5//===========================================================================================================
[9beae23]6// Main loop of the compilation
[29f4fe62]7//===========================================================================================================
[56a9ce6]8
[5307c33]9node('master') {
[5b8413b4]10 // Globals
[4c55047]11 BuildDir = pwd tmp: true
12 SrcDir = pwd tmp: false
[5b8413b4]13 Settings = null
14 StageName = ''
15
16 // Local variables
[9beae23]17 def err = null
18 def log_needed = false
[0ef06b6]19
20 currentBuild.result = "SUCCESS"
21
[9beae23]22 try {
[95fdb0a]23 //Wrap build to add timestamp to command line
24 wrap([$class: 'TimestamperBuildWrapper']) {
[23a14d86]25
[c431138]26 Settings = prepare_build()
[7aebc62]27
[5307c33]28 node(Settings.Architecture.node) {
[bf9d323]29 BuildDir = pwd tmp: true
30 SrcDir = pwd tmp: false
31
[5307c33]32 clean()
[0dc3ac3]33
[5307c33]34 checkout()
[fde808df]35
[5307c33]36 build()
[95fdb0a]37
[5307c33]38 test()
[95fdb0a]39
[5307c33]40 benchmark()
[95fdb0a]41
[5307c33]42 build_doc()
[7359098]43
[5307c33]44 publish()
45 }
[9beae23]46
[4c55047]47 // Update the build directories when exiting the node
48 BuildDir = pwd tmp: true
49 SrcDir = pwd tmp: false
[9beae23]50 }
[738cf8f]51 }
52
[9beae23]53 //If an exception is caught we need to change the status and remember to
54 //attach the build log to the email
[738cf8f]55 catch (Exception caughtError) {
56 //rethrow error later
57 err = caughtError
58
[e966ec0]59 echo err.toString()
60
[9beae23]61 //An error has occured, the build log is relevent
62 log_needed = true
63
64 //Store the result of the build log
[5b8413b4]65 currentBuild.result = "${StageName} FAILURE".trim()
[738cf8f]66 }
67
68 finally {
[9beae23]69 //Send email with final results if this is not a full build
[13c98a4]70 email(log_needed)
[9beae23]71
[734891d]72 echo 'Build Completed'
73
[738cf8f]74 /* Must re-throw exception to propagate error */
75 if (err) {
76 throw err
77 }
78 }
79}
[29f4fe62]80//===========================================================================================================
[9beae23]81// Main compilation routines
[29f4fe62]82//===========================================================================================================
[0dc3ac3]83def clean() {
84 build_stage('Cleanup') {
85 // clean the build by wipping the build directory
[5b8413b4]86 dir(BuildDir) {
[d4cd491]87 deleteDir()
[ece8a80]88 }
[620dd2b]89 }
[95fdb0a]90}
[29f4fe62]91
[0dc3ac3]92//Compilation script is done here but environnement set-up and error handling is done in main loop
93def checkout() {
94 build_stage('Checkout') {
95 //checkout the source code and clean the repo
[a336d46]96 final scmVars = checkout scm
97 Settings.GitNewRef = scmVars.GIT_COMMIT
98 Settings.GitOldRef = scmVars.GIT_PREVIOUS_COMMIT
[d3a4564a]99
[a336d46]100 echo GitLogMessage()
[0dc3ac3]101 }
102}
103
[95fdb0a]104def build() {
[620dd2b]105 build_stage('Build') {
[50f2cfc]106 // Build outside of the src tree to ease cleaning
[5b8413b4]107 dir (BuildDir) {
[50f2cfc]108 //Configure the conpilation (Output is not relevant)
109 //Use the current directory as the installation target so nothing escapes the sandbox
110 //Also specify the compiler by hand
[3fc5f010]111 targets=""
[d4510ea]112 if( Settings.RunAllTests || Settings.RunBenchmark ) {
[6bde81d]113 targets="--with-target-hosts='host:debug,host:nodebug'"
[3fc5f010]114 } else {
[6bde81d]115 targets="--with-target-hosts='host:debug'"
[3fc5f010]116 }
117
[93fe3154]118 sh "${SrcDir}/configure CXX=${Settings.Compiler.CXX} CC=${Settings.Compiler.CC} ${Settings.Architecture.flags} ${targets} --quiet"
[1752d0e]119
[50f2cfc]120 //Compile the project
121 sh 'make -j 8 --no-print-directory'
122 }
[620dd2b]123 }
[95fdb0a]124}
[24eecab]125
[95fdb0a]126def test() {
[620dd2b]127 build_stage('Test') {
[9e5f409]128
[5b8413b4]129 dir (BuildDir) {
[0dc3ac3]130 //Run the tests from the tests directory
[5afeab9]131 if ( Settings.RunAllTests ) {
[b90aace]132 sh 'make --no-print-directory -C tests timeouts="--timeout=600" all-tests debug=yes'
133 sh 'make --no-print-directory -C tests timeouts="--timeout=600" all-tests debug=no '
[0dc3ac3]134 }
135 else {
[7428ad9]136 sh 'make --no-print-directory -C tests'
[0dc3ac3]137 }
[9beae23]138 }
[620dd2b]139 }
[95fdb0a]140}
141
142def benchmark() {
[620dd2b]143 build_stage('Benchmark') {
[29f4fe62]144
[5afeab9]145 if( !Settings.RunBenchmark ) return
[ae28ee2]146
[5b8413b4]147 dir (BuildDir) {
[0dc3ac3]148 //Append bench results
[f15fe0a]149 sh "make --no-print-directory -C benchmark jenkins"
[0dc3ac3]150 }
[620dd2b]151 }
[9beae23]152}
[efd60d67]153
[95fdb0a]154def build_doc() {
[620dd2b]155 build_stage('Documentation') {
[9beae23]156
[5afeab9]157 if( !Settings.BuildDocumentation ) return
[9beae23]158
159 dir ('doc/user') {
160 make_doc()
161 }
162
163 dir ('doc/refrat') {
164 make_doc()
165 }
[620dd2b]166 }
[9beae23]167}
168
[7a230fd]169@Field PlotGroup CompileGroup = new PlotGroup('Compilation', 'seconds', true)
170@Field PlotGroup ConcurrencyGroup = new PlotGroup('Concurrency', 'nanoseconds', false)
[490cb3c]171
[95fdb0a]172def publish() {
[620dd2b]173 build_stage('Publish') {
[95fdb0a]174
[5afeab9]175 if( !Settings.Publish ) return
[f15fe0a]176 if( !Settings.RunBenchmark ) {
177 echo 'No results to publish!!!'
178 return
179 }
[95fdb0a]180
181 //Then publish the results
[490cb3c]182 do_plot('compile', CompilationGroup, 'Compilation')
[a2a0065]183
[490cb3c]184 do_plot('ctxswitch', ConcurrencyGroup, 'Context Switching')
[a2a0065]185
[490cb3c]186 do_plot('mutex', ConcurrencyGroup, 'Mutual Exclusion')
[a2a0065]187
[490cb3c]188 do_plot('signal', ConcurrencyGroup, 'Internal and External Scheduling')
[620dd2b]189 }
[95fdb0a]190}
191
[29f4fe62]192//===========================================================================================================
193//Routine responsible of sending the email notification once the build is completed
194//===========================================================================================================
[a336d46]195def GitLogMessage() {
196 if (!Settings || !Settings.GitOldRef || !Settings.GitNewRef) return "\nERROR retrieveing git information!\n"
[e8a22a7]197
[9f5bb817]198 sh "${SrcDir}/tools/PrettyGitLogs.sh ${SrcDir} ${BuildDir} ${Settings.GitOldRef} ${Settings.GitNewRef}"
[6e31c43]199
[eda8175]200 def gitUpdate = readFile("${BuildDir}/GIT_UPDATE")
201 def gitLog = readFile("${BuildDir}/GIT_LOG")
202 def gitDiff = readFile("${BuildDir}/GIT_DIFF")
[7a927ed0]203
[a336d46]204 return """
[13c98a4]205<pre>
[848fb00]206The branch ${env.BRANCH_NAME} has been updated.
[7a927ed0]207${gitUpdate}
[13c98a4]208</pre>
209
210<p>Check console output at ${env.BUILD_URL} to view the results.</p>
[7b1a604]211
[13c98a4]212<p>- Status --------------------------------------------------------------</p>
[7b1a604]213
[13c98a4]214<p>BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}</p>
[7b1a604]215
[13c98a4]216<p>- Log -----------------------------------------------------------------</p>
[e8a22a7]217
[13c98a4]218<pre>
[7a927ed0]219${gitLog}
[13c98a4]220</pre>
221
222<p>-----------------------------------------------------------------------</p>
223<pre>
[7b1a604]224Summary of changes:
[7a927ed0]225${gitDiff}
[13c98a4]226</pre>
[7b1a604]227"""
[a336d46]228}
229
230//Standard build email notification
[13c98a4]231def email(boolean log) {
[a336d46]232 //Since tokenizer doesn't work, figure stuff out from the environnement variables and command line
233 //Configurations for email format
234 echo 'Notifying users of result'
235
236 def project_name = (env.JOB_NAME =~ /(.+)\/.+/)[0][1].toLowerCase()
237 def email_subject = "[${project_name} git][BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}] - branch ${env.BRANCH_NAME}"
[13c98a4]238 def email_body = """<p>This is an automated email from the Jenkins build machine. It was
[a336d46]239generated because of a git hooks/post-receive script following
[13c98a4]240a ref change which was pushed to the C∀ repository.</p>
[a336d46]241""" + GitLogMessage()
[e8a22a7]242
[13c98a4]243 def email_to = !Settings.IsSandbox ? "cforall@lists.uwaterloo.ca" : "tdelisle@uwaterloo.ca"
[e8a22a7]244
[13c98a4]245 if( Settings && !Settings.Silent ) {
[094a42c]246 //send email notification
247 emailext body: email_body, subject: email_subject, to: email_to, attachLog: log
248 } else {
249 echo "Would send email to: ${email_to}"
250 echo "With title: ${email_subject}"
251 echo "Content: \n${email_body}"
252 }
[e8a22a7]253}
[5b8413b4]254
255//===========================================================================================================
256// Helper classes/variables/routines
257//===========================================================================================================
258//Description of a compiler (Must be serializable since pipelines are persistent)
259class CC_Desc implements Serializable {
[93fe3154]260 public String name
261 public String CXX
[6ebc13f]262 public String CC
[93fe3154]263
[6ebc13f]264 CC_Desc(String name, String CXX, String CC) {
[93fe3154]265 this.name = name
266 this.CXX = CXX
[6ebc13f]267 this.CC = CC
[5b8413b4]268 }
269}
270
271//Description of an architecture (Must be serializable since pipelines are persistent)
272class Arch_Desc implements Serializable {
273 public String name
274 public String flags
[5307c33]275 public String node
[5b8413b4]276
[5307c33]277 Arch_Desc(String name, String flags, String node) {
[5b8413b4]278 this.name = name
279 this.flags = flags
[5307c33]280 this.node = node
[5b8413b4]281 }
282}
283
284class BuildSettings implements Serializable {
285 public final CC_Desc Compiler
286 public final Arch_Desc Architecture
287 public final Boolean RunAllTests
288 public final Boolean RunBenchmark
289 public final Boolean BuildDocumentation
290 public final Boolean Publish
291 public final Boolean Silent
292 public final Boolean IsSandbox
293 public final String DescLong
294 public final String DescShort
295
[a336d46]296 public String GitNewRef
297 public String GitOldRef
298
[490cb3c]299 BuildSettings(java.util.Collections$UnmodifiableMap param, String branch) {
[5b8413b4]300 switch( param.Compiler ) {
301 case 'gcc-6':
302 this.Compiler = new CC_Desc('gcc-6', 'g++-6', 'gcc-6')
303 break
304 case 'gcc-5':
305 this.Compiler = new CC_Desc('gcc-5', 'g++-5', 'gcc-5')
306 break
307 case 'gcc-4.9':
308 this.Compiler = new CC_Desc('gcc-4.9', 'g++-4.9', 'gcc-4.9')
309 break
310 case 'clang':
311 this.Compiler = new CC_Desc('clang', 'clang++', 'gcc-6')
312 break
313 default :
314 error "Unhandled compiler : ${cc}"
315 }
316
317 switch( param.Architecture ) {
318 case 'x64':
[a3e8281]319 this.Architecture = new Arch_Desc('x64', '--host=x86_64', 'x64')
[5b8413b4]320 break
321 case 'x86':
[a3e8281]322 this.Architecture = new Arch_Desc('x86', '--host=i386', 'x86')
[5b8413b4]323 break
324 default :
325 error "Unhandled architecture : ${arch}"
326 }
327
[f95e8f0]328 this.IsSandbox = (branch == "jenkins-sandbox")
[5b8413b4]329 this.RunAllTests = param.RunAllTests
[7a230fd]330 this.RunBenchmark = param.RunBenchmark
[5b8413b4]331 this.BuildDocumentation = param.BuildDocumentation
[7a230fd]332 this.Publish = param.Publish
[5b8413b4]333 this.Silent = param.Silent
334
335 def full = param.RunAllTests ? " (Full)" : ""
[490cb3c]336 this.DescShort = "${ this.Compiler.name }:${ this.Architecture.name }${full}"
[5b8413b4]337
[93fe3154]338 this.DescLong = """Compiler : ${ this.Compiler.name } (${ this.Compiler.CXX }/${ this.Compiler.CC })
[5b8413b4]339Architecture : ${ this.Architecture.name }
340Arc Flags : ${ this.Architecture.flags }
341Run All Tests : ${ this.RunAllTests.toString() }
342Run Benchmark : ${ this.RunBenchmark.toString() }
343Build Documentation : ${ this.BuildDocumentation.toString() }
344Publish : ${ this.Publish.toString() }
345Silent : ${ this.Silent.toString() }
346"""
[a336d46]347
348 this.GitNewRef = ''
349 this.GitOldRef = ''
[5b8413b4]350 }
351}
352
[490cb3c]353class PlotGroup implements Serializable {
354 public String name
355 public String unit
356 public boolean log
357
358 PlotGroup(String name, String unit, boolean log) {
359 this.name = name
360 this.unit = unit
361 this.log = log
362 }
363}
364
[5b8413b4]365def prepare_build() {
366 // prepare the properties
367 properties ([ \
368 [$class: 'ParametersDefinitionProperty', \
369 parameterDefinitions: [ \
370 [$class: 'ChoiceParameterDefinition', \
371 description: 'Which compiler to use', \
372 name: 'Compiler', \
373 choices: 'gcc-6\ngcc-5\ngcc-4.9\nclang', \
374 defaultValue: 'gcc-6', \
375 ], \
376 [$class: 'ChoiceParameterDefinition', \
377 description: 'The target architecture', \
378 name: 'Architecture', \
379 choices: 'x64\nx86', \
380 defaultValue: 'x64', \
381 ], \
382 [$class: 'BooleanParameterDefinition', \
383 description: 'If false, only the quick test suite is ran', \
384 name: 'RunAllTests', \
385 defaultValue: false, \
386 ], \
387 [$class: 'BooleanParameterDefinition', \
388 description: 'If true, jenkins also runs benchmarks', \
389 name: 'RunBenchmark', \
390 defaultValue: false, \
391 ], \
392 [$class: 'BooleanParameterDefinition', \
393 description: 'If true, jenkins also builds documentation', \
394 name: 'BuildDocumentation', \
395 defaultValue: true, \
396 ], \
397 [$class: 'BooleanParameterDefinition', \
398 description: 'If true, jenkins also publishes results', \
399 name: 'Publish', \
400 defaultValue: false, \
401 ], \
402 [$class: 'BooleanParameterDefinition', \
403 description: 'If true, jenkins will not send emails', \
404 name: 'Silent', \
405 defaultValue: false, \
406 ], \
407 ],
408 ]])
409
[4c55047]410 // It's unfortunate but it looks like we need to checkout the entire repo just to get the pretty git printer
411 checkout scm
[2407853]412
[490cb3c]413 final settings = new BuildSettings(params, env.BRANCH_NAME)
[5b8413b4]414
415 currentBuild.description = settings.DescShort
416 echo settings.DescLong
417
418 return settings
419}
420
421def build_stage(String name, Closure block ) {
422 StageName = name
423 echo " -------- ${StageName} -------- "
[939fd39]424 stage(name, block)
[5b8413b4]425}
426
427def make_doc() {
428 def err = null
429 try {
430 sh 'make clean > /dev/null'
431 sh 'make > /dev/null 2>&1'
432 }
433 catch (Exception caughtError) {
434 err = caughtError //rethrow error later
[65f4a51]435 sh 'cat build/*.log'
[5b8413b4]436 }
437 finally {
438 if (err) throw err // Must re-throw exception to propagate error
439 }
[a2a0065]440}
441
[490cb3c]442def do_plot(String file, PlotGroup group, String title) {
[df57a84]443 echo "file is ${BuildDir}/benchmark/${file}.csv, group ${group}, title ${title}"
444 dir("${BuildDir}/benchmark/") {
[3c40dc2a]445 plot csvFileName: "cforall-${env.BRANCH_NAME}-${file}.csv",
446 csvSeries: [[
[df57a84]447 file: "${file}.csv",
[3c40dc2a]448 exclusionValues: '',
449 displayTableFlag: false,
450 inclusionFlag: 'OFF',
451 url: ''
452 ]],
[490cb3c]453 group: "${group.name}",
[3c40dc2a]454 title: "${title}",
455 style: 'lineSimple',
456 exclZero: false,
457 keepRecords: false,
[490cb3c]458 logarithmic: group.log,
[3c40dc2a]459 numBuilds: '120',
460 useDescr: true,
[490cb3c]461 yaxis: group.unit,
[3c40dc2a]462 yaxisMaximum: '',
463 yaxisMinimum: ''
[df57a84]464 }
465}
Note: See TracBrowser for help on using the repository browser.