source: Jenkinsfile@ 1d760934

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

Reverted local timeout but increased global timeout

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