source: Jenkinsfile@ 2469a6e

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors deferred_resn demangler enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr no_list persistent-indexer pthread-emulation qualifiedEnum
Last change on this file since 2469a6e was 2469a6e, checked in by Thierry Delisle <tdelisle@…>, 7 years ago

Fixed bad copy-paste

  • Property mode set to 100644
File size: 12.9 KB
Line 
1#!groovy
2
3//===========================================================================================================
4// Main loop of the compilation
5//===========================================================================================================
6node ('master'){
7
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 notify_server(0)
25
26 Settings = prepare_build()
27
28 clean()
29
30 checkout()
31
32 notify_server(0)
33
34 build()
35
36 test()
37
38 benchmark()
39
40 build_doc()
41
42 publish()
43
44 notify_server(45)
45 }
46 }
47
48 //If an exception is caught we need to change the status and remember to
49 //attach the build log to the email
50 catch (Exception caughtError) {
51 //rethrow error later
52 err = caughtError
53
54 echo err.toString()
55
56 //An error has occured, the build log is relevent
57 log_needed = true
58
59 //Store the result of the build log
60 currentBuild.result = "${StageName} FAILURE".trim()
61 }
62
63 finally {
64 //Send email with final results if this is not a full build
65 if( Settings && !Settings.Silent ) {
66 echo 'Notifying users of result'
67 email(currentBuild.result, log_needed, bIsSandbox)
68 }
69
70 echo 'Build Completed'
71
72 /* Must re-throw exception to propagate error */
73 if (err) {
74 throw err
75 }
76 }
77}
78
79//===========================================================================================================
80// Main compilation routines
81//===========================================================================================================
82def clean() {
83 build_stage('Cleanup') {
84 // clean the build by wipping the build directory
85 dir(BuildDir) {
86 deleteDir()
87 }
88 }
89}
90
91//Compilation script is done here but environnement set-up and error handling is done in main loop
92def checkout() {
93 build_stage('Checkout') {
94 //checkout the source code and clean the repo
95 checkout scm
96
97 def changeLogSets = currentBuild.changeSets
98 for (int i = 0; i < changeLogSets.size(); i++) {
99 def entries = changeLogSets[i].items
100 for (int j = 0; j < entries.length; j++) {
101 def entry = entries[j]
102 echo "${entry.commitId} by ${entry.author} on ${new Date(entry.timestamp)}: ${entry.msg}"
103 def files = new ArrayList(entry.affectedFiles)
104 for (int k = 0; k < files.size(); k++) {
105 def file = files[k]
106 echo " ${file.editType.name} ${file.path}"
107 }
108 }
109 }
110
111 echo """This is an automated email from the Jenkins build machine. It was
112generated because of a git hooks/post-receive script following
113a ref change was pushed to the repository containing
114the project "UNNAMED PROJECT".
115
116The branch ${env.BRANCH_NAME} has been updated.
117
118
119Check console output at ${env.BUILD_URL} to view the results.
120
121- Status --------------------------------------------------------------
122
123BUILD# ${env.BUILD_NUMBER} - ${status}
124
125- Log -----------------------------------------------------------------
126
127-----------------------------------------------------------------------
128Summary of changes:
129
130"""
131 }
132}
133
134def build() {
135 build_stage('Build') {
136 // Build outside of the src tree to ease cleaning
137 dir (BuildDir) {
138 //Configure the conpilation (Output is not relevant)
139 //Use the current directory as the installation target so nothing escapes the sandbox
140 //Also specify the compiler by hand
141 targets=""
142 if( Settings.RunAllTests ) {
143 targets="--with-target-hosts='host:debug,host:nodebug'"
144 } else {
145 targets="--with-target-hosts='host:debug'"
146 }
147
148 sh "${SrcDir}/configure CXX=${Settings.Compiler.cpp_cc} ${Settings.Architecture.flags} ${targets} --with-backend-compiler=${Settings.Compiler.cfa_cc} --quiet"
149
150 //Compile the project
151 sh 'make -j 8 --no-print-directory'
152 }
153 }
154}
155
156def test() {
157 build_stage('Test') {
158
159 dir (BuildDir) {
160 //Run the tests from the tests directory
161 if ( Settings.RunAllTests ) {
162 sh 'make --no-print-directory -C tests all-tests debug=yes'
163 sh 'make --no-print-directory -C tests all-tests debug=no '
164 }
165 else {
166 sh 'make --no-print-directory -C tests'
167 }
168 }
169 }
170}
171
172def benchmark() {
173 build_stage('Benchmark') {
174
175 if( !Settings.RunBenchmark ) return
176
177 dir (BuildDir) {
178 //Append bench results
179 sh "make --no-print-directory -C benchmark jenkins githash=${gitRefNewValue} arch=${Settings.Architecture} | tee ${SrcDir}/bench.json"
180 }
181 }
182}
183
184def build_doc() {
185 build_stage('Documentation') {
186
187 if( !Settings.BuildDocumentation ) return
188
189 dir ('doc/user') {
190 make_doc()
191 }
192
193 dir ('doc/refrat') {
194 make_doc()
195 }
196 }
197}
198
199def publish() {
200 build_stage('Publish') {
201
202 if( !Settings.Publish ) return
203
204 //Then publish the results
205 sh 'curl --silent --show-error -H \'Content-Type: application/json\' --data @bench.json https://cforall.uwaterloo.ca:8082/jenkins/publish > /dev/null || true'
206 }
207}
208
209//===========================================================================================================
210//Routine responsible of sending the email notification once the build is completed
211//===========================================================================================================
212def gitBranchUpdate(String gitRefOldValue, String gitRefNewValue) {
213 def update = ""
214 sh "git rev-list ${gitRefOldValue}..${gitRefNewValue} > GIT_LOG";
215 readFile('GIT_LOG').eachLine { rev ->
216 sh "git cat-file -t ${rev} > GIT_TYPE"
217 def type = readFile('GIT_TYPE')
218
219 update += " via ${rev} (${type})\n"
220 }
221 def rev = gitRefOldValue
222 sh "git cat-file -t ${rev} > GIT_TYPE"
223 def type = readFile('GIT_TYPE')
224
225 update += " from ${rev} (${type})\n"
226 return update
227
228 def output=readFile('result').trim()
229 echo "output=$output";
230}
231
232//Standard build email notification
233def email(String status, boolean log, boolean bIsSandbox) {
234 //Since tokenizer doesn't work, figure stuff out from the environnement variables and command line
235 //Configurations for email format
236 def project_name = (env.JOB_NAME =~ /(.+)\/.+/)[0][1].toLowerCase()
237
238 def gitLog = 'Error retrieving git logs'
239 def gitDiff = 'Error retrieving git diff'
240 def gitUpdate = 'Error retrieving update'
241
242 try {
243 final scmVars = checkout(scm)
244
245 gitUpdate = gitBranchUpdate(scmVars.GIT_PREVIOUS_COMMIT, scmVars.GIT_COMMIT)
246
247 sh "git rev-list --format=short ${scmVars.GIT_PREVIOUS_COMMIT}...${scmVars.GIT_COMMIT} > ${BuildDir}/GIT_LOG"
248 gitLog = readFile("${BuildDir}/GIT_LOG")
249
250 sh "git diff --stat ${scmVars.GIT_COMMIT} ${scmVars.GIT_PREVIOUS_COMMIT} > ${BuildDir}/GIT_DIFF"
251 gitDiff = readFile("${BuildDir}/GIT_DIFF")
252 }
253 catch (Exception error) {
254 echo error.toString()
255 echo error.getMessage()
256 }
257
258 def email_subject = "[${project_name} git][BUILD# ${env.BUILD_NUMBER} - ${status}] - branch ${env.BRANCH_NAME}"
259 def email_body = """This is an automated email from the Jenkins build machine. It was
260generated because of a git hooks/post-receive script following
261a ref change was pushed to the repository containing
262the project "UNNAMED PROJECT".
263
264The branch ${env.BRANCH_NAME} has been updated.
265${gitUpdate}
266
267Check console output at ${env.BUILD_URL} to view the results.
268
269- Status --------------------------------------------------------------
270
271BUILD# ${env.BUILD_NUMBER} - ${status}
272
273- Log -----------------------------------------------------------------
274${gitLog}
275-----------------------------------------------------------------------
276Summary of changes:
277${gitDiff}
278"""
279
280 def email_to = "cforall@lists.uwaterloo.ca"
281
282 if( Settings && !Settings.IsSandbox ) {
283 //send email notification
284 emailext body: email_body, subject: email_subject, to: email_to, attachLog: log
285 } else {
286 echo "Would send email to: ${email_to}"
287 echo "With title: ${email_subject}"
288 echo "Content: \n${email_body}"
289 }
290}
291
292//===========================================================================================================
293// Helper classes/variables/routines
294//===========================================================================================================
295//Description of a compiler (Must be serializable since pipelines are persistent)
296class CC_Desc implements Serializable {
297 public String cc_name
298 public String cpp_cc
299 public String cfa_cc
300
301 CC_Desc(String cc_name, String cpp_cc, String cfa_cc) {
302 this.cc_name = cc_name
303 this.cpp_cc = cpp_cc
304 this.cfa_cc = cfa_cc
305 }
306}
307
308//Description of an architecture (Must be serializable since pipelines are persistent)
309class Arch_Desc implements Serializable {
310 public String name
311 public String flags
312
313 Arch_Desc(String name, String flags) {
314 this.name = name
315 this.flags = flags
316 }
317}
318
319class BuildSettings implements Serializable {
320 public final CC_Desc Compiler
321 public final Arch_Desc Architecture
322 public final Boolean RunAllTests
323 public final Boolean RunBenchmark
324 public final Boolean BuildDocumentation
325 public final Boolean Publish
326 public final Boolean Silent
327 public final Boolean IsSandbox
328 public final String DescLong
329 public final String DescShort
330
331 BuildSettings(java.util.Collections$UnmodifiableMap param, String branch) {
332 switch( param.Compiler ) {
333 case 'gcc-6':
334 this.Compiler = new CC_Desc('gcc-6', 'g++-6', 'gcc-6')
335 break
336 case 'gcc-5':
337 this.Compiler = new CC_Desc('gcc-5', 'g++-5', 'gcc-5')
338 break
339 case 'gcc-4.9':
340 this.Compiler = new CC_Desc('gcc-4.9', 'g++-4.9', 'gcc-4.9')
341 break
342 case 'clang':
343 this.Compiler = new CC_Desc('clang', 'clang++', 'gcc-6')
344 break
345 default :
346 error "Unhandled compiler : ${cc}"
347 }
348
349 switch( param.Architecture ) {
350 case 'x64':
351 this.Architecture = new Arch_Desc('x64', '--host=x86_64')
352 break
353 case 'x86':
354 this.Architecture = new Arch_Desc('x86', '--host=i386')
355 break
356 default :
357 error "Unhandled architecture : ${arch}"
358 }
359
360 this.RunAllTests = param.RunAllTests
361 this.RunBenchmark = param.RunBenchmark
362 this.BuildDocumentation = param.BuildDocumentation
363 this.Publish = param.Publish
364 this.Silent = param.Silent
365 this.IsSandbox = (branch == "jenkins-sandbox")
366
367 def full = param.RunAllTests ? " (Full)" : ""
368 this.DescShort = "${ this.Compiler.cc_name }:${ this.Architecture.name }${full}"
369
370 this.DescLong = """Compiler : ${ this.Compiler.cc_name } (${ this.Compiler.cpp_cc }/${ this.Compiler.cfa_cc })
371Architecture : ${ this.Architecture.name }
372Arc Flags : ${ this.Architecture.flags }
373Run All Tests : ${ this.RunAllTests.toString() }
374Run Benchmark : ${ this.RunBenchmark.toString() }
375Build Documentation : ${ this.BuildDocumentation.toString() }
376Publish : ${ this.Publish.toString() }
377Silent : ${ this.Silent.toString() }
378"""
379 }
380}
381
382def prepare_build() {
383 // prepare the properties
384 properties ([ \
385 [$class: 'ParametersDefinitionProperty', \
386 parameterDefinitions: [ \
387 [$class: 'ChoiceParameterDefinition', \
388 description: 'Which compiler to use', \
389 name: 'Compiler', \
390 choices: 'gcc-6\ngcc-5\ngcc-4.9\nclang', \
391 defaultValue: 'gcc-6', \
392 ], \
393 [$class: 'ChoiceParameterDefinition', \
394 description: 'The target architecture', \
395 name: 'Architecture', \
396 choices: 'x64\nx86', \
397 defaultValue: 'x64', \
398 ], \
399 [$class: 'BooleanParameterDefinition', \
400 description: 'If false, only the quick test suite is ran', \
401 name: 'RunAllTests', \
402 defaultValue: false, \
403 ], \
404 [$class: 'BooleanParameterDefinition', \
405 description: 'If true, jenkins also runs benchmarks', \
406 name: 'RunBenchmark', \
407 defaultValue: false, \
408 ], \
409 [$class: 'BooleanParameterDefinition', \
410 description: 'If true, jenkins also builds documentation', \
411 name: 'BuildDocumentation', \
412 defaultValue: true, \
413 ], \
414 [$class: 'BooleanParameterDefinition', \
415 description: 'If true, jenkins also publishes results', \
416 name: 'Publish', \
417 defaultValue: false, \
418 ], \
419 [$class: 'BooleanParameterDefinition', \
420 description: 'If true, jenkins will not send emails', \
421 name: 'Silent', \
422 defaultValue: false, \
423 ], \
424 ],
425 ]])
426
427 final settings = new BuildSettings(params, env.BRANCH_NAME)
428
429 currentBuild.description = settings.DescShort
430 echo settings.DescLong
431
432 return settings
433}
434
435def build_stage(String name, Closure block ) {
436 StageName = name
437 echo " -------- ${StageName} -------- "
438 stage(name, block)
439}
440
441def notify_server(int wait) {
442 sh """curl --silent --show-error --data "wait=${wait}" -X POST https://cforall.uwaterloo.ca:8082/jenkins/notify > /dev/null || true"""
443 return
444}
445
446def make_doc() {
447 def err = null
448 try {
449 sh 'make clean > /dev/null'
450 sh 'make > /dev/null 2>&1'
451 }
452 catch (Exception caughtError) {
453 err = caughtError //rethrow error later
454 sh 'cat *.log'
455 }
456 finally {
457 if (err) throw err // Must re-throw exception to propagate error
458 }
459}
Note: See TracBrowser for help on using the repository browser.