source: Jenkinsfile@ 8e70823

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

Fixed directory for jenkins benchmark script.
Also testing closing ticket [fixes #119]

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