source: Jenkinsfile@ 4fd45bc

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
Last change on this file since 4fd45bc was af43394, checked in by Thierry Delisle <tdelisle@…>, 7 years ago

Moved all builds to master to ease merge

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