source: Jenkinsfile @ 13c98a4

arm-ehcleanup-dtorsjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-expr
Last change on this file since 13c98a4 was 13c98a4, checked in by Thierry Delisle <tdelisle@…>, 3 years ago

Jenkins emails now use html, this push does some work to improve how they look

  • Property mode set to 100644
File size: 12.3 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                        Settings = prepare_build()
25
26                        node(Settings.Architecture.node) {
27                                BuildDir  = pwd tmp: true
28                                SrcDir    = pwd tmp: false
29
30                                clean()
31
32                                checkout()
33
34                                build()
35
36                                test()
37
38                                benchmark()
39
40                                build_doc()
41
42                                publish()
43                        }
44
45                        // Update the build directories when exiting the node
46                        BuildDir  = pwd tmp: true
47                        SrcDir    = pwd tmp: false
48                }
49        }
50
51        //If an exception is caught we need to change the status and remember to
52        //attach the build log to the email
53        catch (Exception caughtError) {
54                //rethrow error later
55                err = caughtError
56
57                echo err.toString()
58
59                //An error has occured, the build log is relevent
60                log_needed = true
61
62                //Store the result of the build log
63                currentBuild.result = "${StageName} FAILURE".trim()
64        }
65
66        finally {
67                //Send email with final results if this is not a full build
68                email(log_needed)
69
70                echo 'Build Completed'
71
72                /* Must re-throw exception to propagate error */
73                if (err) {
74                        throw err
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 || Settings.RunBenchmark ) {
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.CXX} CC=${Settings.Compiler.CC} ${Settings.Architecture.flags} ${targets} --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 timeouts="--timeout=600" all-tests debug=yes'
131                                sh 'make --no-print-directory -C tests timeouts="--timeout=600" 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"
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                if( !Settings.RunBenchmark ) {
172                        echo 'No results to publish!!!'
173                        return
174                }
175
176                //Then publish the results
177                do_plot('compile', 'Compilation', 'Compilation')
178
179                do_plot('ctxswitch', 'Concurrency', 'Context Switching')
180
181                do_plot('mutex', 'Concurrency', 'Mutual Exclusion')
182
183                do_plot('signal', 'Concurrency', 'Internal and External Scheduling')
184        }
185}
186
187//===========================================================================================================
188//Routine responsible of sending the email notification once the build is completed
189//===========================================================================================================
190def GitLogMessage() {
191        if (!Settings || !Settings.GitOldRef || !Settings.GitNewRef) return "\nERROR retrieveing git information!\n"
192
193        sh "${SrcDir}/tools/PrettyGitLogs.sh ${SrcDir} ${BuildDir} ${Settings.GitOldRef} ${Settings.GitNewRef}"
194
195        def gitUpdate = readFile("${BuildDir}/GIT_UPDATE")
196        def gitLog    = readFile("${BuildDir}/GIT_LOG")
197        def gitDiff   = readFile("${BuildDir}/GIT_DIFF")
198
199        return """
200<pre>
201The branch ${env.BRANCH_NAME} has been updated.
202${gitUpdate}
203</pre>
204
205<p>Check console output at ${env.BUILD_URL} to view the results.</p>
206
207<p>- Status --------------------------------------------------------------</p>
208
209<p>BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}</p>
210
211<p>- Log -----------------------------------------------------------------</p>
212
213<pre>
214${gitLog}
215</pre>
216
217<p>-----------------------------------------------------------------------</p>
218<pre>
219Summary of changes:
220${gitDiff}
221</pre>
222"""
223}
224
225//Standard build email notification
226def email(boolean log) {
227        //Since tokenizer doesn't work, figure stuff out from the environnement variables and command line
228        //Configurations for email format
229        echo 'Notifying users of result'
230
231        def project_name = (env.JOB_NAME =~ /(.+)\/.+/)[0][1].toLowerCase()
232        def email_subject = "[${project_name} git][BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}] - branch ${env.BRANCH_NAME}"
233        def email_body = """<p>This is an automated email from the Jenkins build machine. It was
234generated because of a git hooks/post-receive script following
235a ref change which was pushed to the C repository.</p>
236""" + GitLogMessage()
237
238        def email_to = !Settings.IsSandbox ? "cforall@lists.uwaterloo.ca" : "tdelisle@uwaterloo.ca"
239
240        if( Settings && !Settings.Silent ) {
241                //send email notification
242                emailext body: email_body, subject: email_subject, to: email_to, attachLog: log
243        } else {
244                echo "Would send email to: ${email_to}"
245                echo "With title: ${email_subject}"
246                echo "Content: \n${email_body}"
247        }
248}
249
250//===========================================================================================================
251// Helper classes/variables/routines
252//===========================================================================================================
253//Description of a compiler (Must be serializable since pipelines are persistent)
254class CC_Desc implements Serializable {
255        public String name
256        public String CXX
257        public String CC
258
259        CC_Desc(String name, String CXX, String CC) {
260                this.name = name
261                this.CXX = CXX
262                this.CC = CC
263        }
264}
265
266//Description of an architecture (Must be serializable since pipelines are persistent)
267class Arch_Desc implements Serializable {
268        public String name
269        public String flags
270        public String node
271
272        Arch_Desc(String name, String flags, String node) {
273                this.name  = name
274                this.flags = flags
275                this.node  = node
276        }
277}
278
279class BuildSettings implements Serializable {
280        public final CC_Desc Compiler
281        public final Arch_Desc Architecture
282        public final Boolean RunAllTests
283        public final Boolean RunBenchmark
284        public final Boolean BuildDocumentation
285        public final Boolean Publish
286        public final Boolean Silent
287        public final Boolean IsSandbox
288        public final String DescLong
289        public final String DescShort
290
291        public String GitNewRef
292        public String GitOldRef
293
294        BuildSettings(java.util.Collections$UnmodifiableMap param, String branch) {
295                switch( param.Compiler ) {
296                        case 'gcc-6':
297                                this.Compiler = new CC_Desc('gcc-6', 'g++-6', 'gcc-6')
298                        break
299                        case 'gcc-5':
300                                this.Compiler = new CC_Desc('gcc-5', 'g++-5', 'gcc-5')
301                        break
302                        case 'gcc-4.9':
303                                this.Compiler = new CC_Desc('gcc-4.9', 'g++-4.9', 'gcc-4.9')
304                        break
305                        case 'clang':
306                                this.Compiler = new CC_Desc('clang', 'clang++', 'gcc-6')
307                        break
308                        default :
309                                error "Unhandled compiler : ${cc}"
310                }
311
312                switch( param.Architecture ) {
313                        case 'x64':
314                                this.Architecture = new Arch_Desc('x64', '--host=x86_64', 'x64')
315                        break
316                        case 'x86':
317                                this.Architecture = new Arch_Desc('x86', '--host=i386', 'x86')
318                        break
319                        default :
320                                error "Unhandled architecture : ${arch}"
321                }
322
323                this.IsSandbox          = (branch == "jenkins-sandbox")
324                this.RunAllTests        = param.RunAllTests
325                this.RunBenchmark       = param.RunBenchmark || this.IsSandbox
326                this.BuildDocumentation = param.BuildDocumentation
327                this.Publish            = param.Publish || this.IsSandbox
328                this.Silent             = param.Silent
329
330                def full = param.RunAllTests ? " (Full)" : ""
331                this.DescShort = "${ this.Compiler.name }:${ this.Architecture.name }${full}"
332
333                this.DescLong = """Compiler              : ${ this.Compiler.name } (${ this.Compiler.CXX }/${ this.Compiler.CC })
334Architecture            : ${ this.Architecture.name }
335Arc Flags               : ${ this.Architecture.flags }
336Run All Tests           : ${ this.RunAllTests.toString() }
337Run Benchmark           : ${ this.RunBenchmark.toString() }
338Build Documentation     : ${ this.BuildDocumentation.toString() }
339Publish                 : ${ this.Publish.toString() }
340Silent                  : ${ this.Silent.toString() }
341"""
342
343                this.GitNewRef = ''
344                this.GitOldRef = ''
345        }
346}
347
348def prepare_build() {
349        // prepare the properties
350        properties ([                                                                                                   \
351                [$class: 'ParametersDefinitionProperty',                                                                \
352                        parameterDefinitions: [                                                                         \
353                                [$class: 'ChoiceParameterDefinition',                                           \
354                                        description: 'Which compiler to use',                                   \
355                                        name: 'Compiler',                                                                       \
356                                        choices: 'gcc-6\ngcc-5\ngcc-4.9\nclang',                                        \
357                                        defaultValue: 'gcc-6',                                                          \
358                                ],                                                                                              \
359                                [$class: 'ChoiceParameterDefinition',                                           \
360                                        description: 'The target architecture',                                 \
361                                        name: 'Architecture',                                                           \
362                                        choices: 'x64\nx86',                                                            \
363                                        defaultValue: 'x64',                                                            \
364                                ],                                                                                              \
365                                [$class: 'BooleanParameterDefinition',                                                  \
366                                        description: 'If false, only the quick test suite is ran',              \
367                                        name: 'RunAllTests',                                                            \
368                                        defaultValue: false,                                                            \
369                                ],                                                                                              \
370                                [$class: 'BooleanParameterDefinition',                                                  \
371                                        description: 'If true, jenkins also runs benchmarks',           \
372                                        name: 'RunBenchmark',                                                           \
373                                        defaultValue: false,                                                            \
374                                ],                                                                                              \
375                                [$class: 'BooleanParameterDefinition',                                                  \
376                                        description: 'If true, jenkins also builds documentation',              \
377                                        name: 'BuildDocumentation',                                                     \
378                                        defaultValue: true,                                                             \
379                                ],                                                                                              \
380                                [$class: 'BooleanParameterDefinition',                                                  \
381                                        description: 'If true, jenkins also publishes results',                 \
382                                        name: 'Publish',                                                                        \
383                                        defaultValue: false,                                                            \
384                                ],                                                                                              \
385                                [$class: 'BooleanParameterDefinition',                                                  \
386                                        description: 'If true, jenkins will not send emails',           \
387                                        name: 'Silent',                                                                         \
388                                        defaultValue: false,                                                            \
389                                ],                                                                                              \
390                        ],
391                ]])
392
393        // It's unfortunate but it looks like we need to checkout the entire repo just to get the pretty git printer
394        checkout scm
395
396        final settings = new BuildSettings(params, env.BRANCH_NAME)
397
398        currentBuild.description = settings.DescShort
399        echo                       settings.DescLong
400
401        return settings
402}
403
404def build_stage(String name, Closure block ) {
405        StageName = name
406        echo " -------- ${StageName} -------- "
407        stage(name, block)
408}
409
410def make_doc() {
411        def err = null
412        try {
413                sh 'make clean > /dev/null'
414                sh 'make > /dev/null 2>&1'
415        }
416        catch (Exception caughtError) {
417                err = caughtError //rethrow error later
418                sh 'cat build/*.log'
419        }
420        finally {
421                if (err) throw err // Must re-throw exception to propagate error
422        }
423}
424
425def do_plot(String file, String group, String title) {
426        echo "file is ${BuildDir}/benchmark/${file}.csv, group ${group}, title ${title}"
427        fileExists "${BuildDir}/benchmark/${file}.csv"
428        plot csvFileName: "cforall-${env.BRANCH_NAME}-${file}.csv",
429                csvSeries: [[
430                        file: "'${BuildDir}/benchmark/${file}.csv'",
431                        exclusionValues: '',
432                        displayTableFlag: false,
433                        inclusionFlag: 'OFF',
434                        url: ''
435                ]],
436                group: "${group}",
437                title: "${title}",
438                style: 'lineSimple',
439                exclZero: false,
440                keepRecords: false,
441                logarithmic: false,
442                numBuilds: '120',
443                useDescr: true,
444                yaxis: '',
445                yaxisMaximum: '',
446                yaxisMinimum: ''
447}
Note: See TracBrowser for help on using the repository browser.