source: Jenkinsfile @ 5307c33

aaron-thesisarm-ehcleanup-dtorsjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprno_listpersistent-indexer
Last change on this file since 5307c33 was 5307c33, checked in by Thierry Delisle <tdelisle@…>, 3 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.