source: Jenkinsfile @ 143e6f3

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

Trying out archive build failures

  • Property mode set to 100644
File size: 14.8 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
[143e6f3]167                        sh """make --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=yes archiveerrors=${BuildDir}/tests/crashes/debug"""
168                        sh """make --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=no  archiveerrors=${BuildDir}/tests/crashes/nodebug"""
169
170                        if(fileExists "${BuildDir}/tests/crashes") {
171                                archiveArtifacts artifacts: "${BuildDir}/tests/crashes", fingerprint: true
172                        }
[9beae23]173                }
[620dd2b]174        }
[95fdb0a]175}
176
177def benchmark() {
[6c55a3d]178        build_stage('Benchmark', Settings.RunBenchmark) {
[5b8413b4]179                dir (BuildDir) {
[0dc3ac3]180                        //Append bench results
[c6f1f3e]181                        sh "make --no-print-directory -C benchmark jenkins arch=${Settings.Architecture.name}"
[0dc3ac3]182                }
[620dd2b]183        }
[9beae23]184}
[efd60d67]185
[95fdb0a]186def build_doc() {
[6c55a3d]187        build_stage('Documentation', Settings.BuildDocumentation) {
[9beae23]188                dir ('doc/user') {
189                        make_doc()
190                }
191
192                dir ('doc/refrat') {
193                        make_doc()
194                }
[620dd2b]195        }
[9beae23]196}
197
[95fdb0a]198def publish() {
[6c55a3d]199        build_stage('Publish', true) {
[95fdb0a]200
[1b3eef8]201                if( Settings.Publish && !Settings.RunBenchmark ) { echo 'No results to publish!!!' }
[95fdb0a]202
[3221a2b]203                def groupCompile = new PlotGroup('Compilation', 'duration (s) - lower is better', true)
204                def groupConcurrency = new PlotGroup('Concurrency', 'duration (n) - lower is better', false)
[a2a0065]205
[3898392]206                //Then publish the results
[3221a2b]207                do_plot(Settings.RunBenchmark && Settings.Publish, 'compile'       , groupCompile    , false, 'Compilation')
208                do_plot(Settings.RunBenchmark && Settings.Publish, 'compile.diff'  , groupCompile    , true , 'Compilation (relative)')
209                do_plot(Settings.RunBenchmark && Settings.Publish, 'ctxswitch'     , groupConcurrency, false, 'Context Switching')
210                do_plot(Settings.RunBenchmark && Settings.Publish, 'ctxswitch.diff', groupConcurrency, true , 'Context Switching (relative)')
211                do_plot(Settings.RunBenchmark && Settings.Publish, 'mutex'         , groupConcurrency, false, 'Mutual Exclusion')
212                do_plot(Settings.RunBenchmark && Settings.Publish, 'mutex.diff'    , groupConcurrency, true , 'Mutual Exclusion (relative)')
213                do_plot(Settings.RunBenchmark && Settings.Publish, 'signal'        , groupConcurrency, false, 'Internal and External Scheduling')
214                do_plot(Settings.RunBenchmark && Settings.Publish, 'signal.diff'   , groupConcurrency, true , 'Internal and External Scheduling (relative)')
[620dd2b]215        }
[95fdb0a]216}
217
[29f4fe62]218//===========================================================================================================
219//Routine responsible of sending the email notification once the build is completed
220//===========================================================================================================
[a336d46]221def GitLogMessage() {
222        if (!Settings || !Settings.GitOldRef || !Settings.GitNewRef) return "\nERROR retrieveing git information!\n"
[e8a22a7]223
[9f5bb817]224        sh "${SrcDir}/tools/PrettyGitLogs.sh ${SrcDir} ${BuildDir} ${Settings.GitOldRef} ${Settings.GitNewRef}"
[6e31c43]225
[eda8175]226        def gitUpdate = readFile("${BuildDir}/GIT_UPDATE")
227        def gitLog    = readFile("${BuildDir}/GIT_LOG")
228        def gitDiff   = readFile("${BuildDir}/GIT_DIFF")
[7a927ed0]229
[a336d46]230        return """
[13c98a4]231<pre>
[848fb00]232The branch ${env.BRANCH_NAME} has been updated.
[7a927ed0]233${gitUpdate}
[13c98a4]234</pre>
235
236<p>Check console output at ${env.BUILD_URL} to view the results.</p>
[7b1a604]237
[13c98a4]238<p>- Status --------------------------------------------------------------</p>
[7b1a604]239
[13c98a4]240<p>BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}</p>
[7b1a604]241
[13c98a4]242<p>- Log -----------------------------------------------------------------</p>
[e8a22a7]243
[13c98a4]244<pre>
[7a927ed0]245${gitLog}
[13c98a4]246</pre>
247
248<p>-----------------------------------------------------------------------</p>
249<pre>
[7b1a604]250Summary of changes:
[7a927ed0]251${gitDiff}
[13c98a4]252</pre>
[7b1a604]253"""
[a336d46]254}
255
256//Standard build email notification
[13c98a4]257def email(boolean log) {
[a336d46]258        //Since tokenizer doesn't work, figure stuff out from the environnement variables and command line
259        //Configurations for email format
260        echo 'Notifying users of result'
261
262        def project_name = (env.JOB_NAME =~ /(.+)\/.+/)[0][1].toLowerCase()
263        def email_subject = "[${project_name} git][BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}] - branch ${env.BRANCH_NAME}"
[13c98a4]264        def email_body = """<p>This is an automated email from the Jenkins build machine. It was
[a336d46]265generated because of a git hooks/post-receive script following
[986e260]266a ref change which was pushed to the C\u2200 repository.</p>
[a336d46]267""" + GitLogMessage()
[e8a22a7]268
[13c98a4]269        def email_to = !Settings.IsSandbox ? "cforall@lists.uwaterloo.ca" : "tdelisle@uwaterloo.ca"
[e8a22a7]270
[13c98a4]271        if( Settings && !Settings.Silent ) {
[094a42c]272                //send email notification
273                emailext body: email_body, subject: email_subject, to: email_to, attachLog: log
274        } else {
275                echo "Would send email to: ${email_to}"
276                echo "With title: ${email_subject}"
277                echo "Content: \n${email_body}"
278        }
[e8a22a7]279}
[5b8413b4]280
281//===========================================================================================================
282// Helper classes/variables/routines
283//===========================================================================================================
284//Description of a compiler (Must be serializable since pipelines are persistent)
285class CC_Desc implements Serializable {
[93fe3154]286        public String name
287        public String CXX
[6ebc13f]288        public String CC
[93fe3154]289
[6ebc13f]290        CC_Desc(String name, String CXX, String CC) {
[93fe3154]291                this.name = name
292                this.CXX = CXX
[6ebc13f]293                this.CC = CC
[5b8413b4]294        }
295}
296
297//Description of an architecture (Must be serializable since pipelines are persistent)
298class Arch_Desc implements Serializable {
299        public String name
300        public String flags
[5307c33]301        public String node
[5b8413b4]302
[5307c33]303        Arch_Desc(String name, String flags, String node) {
[5b8413b4]304                this.name  = name
305                this.flags = flags
[5307c33]306                this.node  = node
[5b8413b4]307        }
308}
309
310class BuildSettings implements Serializable {
311        public final CC_Desc Compiler
312        public final Arch_Desc Architecture
313        public final Boolean RunAllTests
314        public final Boolean RunBenchmark
315        public final Boolean BuildDocumentation
316        public final Boolean Publish
317        public final Boolean Silent
318        public final Boolean IsSandbox
319        public final String DescLong
320        public final String DescShort
321
[a336d46]322        public String GitNewRef
323        public String GitOldRef
324
[490cb3c]325        BuildSettings(java.util.Collections$UnmodifiableMap param, String branch) {
[5b8413b4]326                switch( param.Compiler ) {
327                        case 'gcc-6':
328                                this.Compiler = new CC_Desc('gcc-6', 'g++-6', 'gcc-6')
329                        break
330                        case 'gcc-5':
331                                this.Compiler = new CC_Desc('gcc-5', 'g++-5', 'gcc-5')
332                        break
333                        case 'gcc-4.9':
334                                this.Compiler = new CC_Desc('gcc-4.9', 'g++-4.9', 'gcc-4.9')
335                        break
336                        case 'clang':
337                                this.Compiler = new CC_Desc('clang', 'clang++', 'gcc-6')
338                        break
339                        default :
340                                error "Unhandled compiler : ${cc}"
341                }
342
343                switch( param.Architecture ) {
344                        case 'x64':
[a3e8281]345                                this.Architecture = new Arch_Desc('x64', '--host=x86_64', 'x64')
[5b8413b4]346                        break
347                        case 'x86':
[a3e8281]348                                this.Architecture = new Arch_Desc('x86', '--host=i386', 'x86')
[5b8413b4]349                        break
350                        default :
351                                error "Unhandled architecture : ${arch}"
352                }
353
[f95e8f0]354                this.IsSandbox          = (branch == "jenkins-sandbox")
[5b8413b4]355                this.RunAllTests        = param.RunAllTests
[7a230fd]356                this.RunBenchmark       = param.RunBenchmark
[5b8413b4]357                this.BuildDocumentation = param.BuildDocumentation
[7a230fd]358                this.Publish            = param.Publish
[5b8413b4]359                this.Silent             = param.Silent
360
361                def full = param.RunAllTests ? " (Full)" : ""
[490cb3c]362                this.DescShort = "${ this.Compiler.name }:${ this.Architecture.name }${full}"
[5b8413b4]363
[93fe3154]364                this.DescLong = """Compiler              : ${ this.Compiler.name } (${ this.Compiler.CXX }/${ this.Compiler.CC })
[5b8413b4]365Architecture            : ${ this.Architecture.name }
366Arc Flags               : ${ this.Architecture.flags }
367Run All Tests           : ${ this.RunAllTests.toString() }
368Run Benchmark           : ${ this.RunBenchmark.toString() }
369Build Documentation     : ${ this.BuildDocumentation.toString() }
370Publish                 : ${ this.Publish.toString() }
371Silent                  : ${ this.Silent.toString() }
372"""
[a336d46]373
374                this.GitNewRef = ''
375                this.GitOldRef = ''
[5b8413b4]376        }
377}
378
[490cb3c]379class PlotGroup implements Serializable {
380        public String name
381        public String unit
382        public boolean log
383
384        PlotGroup(String name, String unit, boolean log) {
385                this.name = name
386                this.unit = unit
387                this.log = log
388        }
389}
390
[5b8413b4]391def prepare_build() {
392        // prepare the properties
393        properties ([                                                                                                   \
394                [$class: 'ParametersDefinitionProperty',                                                                \
395                        parameterDefinitions: [                                                                         \
396                                [$class: 'ChoiceParameterDefinition',                                           \
397                                        description: 'Which compiler to use',                                   \
398                                        name: 'Compiler',                                                                       \
399                                        choices: 'gcc-6\ngcc-5\ngcc-4.9\nclang',                                        \
400                                        defaultValue: 'gcc-6',                                                          \
401                                ],                                                                                              \
402                                [$class: 'ChoiceParameterDefinition',                                           \
403                                        description: 'The target architecture',                                 \
404                                        name: 'Architecture',                                                           \
405                                        choices: 'x64\nx86',                                                            \
406                                        defaultValue: 'x64',                                                            \
407                                ],                                                                                              \
408                                [$class: 'BooleanParameterDefinition',                                                  \
409                                        description: 'If false, only the quick test suite is ran',              \
410                                        name: 'RunAllTests',                                                            \
411                                        defaultValue: false,                                                            \
412                                ],                                                                                              \
413                                [$class: 'BooleanParameterDefinition',                                                  \
414                                        description: 'If true, jenkins also runs benchmarks',           \
415                                        name: 'RunBenchmark',                                                           \
416                                        defaultValue: false,                                                            \
417                                ],                                                                                              \
418                                [$class: 'BooleanParameterDefinition',                                                  \
419                                        description: 'If true, jenkins also builds documentation',              \
420                                        name: 'BuildDocumentation',                                                     \
421                                        defaultValue: true,                                                             \
422                                ],                                                                                              \
423                                [$class: 'BooleanParameterDefinition',                                                  \
424                                        description: 'If true, jenkins also publishes results',                 \
425                                        name: 'Publish',                                                                        \
426                                        defaultValue: false,                                                            \
427                                ],                                                                                              \
428                                [$class: 'BooleanParameterDefinition',                                                  \
429                                        description: 'If true, jenkins will not send emails',           \
430                                        name: 'Silent',                                                                         \
431                                        defaultValue: false,                                                            \
432                                ],                                                                                              \
433                        ],
434                ]])
435
[4c55047]436        // It's unfortunate but it looks like we need to checkout the entire repo just to get the pretty git printer
437        checkout scm
[2407853]438
[490cb3c]439        final settings = new BuildSettings(params, env.BRANCH_NAME)
[5b8413b4]440
441        currentBuild.description = settings.DescShort
442        echo                       settings.DescLong
443
444        return settings
445}
446
[6c55a3d]447def build_stage(String name, boolean run, Closure block ) {
[5b8413b4]448        StageName = name
449        echo " -------- ${StageName} -------- "
[8ecb590]450        if(run) {
451                stage(name, block)
452        } else {
453                stage(name) { Utils.markStageSkippedForConditional(STAGE_NAME) }
454        }
[5b8413b4]455}
456
457def make_doc() {
458        def err = null
459        try {
460                sh 'make clean > /dev/null'
461                sh 'make > /dev/null 2>&1'
462        }
463        catch (Exception caughtError) {
464                err = caughtError //rethrow error later
[65f4a51]465                sh 'cat build/*.log'
[5b8413b4]466        }
467        finally {
468                if (err) throw err // Must re-throw exception to propagate error
469        }
[a2a0065]470}
471
[3221a2b]472def do_plot(boolean new_data, String file, PlotGroup group, boolean relative, String title) {
[8d63649]473
[1b3eef8]474        if(new_data) {
475                echo "Publishing new data"
476        }
477
[cdcd53dc]478        def series = new_data ? [[
[df57a84]479                                file: "${file}.csv",
[3c40dc2a]480                                exclusionValues: '',
481                                displayTableFlag: false,
482                                inclusionFlag: 'OFF',
483                                url: ''
[cdcd53dc]484                        ]] : [];
[8d63649]485
486        echo "file is ${BuildDir}/benchmark/${file}.csv, group ${group}, title ${title}"
487        dir("${BuildDir}/benchmark/") {
488                plot csvFileName: "cforall-${env.BRANCH_NAME}-${file}.csv",
489                        csvSeries: series,
[490cb3c]490                        group: "${group.name}",
[3c40dc2a]491                        title: "${title}",
492                        style: 'lineSimple',
493                        exclZero: false,
494                        keepRecords: false,
[3221a2b]495                        logarithmic: !relative && group.log,
[3c40dc2a]496                        numBuilds: '120',
497                        useDescr: true,
[490cb3c]498                        yaxis: group.unit,
[3c40dc2a]499                        yaxisMaximum: '',
500                        yaxisMinimum: ''
[df57a84]501        }
502}
Note: See TracBrowser for help on using the repository browser.