source: Jenkinsfile @ 7a927ed0

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprno_listpersistent-indexerpthread-emulationqualifiedEnum
Last change on this file since 7a927ed0 was 7a927ed0, checked in by Thierry Delisle <tdelisle@…>, 6 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.