source: Jenkinsfile@ 36354b1

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
Last change on this file since 36354b1 was 1b3eef8, checked in by Thierry Delisle <tdelisle@…>, 6 years ago

Fixed some mistakes into which builds are published

  • Property mode set to 100644
File size: 12.9 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
[95fdb0a]169def publish() {
[620dd2b]170 build_stage('Publish') {
[95fdb0a]171
[1b3eef8]172 if( Settings.Publish && !Settings.RunBenchmark ) { echo 'No results to publish!!!' }
[95fdb0a]173
[3898392]174 def groupCompile = new PlotGroup('Compilation', 'seconds', true)
175 def groupConcurrency = new PlotGroup('Concurrency', 'nanoseconds', false)
[a2a0065]176
[3898392]177 //Then publish the results
[8d63649]178 do_plot(Settings.RunBenchmark && Settings.Publish, 'compile' , groupCompile , 'Compilation')
179 do_plot(Settings.RunBenchmark && Settings.Publish, 'ctxswitch', groupConcurrency, 'Context Switching')
180 do_plot(Settings.RunBenchmark && Settings.Publish, 'mutex' , groupConcurrency, 'Mutual Exclusion')
181 do_plot(Settings.RunBenchmark && Settings.Publish, 'signal' , groupConcurrency, 'Internal and External Scheduling')
[620dd2b]182 }
[95fdb0a]183}
184
[29f4fe62]185//===========================================================================================================
186//Routine responsible of sending the email notification once the build is completed
187//===========================================================================================================
[a336d46]188def GitLogMessage() {
189 if (!Settings || !Settings.GitOldRef || !Settings.GitNewRef) return "\nERROR retrieveing git information!\n"
[e8a22a7]190
[9f5bb817]191 sh "${SrcDir}/tools/PrettyGitLogs.sh ${SrcDir} ${BuildDir} ${Settings.GitOldRef} ${Settings.GitNewRef}"
[6e31c43]192
[eda8175]193 def gitUpdate = readFile("${BuildDir}/GIT_UPDATE")
194 def gitLog = readFile("${BuildDir}/GIT_LOG")
195 def gitDiff = readFile("${BuildDir}/GIT_DIFF")
[7a927ed0]196
[a336d46]197 return """
[13c98a4]198<pre>
[848fb00]199The branch ${env.BRANCH_NAME} has been updated.
[7a927ed0]200${gitUpdate}
[13c98a4]201</pre>
202
203<p>Check console output at ${env.BUILD_URL} to view the results.</p>
[7b1a604]204
[13c98a4]205<p>- Status --------------------------------------------------------------</p>
[7b1a604]206
[13c98a4]207<p>BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}</p>
[7b1a604]208
[13c98a4]209<p>- Log -----------------------------------------------------------------</p>
[e8a22a7]210
[13c98a4]211<pre>
[7a927ed0]212${gitLog}
[13c98a4]213</pre>
214
215<p>-----------------------------------------------------------------------</p>
216<pre>
[7b1a604]217Summary of changes:
[7a927ed0]218${gitDiff}
[13c98a4]219</pre>
[7b1a604]220"""
[a336d46]221}
222
223//Standard build email notification
[13c98a4]224def email(boolean log) {
[a336d46]225 //Since tokenizer doesn't work, figure stuff out from the environnement variables and command line
226 //Configurations for email format
227 echo 'Notifying users of result'
228
229 def project_name = (env.JOB_NAME =~ /(.+)\/.+/)[0][1].toLowerCase()
230 def email_subject = "[${project_name} git][BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}] - branch ${env.BRANCH_NAME}"
[13c98a4]231 def email_body = """<p>This is an automated email from the Jenkins build machine. It was
[a336d46]232generated because of a git hooks/post-receive script following
[986e260]233a ref change which was pushed to the C\u2200 repository.</p>
[a336d46]234""" + GitLogMessage()
[e8a22a7]235
[13c98a4]236 def email_to = !Settings.IsSandbox ? "cforall@lists.uwaterloo.ca" : "tdelisle@uwaterloo.ca"
[e8a22a7]237
[13c98a4]238 if( Settings && !Settings.Silent ) {
[094a42c]239 //send email notification
240 emailext body: email_body, subject: email_subject, to: email_to, attachLog: log
241 } else {
242 echo "Would send email to: ${email_to}"
243 echo "With title: ${email_subject}"
244 echo "Content: \n${email_body}"
245 }
[e8a22a7]246}
[5b8413b4]247
248//===========================================================================================================
249// Helper classes/variables/routines
250//===========================================================================================================
251//Description of a compiler (Must be serializable since pipelines are persistent)
252class CC_Desc implements Serializable {
[93fe3154]253 public String name
254 public String CXX
[6ebc13f]255 public String CC
[93fe3154]256
[6ebc13f]257 CC_Desc(String name, String CXX, String CC) {
[93fe3154]258 this.name = name
259 this.CXX = CXX
[6ebc13f]260 this.CC = CC
[5b8413b4]261 }
262}
263
264//Description of an architecture (Must be serializable since pipelines are persistent)
265class Arch_Desc implements Serializable {
266 public String name
267 public String flags
[5307c33]268 public String node
[5b8413b4]269
[5307c33]270 Arch_Desc(String name, String flags, String node) {
[5b8413b4]271 this.name = name
272 this.flags = flags
[5307c33]273 this.node = node
[5b8413b4]274 }
275}
276
277class BuildSettings implements Serializable {
278 public final CC_Desc Compiler
279 public final Arch_Desc Architecture
280 public final Boolean RunAllTests
281 public final Boolean RunBenchmark
282 public final Boolean BuildDocumentation
283 public final Boolean Publish
284 public final Boolean Silent
285 public final Boolean IsSandbox
286 public final String DescLong
287 public final String DescShort
288
[a336d46]289 public String GitNewRef
290 public String GitOldRef
291
[490cb3c]292 BuildSettings(java.util.Collections$UnmodifiableMap param, String branch) {
[5b8413b4]293 switch( param.Compiler ) {
294 case 'gcc-6':
295 this.Compiler = new CC_Desc('gcc-6', 'g++-6', 'gcc-6')
296 break
297 case 'gcc-5':
298 this.Compiler = new CC_Desc('gcc-5', 'g++-5', 'gcc-5')
299 break
300 case 'gcc-4.9':
301 this.Compiler = new CC_Desc('gcc-4.9', 'g++-4.9', 'gcc-4.9')
302 break
303 case 'clang':
304 this.Compiler = new CC_Desc('clang', 'clang++', 'gcc-6')
305 break
306 default :
307 error "Unhandled compiler : ${cc}"
308 }
309
310 switch( param.Architecture ) {
311 case 'x64':
[a3e8281]312 this.Architecture = new Arch_Desc('x64', '--host=x86_64', 'x64')
[5b8413b4]313 break
314 case 'x86':
[a3e8281]315 this.Architecture = new Arch_Desc('x86', '--host=i386', 'x86')
[5b8413b4]316 break
317 default :
318 error "Unhandled architecture : ${arch}"
319 }
320
[f95e8f0]321 this.IsSandbox = (branch == "jenkins-sandbox")
[5b8413b4]322 this.RunAllTests = param.RunAllTests
[7a230fd]323 this.RunBenchmark = param.RunBenchmark
[5b8413b4]324 this.BuildDocumentation = param.BuildDocumentation
[7a230fd]325 this.Publish = param.Publish
[5b8413b4]326 this.Silent = param.Silent
327
328 def full = param.RunAllTests ? " (Full)" : ""
[490cb3c]329 this.DescShort = "${ this.Compiler.name }:${ this.Architecture.name }${full}"
[5b8413b4]330
[93fe3154]331 this.DescLong = """Compiler : ${ this.Compiler.name } (${ this.Compiler.CXX }/${ this.Compiler.CC })
[5b8413b4]332Architecture : ${ this.Architecture.name }
333Arc Flags : ${ this.Architecture.flags }
334Run All Tests : ${ this.RunAllTests.toString() }
335Run Benchmark : ${ this.RunBenchmark.toString() }
336Build Documentation : ${ this.BuildDocumentation.toString() }
337Publish : ${ this.Publish.toString() }
338Silent : ${ this.Silent.toString() }
339"""
[a336d46]340
341 this.GitNewRef = ''
342 this.GitOldRef = ''
[5b8413b4]343 }
344}
345
[490cb3c]346class PlotGroup implements Serializable {
347 public String name
348 public String unit
349 public boolean log
350
351 PlotGroup(String name, String unit, boolean log) {
352 this.name = name
353 this.unit = unit
354 this.log = log
355 }
356}
357
[5b8413b4]358def prepare_build() {
359 // prepare the properties
360 properties ([ \
361 [$class: 'ParametersDefinitionProperty', \
362 parameterDefinitions: [ \
363 [$class: 'ChoiceParameterDefinition', \
364 description: 'Which compiler to use', \
365 name: 'Compiler', \
366 choices: 'gcc-6\ngcc-5\ngcc-4.9\nclang', \
367 defaultValue: 'gcc-6', \
368 ], \
369 [$class: 'ChoiceParameterDefinition', \
370 description: 'The target architecture', \
371 name: 'Architecture', \
372 choices: 'x64\nx86', \
373 defaultValue: 'x64', \
374 ], \
375 [$class: 'BooleanParameterDefinition', \
376 description: 'If false, only the quick test suite is ran', \
377 name: 'RunAllTests', \
378 defaultValue: false, \
379 ], \
380 [$class: 'BooleanParameterDefinition', \
381 description: 'If true, jenkins also runs benchmarks', \
382 name: 'RunBenchmark', \
383 defaultValue: false, \
384 ], \
385 [$class: 'BooleanParameterDefinition', \
386 description: 'If true, jenkins also builds documentation', \
387 name: 'BuildDocumentation', \
388 defaultValue: true, \
389 ], \
390 [$class: 'BooleanParameterDefinition', \
391 description: 'If true, jenkins also publishes results', \
392 name: 'Publish', \
393 defaultValue: false, \
394 ], \
395 [$class: 'BooleanParameterDefinition', \
396 description: 'If true, jenkins will not send emails', \
397 name: 'Silent', \
398 defaultValue: false, \
399 ], \
400 ],
401 ]])
402
[4c55047]403 // It's unfortunate but it looks like we need to checkout the entire repo just to get the pretty git printer
404 checkout scm
[2407853]405
[490cb3c]406 final settings = new BuildSettings(params, env.BRANCH_NAME)
[5b8413b4]407
408 currentBuild.description = settings.DescShort
409 echo settings.DescLong
410
411 return settings
412}
413
414def build_stage(String name, Closure block ) {
415 StageName = name
416 echo " -------- ${StageName} -------- "
[939fd39]417 stage(name, block)
[5b8413b4]418}
419
420def make_doc() {
421 def err = null
422 try {
423 sh 'make clean > /dev/null'
424 sh 'make > /dev/null 2>&1'
425 }
426 catch (Exception caughtError) {
427 err = caughtError //rethrow error later
[65f4a51]428 sh 'cat build/*.log'
[5b8413b4]429 }
430 finally {
431 if (err) throw err // Must re-throw exception to propagate error
432 }
[a2a0065]433}
434
[1b3eef8]435def do_plot(boolean new_data, String file, PlotGroup group, String title) {
[8d63649]436
[1b3eef8]437 if(new_data) {
438 echo "Publishing new data"
439 }
440
441 def series = new_data ? [] : [[
[df57a84]442 file: "${file}.csv",
[3c40dc2a]443 exclusionValues: '',
444 displayTableFlag: false,
445 inclusionFlag: 'OFF',
446 url: ''
[8d63649]447 ]];
448
449 echo "file is ${BuildDir}/benchmark/${file}.csv, group ${group}, title ${title}"
450 dir("${BuildDir}/benchmark/") {
451 plot csvFileName: "cforall-${env.BRANCH_NAME}-${file}.csv",
452 csvSeries: series,
[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.