source: Jenkinsfile@ 7a927ed0

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

Jenkins now use script for build logs to reduce output

  • Property mode set to 100644
File size: 11.3 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 email(log_needed, Settings.IsSandbox)
67 }
68
69 echo 'Build Completed'
70
71 /* Must re-throw exception to propagate error */
72 if (err) {
73 throw err
74 }
75 }
76}
77
78//===========================================================================================================
79// Main compilation routines
80//===========================================================================================================
81def clean() {
82 build_stage('Cleanup') {
83 // clean the build by wipping the build directory
84 dir(BuildDir) {
85 deleteDir()
86 }
87 }
88}
89
90//Compilation script is done here but environnement set-up and error handling is done in main loop
91def checkout() {
92 build_stage('Checkout') {
93 //checkout the source code and clean the repo
94 final scmVars = checkout scm
95 Settings.GitNewRef = scmVars.GIT_COMMIT
96 Settings.GitOldRef = scmVars.GIT_PREVIOUS_COMMIT
97
98 echo GitLogMessage()
99 }
100}
101
102def build() {
103 build_stage('Build') {
104 // Build outside of the src tree to ease cleaning
105 dir (BuildDir) {
106 //Configure the conpilation (Output is not relevant)
107 //Use the current directory as the installation target so nothing escapes the sandbox
108 //Also specify the compiler by hand
109 targets=""
110 if( Settings.RunAllTests ) {
111 targets="--with-target-hosts='host:debug,host:nodebug'"
112 } else {
113 targets="--with-target-hosts='host:debug'"
114 }
115
116 sh "${SrcDir}/configure CXX=${Settings.Compiler.cpp_cc} ${Settings.Architecture.flags} ${targets} --with-backend-compiler=${Settings.Compiler.cfa_cc} --quiet"
117
118 //Compile the project
119 sh 'make -j 8 --no-print-directory'
120 }
121 }
122}
123
124def test() {
125 build_stage('Test') {
126
127 dir (BuildDir) {
128 //Run the tests from the tests directory
129 if ( Settings.RunAllTests ) {
130 sh 'make --no-print-directory -C tests all-tests debug=yes'
131 sh 'make --no-print-directory -C tests all-tests debug=no '
132 }
133 else {
134 sh 'make --no-print-directory -C tests'
135 }
136 }
137 }
138}
139
140def benchmark() {
141 build_stage('Benchmark') {
142
143 if( !Settings.RunBenchmark ) return
144
145 dir (BuildDir) {
146 //Append bench results
147 sh "make --no-print-directory -C benchmark jenkins githash=${Settings.GitNewRef} arch=${Settings.Architecture} | tee ${SrcDir}/bench.json"
148 }
149 }
150}
151
152def build_doc() {
153 build_stage('Documentation') {
154
155 if( !Settings.BuildDocumentation ) return
156
157 dir ('doc/user') {
158 make_doc()
159 }
160
161 dir ('doc/refrat') {
162 make_doc()
163 }
164 }
165}
166
167def publish() {
168 build_stage('Publish') {
169
170 if( !Settings.Publish ) return
171
172 //Then publish the results
173 sh 'curl --silent --show-error -H \'Content-Type: application/json\' --data @bench.json https://cforall.uwaterloo.ca:8082/jenkins/publish > /dev/null || true'
174 }
175}
176
177//===========================================================================================================
178//Routine responsible of sending the email notification once the build is completed
179//===========================================================================================================
180def GitLogMessage() {
181 if (!Settings || !Settings.GitOldRef || !Settings.GitNewRef) return "\nERROR retrieveing git information!\n"
182
183 dir(BuildDir) {
184 sh "${SrcDir}/tools/PrettyGitLogs.sh ${Settings.GitOldRef} ${Settings.GitNewRef}";
185 }
186 def gitUpdate = readFile("${BuildDir}/GIT_TYPE").trim()
187 def gitLog = readFile("${BuildDir}/GIT_LOG").trim()
188 def gitDiff = readFile("${BuildDir}/GIT_DIFF").trim()
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
254 Arch_Desc(String name, String flags) {
255 this.name = name
256 this.flags = flags
257 }
258}
259
260class BuildSettings implements Serializable {
261 public final CC_Desc Compiler
262 public final Arch_Desc Architecture
263 public final Boolean RunAllTests
264 public final Boolean RunBenchmark
265 public final Boolean BuildDocumentation
266 public final Boolean Publish
267 public final Boolean Silent
268 public final Boolean IsSandbox
269 public final String DescLong
270 public final String DescShort
271
272 public String GitNewRef
273 public String GitOldRef
274
275 BuildSettings(java.util.Collections$UnmodifiableMap param, String branch) {
276 switch( param.Compiler ) {
277 case 'gcc-6':
278 this.Compiler = new CC_Desc('gcc-6', 'g++-6', 'gcc-6')
279 break
280 case 'gcc-5':
281 this.Compiler = new CC_Desc('gcc-5', 'g++-5', 'gcc-5')
282 break
283 case 'gcc-4.9':
284 this.Compiler = new CC_Desc('gcc-4.9', 'g++-4.9', 'gcc-4.9')
285 break
286 case 'clang':
287 this.Compiler = new CC_Desc('clang', 'clang++', 'gcc-6')
288 break
289 default :
290 error "Unhandled compiler : ${cc}"
291 }
292
293 switch( param.Architecture ) {
294 case 'x64':
295 this.Architecture = new Arch_Desc('x64', '--host=x86_64')
296 break
297 case 'x86':
298 this.Architecture = new Arch_Desc('x86', '--host=i386')
299 break
300 default :
301 error "Unhandled architecture : ${arch}"
302 }
303
304 this.RunAllTests = param.RunAllTests
305 this.RunBenchmark = param.RunBenchmark
306 this.BuildDocumentation = param.BuildDocumentation
307 this.Publish = param.Publish
308 this.Silent = param.Silent
309 this.IsSandbox = (branch == "jenkins-sandbox")
310
311 def full = param.RunAllTests ? " (Full)" : ""
312 this.DescShort = "${ this.Compiler.cc_name }:${ this.Architecture.name }${full}"
313
314 this.DescLong = """Compiler : ${ this.Compiler.cc_name } (${ this.Compiler.cpp_cc }/${ this.Compiler.cfa_cc })
315Architecture : ${ this.Architecture.name }
316Arc Flags : ${ this.Architecture.flags }
317Run All Tests : ${ this.RunAllTests.toString() }
318Run Benchmark : ${ this.RunBenchmark.toString() }
319Build Documentation : ${ this.BuildDocumentation.toString() }
320Publish : ${ this.Publish.toString() }
321Silent : ${ this.Silent.toString() }
322"""
323
324 this.GitNewRef = ''
325 this.GitOldRef = ''
326 }
327}
328
329def prepare_build() {
330 // prepare the properties
331 properties ([ \
332 [$class: 'ParametersDefinitionProperty', \
333 parameterDefinitions: [ \
334 [$class: 'ChoiceParameterDefinition', \
335 description: 'Which compiler to use', \
336 name: 'Compiler', \
337 choices: 'gcc-6\ngcc-5\ngcc-4.9\nclang', \
338 defaultValue: 'gcc-6', \
339 ], \
340 [$class: 'ChoiceParameterDefinition', \
341 description: 'The target architecture', \
342 name: 'Architecture', \
343 choices: 'x64\nx86', \
344 defaultValue: 'x64', \
345 ], \
346 [$class: 'BooleanParameterDefinition', \
347 description: 'If false, only the quick test suite is ran', \
348 name: 'RunAllTests', \
349 defaultValue: false, \
350 ], \
351 [$class: 'BooleanParameterDefinition', \
352 description: 'If true, jenkins also runs benchmarks', \
353 name: 'RunBenchmark', \
354 defaultValue: false, \
355 ], \
356 [$class: 'BooleanParameterDefinition', \
357 description: 'If true, jenkins also builds documentation', \
358 name: 'BuildDocumentation', \
359 defaultValue: true, \
360 ], \
361 [$class: 'BooleanParameterDefinition', \
362 description: 'If true, jenkins also publishes results', \
363 name: 'Publish', \
364 defaultValue: false, \
365 ], \
366 [$class: 'BooleanParameterDefinition', \
367 description: 'If true, jenkins will not send emails', \
368 name: 'Silent', \
369 defaultValue: false, \
370 ], \
371 ],
372 ]])
373
374 final settings = new BuildSettings(params, env.BRANCH_NAME)
375
376 currentBuild.description = settings.DescShort
377 echo settings.DescLong
378
379 return settings
380}
381
382def build_stage(String name, Closure block ) {
383 StageName = name
384 echo " -------- ${StageName} -------- "
385 stage(name, block)
386}
387
388def notify_server(int wait) {
389 sh """curl --silent --show-error --data "wait=${wait}" -X POST https://cforall.uwaterloo.ca:8082/jenkins/notify > /dev/null || true"""
390 return
391}
392
393def make_doc() {
394 def err = null
395 try {
396 sh 'make clean > /dev/null'
397 sh 'make > /dev/null 2>&1'
398 }
399 catch (Exception caughtError) {
400 err = caughtError //rethrow error later
401 sh 'cat *.log'
402 }
403 finally {
404 if (err) throw err // Must re-throw exception to propagate error
405 }
406}
Note: See TracBrowser for help on using the repository browser.