source: Jenkinsfile@ 5307c33

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

First attempt at running jenkins 32bit builds on ruby

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