source: Jenkinsfile@ ce2e547

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

Jenkinsfile now uses line simple to plot

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