source: Jenkinsfile @ 13c98a4

ADTarm-ehast-experimentalcleanup-dtorsenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 13c98a4 was 13c98a4, checked in by Thierry Delisle <tdelisle@…>, 6 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
RevLine 
[a63ad80]1#!groovy
2
[29f4fe62]3//===========================================================================================================
[9beae23]4// Main loop of the compilation
[29f4fe62]5//===========================================================================================================
[56a9ce6]6
[5307c33]7node('master') {
[5b8413b4]8        // Globals
[4c55047]9        BuildDir  = pwd tmp: true
10        SrcDir    = pwd tmp: false
[5b8413b4]11        Settings  = null
12        StageName = ''
13
14        // Local variables
[9beae23]15        def err = null
16        def log_needed = false
[0ef06b6]17
18        currentBuild.result = "SUCCESS"
19
[9beae23]20        try {
[95fdb0a]21                //Wrap build to add timestamp to command line
22                wrap([$class: 'TimestamperBuildWrapper']) {
[23a14d86]23
[c431138]24                        Settings = prepare_build()
[7aebc62]25
[5307c33]26                        node(Settings.Architecture.node) {
[bf9d323]27                                BuildDir  = pwd tmp: true
28                                SrcDir    = pwd tmp: false
29
[5307c33]30                                clean()
[0dc3ac3]31
[5307c33]32                                checkout()
[fde808df]33
[5307c33]34                                build()
[95fdb0a]35
[5307c33]36                                test()
[95fdb0a]37
[5307c33]38                                benchmark()
[95fdb0a]39
[5307c33]40                                build_doc()
[7359098]41
[5307c33]42                                publish()
43                        }
[9beae23]44
[4c55047]45                        // Update the build directories when exiting the node
46                        BuildDir  = pwd tmp: true
47                        SrcDir    = pwd tmp: false
[9beae23]48                }
[738cf8f]49        }
50
[9beae23]51        //If an exception is caught we need to change the status and remember to
52        //attach the build log to the email
[738cf8f]53        catch (Exception caughtError) {
54                //rethrow error later
55                err = caughtError
56
[e966ec0]57                echo err.toString()
58
[9beae23]59                //An error has occured, the build log is relevent
60                log_needed = true
61
62                //Store the result of the build log
[5b8413b4]63                currentBuild.result = "${StageName} FAILURE".trim()
[738cf8f]64        }
65
66        finally {
[9beae23]67                //Send email with final results if this is not a full build
[13c98a4]68                email(log_needed)
[9beae23]69
[734891d]70                echo 'Build Completed'
71
[738cf8f]72                /* Must re-throw exception to propagate error */
73                if (err) {
74                        throw err
75                }
76        }
77}
[29f4fe62]78//===========================================================================================================
[9beae23]79// Main compilation routines
[29f4fe62]80//===========================================================================================================
[0dc3ac3]81def clean() {
82        build_stage('Cleanup') {
83                // clean the build by wipping the build directory
[5b8413b4]84                dir(BuildDir) {
[d4cd491]85                        deleteDir()
[ece8a80]86                }
[620dd2b]87        }
[95fdb0a]88}
[29f4fe62]89
[0dc3ac3]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
[a336d46]94                final scmVars = checkout scm
95                Settings.GitNewRef = scmVars.GIT_COMMIT
96                Settings.GitOldRef = scmVars.GIT_PREVIOUS_COMMIT
[d3a4564a]97
[a336d46]98                echo GitLogMessage()
[0dc3ac3]99        }
100}
101
[95fdb0a]102def build() {
[620dd2b]103        build_stage('Build') {
[50f2cfc]104                // Build outside of the src tree to ease cleaning
[5b8413b4]105                dir (BuildDir) {
[50f2cfc]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
[3fc5f010]109                        targets=""
[d4510ea]110                        if( Settings.RunAllTests || Settings.RunBenchmark ) {
[6bde81d]111                                targets="--with-target-hosts='host:debug,host:nodebug'"
[3fc5f010]112                        } else {
[6bde81d]113                                targets="--with-target-hosts='host:debug'"
[3fc5f010]114                        }
115
[93fe3154]116                        sh "${SrcDir}/configure CXX=${Settings.Compiler.CXX} CC=${Settings.Compiler.CC} ${Settings.Architecture.flags} ${targets} --quiet"
[1752d0e]117
[50f2cfc]118                        //Compile the project
119                        sh 'make -j 8 --no-print-directory'
120                }
[620dd2b]121        }
[95fdb0a]122}
[24eecab]123
[95fdb0a]124def test() {
[620dd2b]125        build_stage('Test') {
[9e5f409]126
[5b8413b4]127                dir (BuildDir) {
[0dc3ac3]128                        //Run the tests from the tests directory
[5afeab9]129                        if ( Settings.RunAllTests ) {
[b90aace]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 '
[0dc3ac3]132                        }
133                        else {
[7428ad9]134                                sh 'make --no-print-directory -C tests'
[0dc3ac3]135                        }
[9beae23]136                }
[620dd2b]137        }
[95fdb0a]138}
139
140def benchmark() {
[620dd2b]141        build_stage('Benchmark') {
[29f4fe62]142
[5afeab9]143                if( !Settings.RunBenchmark ) return
[ae28ee2]144
[5b8413b4]145                dir (BuildDir) {
[0dc3ac3]146                        //Append bench results
[f15fe0a]147                        sh "make --no-print-directory -C benchmark jenkins"
[0dc3ac3]148                }
[620dd2b]149        }
[9beae23]150}
[efd60d67]151
[95fdb0a]152def build_doc() {
[620dd2b]153        build_stage('Documentation') {
[9beae23]154
[5afeab9]155                if( !Settings.BuildDocumentation ) return
[9beae23]156
157                dir ('doc/user') {
158                        make_doc()
159                }
160
161                dir ('doc/refrat') {
162                        make_doc()
163                }
[620dd2b]164        }
[9beae23]165}
166
[95fdb0a]167def publish() {
[620dd2b]168        build_stage('Publish') {
[95fdb0a]169
[5afeab9]170                if( !Settings.Publish ) return
[f15fe0a]171                if( !Settings.RunBenchmark ) {
172                        echo 'No results to publish!!!'
173                        return
174                }
[95fdb0a]175
176                //Then publish the results
[a2a0065]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')
[620dd2b]184        }
[95fdb0a]185}
186
[29f4fe62]187//===========================================================================================================
188//Routine responsible of sending the email notification once the build is completed
189//===========================================================================================================
[a336d46]190def GitLogMessage() {
191        if (!Settings || !Settings.GitOldRef || !Settings.GitNewRef) return "\nERROR retrieveing git information!\n"
[e8a22a7]192
[9f5bb817]193        sh "${SrcDir}/tools/PrettyGitLogs.sh ${SrcDir} ${BuildDir} ${Settings.GitOldRef} ${Settings.GitNewRef}"
[6e31c43]194
[eda8175]195        def gitUpdate = readFile("${BuildDir}/GIT_UPDATE")
196        def gitLog    = readFile("${BuildDir}/GIT_LOG")
197        def gitDiff   = readFile("${BuildDir}/GIT_DIFF")
[7a927ed0]198
[a336d46]199        return """
[13c98a4]200<pre>
[848fb00]201The branch ${env.BRANCH_NAME} has been updated.
[7a927ed0]202${gitUpdate}
[13c98a4]203</pre>
204
205<p>Check console output at ${env.BUILD_URL} to view the results.</p>
[7b1a604]206
[13c98a4]207<p>- Status --------------------------------------------------------------</p>
[7b1a604]208
[13c98a4]209<p>BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}</p>
[7b1a604]210
[13c98a4]211<p>- Log -----------------------------------------------------------------</p>
[e8a22a7]212
[13c98a4]213<pre>
[7a927ed0]214${gitLog}
[13c98a4]215</pre>
216
217<p>-----------------------------------------------------------------------</p>
218<pre>
[7b1a604]219Summary of changes:
[7a927ed0]220${gitDiff}
[13c98a4]221</pre>
[7b1a604]222"""
[a336d46]223}
224
225//Standard build email notification
[13c98a4]226def email(boolean log) {
[a336d46]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}"
[13c98a4]233        def email_body = """<p>This is an automated email from the Jenkins build machine. It was
[a336d46]234generated because of a git hooks/post-receive script following
[13c98a4]235a ref change which was pushed to the C repository.</p>
[a336d46]236""" + GitLogMessage()
[e8a22a7]237
[13c98a4]238        def email_to = !Settings.IsSandbox ? "cforall@lists.uwaterloo.ca" : "tdelisle@uwaterloo.ca"
[e8a22a7]239
[13c98a4]240        if( Settings && !Settings.Silent ) {
[094a42c]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        }
[e8a22a7]248}
[5b8413b4]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 {
[93fe3154]255        public String name
256        public String CXX
[6ebc13f]257        public String CC
[93fe3154]258
[6ebc13f]259        CC_Desc(String name, String CXX, String CC) {
[93fe3154]260                this.name = name
261                this.CXX = CXX
[6ebc13f]262                this.CC = CC
[5b8413b4]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
[5307c33]270        public String node
[5b8413b4]271
[5307c33]272        Arch_Desc(String name, String flags, String node) {
[5b8413b4]273                this.name  = name
274                this.flags = flags
[5307c33]275                this.node  = node
[5b8413b4]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
[a336d46]291        public String GitNewRef
292        public String GitOldRef
293
[5b8413b4]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':
[a3e8281]314                                this.Architecture = new Arch_Desc('x64', '--host=x86_64', 'x64')
[5b8413b4]315                        break
316                        case 'x86':
[a3e8281]317                                this.Architecture = new Arch_Desc('x86', '--host=i386', 'x86')
[5b8413b4]318                        break
319                        default :
320                                error "Unhandled architecture : ${arch}"
321                }
322
[f95e8f0]323                this.IsSandbox          = (branch == "jenkins-sandbox")
[5b8413b4]324                this.RunAllTests        = param.RunAllTests
[f95e8f0]325                this.RunBenchmark       = param.RunBenchmark || this.IsSandbox
[5b8413b4]326                this.BuildDocumentation = param.BuildDocumentation
[f95e8f0]327                this.Publish            = param.Publish || this.IsSandbox
[5b8413b4]328                this.Silent             = param.Silent
329
330                def full = param.RunAllTests ? " (Full)" : ""
[93fe3154]331                this.DescShort = "${ this.Compiler.name }:${ this.Architecture.name }${full}"
[5b8413b4]332
[93fe3154]333                this.DescLong = """Compiler              : ${ this.Compiler.name } (${ this.Compiler.CXX }/${ this.Compiler.CC })
[5b8413b4]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"""
[a336d46]342
343                this.GitNewRef = ''
344                this.GitOldRef = ''
[5b8413b4]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
[4c55047]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
[2407853]395
[5b8413b4]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} -------- "
[939fd39]407        stage(name, block)
[5b8413b4]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
[65f4a51]418                sh 'cat build/*.log'
[5b8413b4]419        }
420        finally {
421                if (err) throw err // Must re-throw exception to propagate error
422        }
[a2a0065]423}
424
425def do_plot(String file, String group, String title) {
[f95e8f0]426        echo "file is ${BuildDir}/benchmark/${file}.csv, group ${group}, title ${title}"
427        fileExists "${BuildDir}/benchmark/${file}.csv"
[a2a0065]428        plot csvFileName: "cforall-${env.BRANCH_NAME}-${file}.csv",
429                csvSeries: [[
[f85464da]430                        file: "'${BuildDir}/benchmark/${file}.csv'",
[a2a0065]431                        exclusionValues: '',
432                        displayTableFlag: false,
433                        inclusionFlag: 'OFF',
434                        url: ''
435                ]],
436                group: "${group}",
437                title: "${title}",
[ce2e547]438                style: 'lineSimple',
[a2a0065]439                exclZero: false,
440                keepRecords: false,
441                logarithmic: false,
[ce2e547]442                numBuilds: '120',
443                useDescr: true,
[a2a0065]444                yaxis: '',
445                yaxisMaximum: '',
446                yaxisMinimum: ''
[5b8413b4]447}
Note: See TracBrowser for help on using the repository browser.