source: Jenkinsfile @ c6f1f3e

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since c6f1f3e was c6f1f3e, checked in by Thierry Delisle <tdelisle@…>, 5 years ago

Jenkins now also computes various speed-up graphs for performance monitoring

  • Property mode set to 100644
File size: 14.5 KB
RevLine 
[a63ad80]1#!groovy
2
[7a230fd]3import groovy.transform.Field
4
[8ecb590]5// For skipping stages
6import org.jenkinsci.plugins.pipeline.modeldefinition.Utils
7
[29f4fe62]8//===========================================================================================================
[9beae23]9// Main loop of the compilation
[29f4fe62]10//===========================================================================================================
[56a9ce6]11
[5307c33]12node('master') {
[5b8413b4]13        // Globals
[4c55047]14        BuildDir  = pwd tmp: true
15        SrcDir    = pwd tmp: false
[5b8413b4]16        Settings  = null
17        StageName = ''
18
19        // Local variables
[9beae23]20        def err = null
21        def log_needed = false
[0ef06b6]22
23        currentBuild.result = "SUCCESS"
24
[9beae23]25        try {
[95fdb0a]26                //Wrap build to add timestamp to command line
27                wrap([$class: 'TimestamperBuildWrapper']) {
[23a14d86]28
[c431138]29                        Settings = prepare_build()
[7aebc62]30
[5307c33]31                        node(Settings.Architecture.node) {
[bf9d323]32                                BuildDir  = pwd tmp: true
33                                SrcDir    = pwd tmp: false
34
[5307c33]35                                clean()
[0dc3ac3]36
[5307c33]37                                checkout()
[fde808df]38
[5307c33]39                                build()
[95fdb0a]40
[5307c33]41                                test()
[95fdb0a]42
[5307c33]43                                benchmark()
[95fdb0a]44
[5307c33]45                                build_doc()
[7359098]46
[5307c33]47                                publish()
48                        }
[9beae23]49
[4c55047]50                        // Update the build directories when exiting the node
51                        BuildDir  = pwd tmp: true
52                        SrcDir    = pwd tmp: false
[9beae23]53                }
[738cf8f]54        }
55
[9beae23]56        //If an exception is caught we need to change the status and remember to
57        //attach the build log to the email
[738cf8f]58        catch (Exception caughtError) {
59                //rethrow error later
60                err = caughtError
61
[e966ec0]62                echo err.toString()
63
[9beae23]64                //An error has occured, the build log is relevent
65                log_needed = true
66
67                //Store the result of the build log
[5b8413b4]68                currentBuild.result = "${StageName} FAILURE".trim()
[738cf8f]69        }
70
71        finally {
[9beae23]72                //Send email with final results if this is not a full build
[13c98a4]73                email(log_needed)
[9beae23]74
[734891d]75                echo 'Build Completed'
76
[738cf8f]77                /* Must re-throw exception to propagate error */
78                if (err) {
79                        throw err
80                }
81        }
82}
[29f4fe62]83//===========================================================================================================
[9beae23]84// Main compilation routines
[29f4fe62]85//===========================================================================================================
[0dc3ac3]86def clean() {
[6c55a3d]87        build_stage('Cleanup', true) {
[0dc3ac3]88                // clean the build by wipping the build directory
[5b8413b4]89                dir(BuildDir) {
[d4cd491]90                        deleteDir()
[ece8a80]91                }
[620dd2b]92        }
[95fdb0a]93}
[29f4fe62]94
[0dc3ac3]95//Compilation script is done here but environnement set-up and error handling is done in main loop
96def checkout() {
[6c55a3d]97        build_stage('Checkout', true) {
[0dc3ac3]98                //checkout the source code and clean the repo
[a336d46]99                final scmVars = checkout scm
100                Settings.GitNewRef = scmVars.GIT_COMMIT
101                Settings.GitOldRef = scmVars.GIT_PREVIOUS_COMMIT
[d3a4564a]102
[a336d46]103                echo GitLogMessage()
[0dc3ac3]104        }
105}
106
[95fdb0a]107def build() {
[e507c11]108        debug = true
109        release = Settings.RunAllTests || Settings.RunBenchmark
110        build_stage('Build : configure', true) {
[50f2cfc]111                // Build outside of the src tree to ease cleaning
[5b8413b4]112                dir (BuildDir) {
[50f2cfc]113                        //Configure the conpilation (Output is not relevant)
114                        //Use the current directory as the installation target so nothing escapes the sandbox
115                        //Also specify the compiler by hand
[3fc5f010]116                        targets=""
[d4510ea]117                        if( Settings.RunAllTests || Settings.RunBenchmark ) {
[6bde81d]118                                targets="--with-target-hosts='host:debug,host:nodebug'"
[3fc5f010]119                        } else {
[6bde81d]120                                targets="--with-target-hosts='host:debug'"
[3fc5f010]121                        }
122
[93fe3154]123                        sh "${SrcDir}/configure CXX=${Settings.Compiler.CXX} CC=${Settings.Compiler.CC} ${Settings.Architecture.flags} ${targets} --quiet"
[f253e4a]124
125                        // Configure libcfa
[e70e54e]126                        sh 'make -j 8 --no-print-directory configure-libcfa'
[e507c11]127                }
128        }
129
130        build_stage('Build : cfa-cpp', true) {
131                // Build outside of the src tree to ease cleaning
132                dir (BuildDir) {
133                        // Build driver
134                        sh 'make -j 8 --no-print-directory -C driver'
135
136                        // Build translator
137                        sh 'make -j 8 --no-print-directory -C src'
138                }
139        }
[1752d0e]140
[e507c11]141        build_stage('Build : libcfa(debug)', debug) {
142                // Build outside of the src tree to ease cleaning
143                dir (BuildDir) {
144                        sh "make -j 8 --no-print-directory -C libcfa/${Settings.Architecture.name}-debug"
145                }
146        }
147
148        build_stage('Build : libcfa(nodebug)', release) {
149                // Build outside of the src tree to ease cleaning
150                dir (BuildDir) {
151                        sh "make -j 8 --no-print-directory -C libcfa/${Settings.Architecture.name}-nodebug"
[50f2cfc]152                }
[620dd2b]153        }
[95fdb0a]154}
[24eecab]155
[95fdb0a]156def test() {
[ab8315f]157        build_stage('Test: short', !Settings.RunAllTests) {
158                dir (BuildDir) {
159                        //Run the tests from the tests directory
160                        sh 'make --no-print-directory -C tests'
161                }
162        }
[9e5f409]163
[f93f35a]164        build_stage('Test: full', Settings.RunAllTests) {
[5b8413b4]165                dir (BuildDir) {
[0dc3ac3]166                        //Run the tests from the tests directory
[05c34c3]167                        sh 'make --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=yes'
168                        sh 'make --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=no '
[9beae23]169                }
[620dd2b]170        }
[95fdb0a]171}
172
173def benchmark() {
[6c55a3d]174        build_stage('Benchmark', Settings.RunBenchmark) {
[5b8413b4]175                dir (BuildDir) {
[0dc3ac3]176                        //Append bench results
[c6f1f3e]177                        sh "make --no-print-directory -C benchmark jenkins arch=${Settings.Architecture.name}"
[0dc3ac3]178                }
[620dd2b]179        }
[9beae23]180}
[efd60d67]181
[95fdb0a]182def build_doc() {
[6c55a3d]183        build_stage('Documentation', Settings.BuildDocumentation) {
[9beae23]184                dir ('doc/user') {
185                        make_doc()
186                }
187
188                dir ('doc/refrat') {
189                        make_doc()
190                }
[620dd2b]191        }
[9beae23]192}
193
[95fdb0a]194def publish() {
[6c55a3d]195        build_stage('Publish', true) {
[95fdb0a]196
[1b3eef8]197                if( Settings.Publish && !Settings.RunBenchmark ) { echo 'No results to publish!!!' }
[95fdb0a]198
[3898392]199                def groupCompile = new PlotGroup('Compilation', 'seconds', true)
200                def groupConcurrency = new PlotGroup('Concurrency', 'nanoseconds', false)
[a2a0065]201
[3898392]202                //Then publish the results
[c6f1f3e]203                do_plot(Settings.RunBenchmark && Settings.Publish, 'compile'       , groupCompile    , 'Compilation')
204                do_plot(Settings.RunBenchmark && Settings.Publish, 'compile-diff'  , groupCompile    , 'Compilation Speed-Up')
205                do_plot(Settings.RunBenchmark && Settings.Publish, 'ctxswitch'     , groupConcurrency, 'Context Switching')
206                do_plot(Settings.RunBenchmark && Settings.Publish, 'ctxswitch-diff', groupConcurrency, 'Context Switching Speed-Up')
207                do_plot(Settings.RunBenchmark && Settings.Publish, 'mutex'         , groupConcurrency, 'Mutual Exclusion')
208                do_plot(Settings.RunBenchmark && Settings.Publish, 'mutex-diff'    , groupConcurrency, 'Mutual Exclusion Speed-Up')
209                do_plot(Settings.RunBenchmark && Settings.Publish, 'signal'        , groupConcurrency, 'Internal and External Scheduling')
210                do_plot(Settings.RunBenchmark && Settings.Publish, 'signal-diff'   , groupConcurrency, 'Internal and External Scheduling Speed-Up')
[620dd2b]211        }
[95fdb0a]212}
213
[29f4fe62]214//===========================================================================================================
215//Routine responsible of sending the email notification once the build is completed
216//===========================================================================================================
[a336d46]217def GitLogMessage() {
218        if (!Settings || !Settings.GitOldRef || !Settings.GitNewRef) return "\nERROR retrieveing git information!\n"
[e8a22a7]219
[9f5bb817]220        sh "${SrcDir}/tools/PrettyGitLogs.sh ${SrcDir} ${BuildDir} ${Settings.GitOldRef} ${Settings.GitNewRef}"
[6e31c43]221
[eda8175]222        def gitUpdate = readFile("${BuildDir}/GIT_UPDATE")
223        def gitLog    = readFile("${BuildDir}/GIT_LOG")
224        def gitDiff   = readFile("${BuildDir}/GIT_DIFF")
[7a927ed0]225
[a336d46]226        return """
[13c98a4]227<pre>
[848fb00]228The branch ${env.BRANCH_NAME} has been updated.
[7a927ed0]229${gitUpdate}
[13c98a4]230</pre>
231
232<p>Check console output at ${env.BUILD_URL} to view the results.</p>
[7b1a604]233
[13c98a4]234<p>- Status --------------------------------------------------------------</p>
[7b1a604]235
[13c98a4]236<p>BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}</p>
[7b1a604]237
[13c98a4]238<p>- Log -----------------------------------------------------------------</p>
[e8a22a7]239
[13c98a4]240<pre>
[7a927ed0]241${gitLog}
[13c98a4]242</pre>
243
244<p>-----------------------------------------------------------------------</p>
245<pre>
[7b1a604]246Summary of changes:
[7a927ed0]247${gitDiff}
[13c98a4]248</pre>
[7b1a604]249"""
[a336d46]250}
251
252//Standard build email notification
[13c98a4]253def email(boolean log) {
[a336d46]254        //Since tokenizer doesn't work, figure stuff out from the environnement variables and command line
255        //Configurations for email format
256        echo 'Notifying users of result'
257
258        def project_name = (env.JOB_NAME =~ /(.+)\/.+/)[0][1].toLowerCase()
259        def email_subject = "[${project_name} git][BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}] - branch ${env.BRANCH_NAME}"
[13c98a4]260        def email_body = """<p>This is an automated email from the Jenkins build machine. It was
[a336d46]261generated because of a git hooks/post-receive script following
[986e260]262a ref change which was pushed to the C\u2200 repository.</p>
[a336d46]263""" + GitLogMessage()
[e8a22a7]264
[13c98a4]265        def email_to = !Settings.IsSandbox ? "cforall@lists.uwaterloo.ca" : "tdelisle@uwaterloo.ca"
[e8a22a7]266
[13c98a4]267        if( Settings && !Settings.Silent ) {
[094a42c]268                //send email notification
269                emailext body: email_body, subject: email_subject, to: email_to, attachLog: log
270        } else {
271                echo "Would send email to: ${email_to}"
272                echo "With title: ${email_subject}"
273                echo "Content: \n${email_body}"
274        }
[e8a22a7]275}
[5b8413b4]276
277//===========================================================================================================
278// Helper classes/variables/routines
279//===========================================================================================================
280//Description of a compiler (Must be serializable since pipelines are persistent)
281class CC_Desc implements Serializable {
[93fe3154]282        public String name
283        public String CXX
[6ebc13f]284        public String CC
[93fe3154]285
[6ebc13f]286        CC_Desc(String name, String CXX, String CC) {
[93fe3154]287                this.name = name
288                this.CXX = CXX
[6ebc13f]289                this.CC = CC
[5b8413b4]290        }
291}
292
293//Description of an architecture (Must be serializable since pipelines are persistent)
294class Arch_Desc implements Serializable {
295        public String name
296        public String flags
[5307c33]297        public String node
[5b8413b4]298
[5307c33]299        Arch_Desc(String name, String flags, String node) {
[5b8413b4]300                this.name  = name
301                this.flags = flags
[5307c33]302                this.node  = node
[5b8413b4]303        }
304}
305
306class BuildSettings implements Serializable {
307        public final CC_Desc Compiler
308        public final Arch_Desc Architecture
309        public final Boolean RunAllTests
310        public final Boolean RunBenchmark
311        public final Boolean BuildDocumentation
312        public final Boolean Publish
313        public final Boolean Silent
314        public final Boolean IsSandbox
315        public final String DescLong
316        public final String DescShort
317
[a336d46]318        public String GitNewRef
319        public String GitOldRef
320
[490cb3c]321        BuildSettings(java.util.Collections$UnmodifiableMap param, String branch) {
[5b8413b4]322                switch( param.Compiler ) {
323                        case 'gcc-6':
324                                this.Compiler = new CC_Desc('gcc-6', 'g++-6', 'gcc-6')
325                        break
326                        case 'gcc-5':
327                                this.Compiler = new CC_Desc('gcc-5', 'g++-5', 'gcc-5')
328                        break
329                        case 'gcc-4.9':
330                                this.Compiler = new CC_Desc('gcc-4.9', 'g++-4.9', 'gcc-4.9')
331                        break
332                        case 'clang':
333                                this.Compiler = new CC_Desc('clang', 'clang++', 'gcc-6')
334                        break
335                        default :
336                                error "Unhandled compiler : ${cc}"
337                }
338
339                switch( param.Architecture ) {
340                        case 'x64':
[a3e8281]341                                this.Architecture = new Arch_Desc('x64', '--host=x86_64', 'x64')
[5b8413b4]342                        break
343                        case 'x86':
[a3e8281]344                                this.Architecture = new Arch_Desc('x86', '--host=i386', 'x86')
[5b8413b4]345                        break
346                        default :
347                                error "Unhandled architecture : ${arch}"
348                }
349
[f95e8f0]350                this.IsSandbox          = (branch == "jenkins-sandbox")
[5b8413b4]351                this.RunAllTests        = param.RunAllTests
[7a230fd]352                this.RunBenchmark       = param.RunBenchmark
[5b8413b4]353                this.BuildDocumentation = param.BuildDocumentation
[7a230fd]354                this.Publish            = param.Publish
[5b8413b4]355                this.Silent             = param.Silent
356
357                def full = param.RunAllTests ? " (Full)" : ""
[490cb3c]358                this.DescShort = "${ this.Compiler.name }:${ this.Architecture.name }${full}"
[5b8413b4]359
[93fe3154]360                this.DescLong = """Compiler              : ${ this.Compiler.name } (${ this.Compiler.CXX }/${ this.Compiler.CC })
[5b8413b4]361Architecture            : ${ this.Architecture.name }
362Arc Flags               : ${ this.Architecture.flags }
363Run All Tests           : ${ this.RunAllTests.toString() }
364Run Benchmark           : ${ this.RunBenchmark.toString() }
365Build Documentation     : ${ this.BuildDocumentation.toString() }
366Publish                 : ${ this.Publish.toString() }
367Silent                  : ${ this.Silent.toString() }
368"""
[a336d46]369
370                this.GitNewRef = ''
371                this.GitOldRef = ''
[5b8413b4]372        }
373}
374
[490cb3c]375class PlotGroup implements Serializable {
376        public String name
377        public String unit
378        public boolean log
379
380        PlotGroup(String name, String unit, boolean log) {
381                this.name = name
382                this.unit = unit
383                this.log = log
384        }
385}
386
[5b8413b4]387def prepare_build() {
388        // prepare the properties
389        properties ([                                                                                                   \
390                [$class: 'ParametersDefinitionProperty',                                                                \
391                        parameterDefinitions: [                                                                         \
392                                [$class: 'ChoiceParameterDefinition',                                           \
393                                        description: 'Which compiler to use',                                   \
394                                        name: 'Compiler',                                                                       \
395                                        choices: 'gcc-6\ngcc-5\ngcc-4.9\nclang',                                        \
396                                        defaultValue: 'gcc-6',                                                          \
397                                ],                                                                                              \
398                                [$class: 'ChoiceParameterDefinition',                                           \
399                                        description: 'The target architecture',                                 \
400                                        name: 'Architecture',                                                           \
401                                        choices: 'x64\nx86',                                                            \
402                                        defaultValue: 'x64',                                                            \
403                                ],                                                                                              \
404                                [$class: 'BooleanParameterDefinition',                                                  \
405                                        description: 'If false, only the quick test suite is ran',              \
406                                        name: 'RunAllTests',                                                            \
407                                        defaultValue: false,                                                            \
408                                ],                                                                                              \
409                                [$class: 'BooleanParameterDefinition',                                                  \
410                                        description: 'If true, jenkins also runs benchmarks',           \
411                                        name: 'RunBenchmark',                                                           \
412                                        defaultValue: false,                                                            \
413                                ],                                                                                              \
414                                [$class: 'BooleanParameterDefinition',                                                  \
415                                        description: 'If true, jenkins also builds documentation',              \
416                                        name: 'BuildDocumentation',                                                     \
417                                        defaultValue: true,                                                             \
418                                ],                                                                                              \
419                                [$class: 'BooleanParameterDefinition',                                                  \
420                                        description: 'If true, jenkins also publishes results',                 \
421                                        name: 'Publish',                                                                        \
422                                        defaultValue: false,                                                            \
423                                ],                                                                                              \
424                                [$class: 'BooleanParameterDefinition',                                                  \
425                                        description: 'If true, jenkins will not send emails',           \
426                                        name: 'Silent',                                                                         \
427                                        defaultValue: false,                                                            \
428                                ],                                                                                              \
429                        ],
430                ]])
431
[4c55047]432        // It's unfortunate but it looks like we need to checkout the entire repo just to get the pretty git printer
433        checkout scm
[2407853]434
[490cb3c]435        final settings = new BuildSettings(params, env.BRANCH_NAME)
[5b8413b4]436
437        currentBuild.description = settings.DescShort
438        echo                       settings.DescLong
439
440        return settings
441}
442
[6c55a3d]443def build_stage(String name, boolean run, Closure block ) {
[5b8413b4]444        StageName = name
445        echo " -------- ${StageName} -------- "
[8ecb590]446        if(run) {
447                stage(name, block)
448        } else {
449                stage(name) { Utils.markStageSkippedForConditional(STAGE_NAME) }
450        }
[5b8413b4]451}
452
453def make_doc() {
454        def err = null
455        try {
456                sh 'make clean > /dev/null'
457                sh 'make > /dev/null 2>&1'
458        }
459        catch (Exception caughtError) {
460                err = caughtError //rethrow error later
[65f4a51]461                sh 'cat build/*.log'
[5b8413b4]462        }
463        finally {
464                if (err) throw err // Must re-throw exception to propagate error
465        }
[a2a0065]466}
467
[1b3eef8]468def do_plot(boolean new_data, String file, PlotGroup group, String title) {
[8d63649]469
[1b3eef8]470        if(new_data) {
471                echo "Publishing new data"
472        }
473
[cdcd53dc]474        def series = new_data ? [[
[df57a84]475                                file: "${file}.csv",
[3c40dc2a]476                                exclusionValues: '',
477                                displayTableFlag: false,
478                                inclusionFlag: 'OFF',
479                                url: ''
[cdcd53dc]480                        ]] : [];
[8d63649]481
482        echo "file is ${BuildDir}/benchmark/${file}.csv, group ${group}, title ${title}"
483        dir("${BuildDir}/benchmark/") {
484                plot csvFileName: "cforall-${env.BRANCH_NAME}-${file}.csv",
485                        csvSeries: series,
[490cb3c]486                        group: "${group.name}",
[3c40dc2a]487                        title: "${title}",
488                        style: 'lineSimple',
489                        exclZero: false,
490                        keepRecords: false,
[490cb3c]491                        logarithmic: group.log,
[3c40dc2a]492                        numBuilds: '120',
493                        useDescr: true,
[490cb3c]494                        yaxis: group.unit,
[3c40dc2a]495                        yaxisMaximum: '',
496                        yaxisMinimum: ''
[df57a84]497        }
498}
Note: See TracBrowser for help on using the repository browser.