source: Jenkinsfile @ af43394

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