source: Jenkinsfile @ aa8e8301

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

No longer using node('master') for build

  • Property mode set to 100644
File size: 15.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
[aa8e8301]12// Globals
13BuildDir  = null
14SrcDir    = null
15Settings  = null
16StageName = ''
[5b8413b4]17
[aa8e8301]18// Local variables
19def err = null
20def log_needed = false
[0ef06b6]21
[aa8e8301]22currentBuild.result = "SUCCESS"
[0ef06b6]23
[aa8e8301]24try {
25        //Wrap build to add timestamp to command line
26        wrap([$class: 'TimestamperBuildWrapper']) {
[23a14d86]27
[aa8e8301]28                Settings = prepare_build()
[7aebc62]29
[aa8e8301]30                node(Settings.Architecture.node) {
31                        BuildDir  = pwd tmp: true
32                        SrcDir    = pwd tmp: false
[0dc3ac3]33
[aa8e8301]34                        clean()
[fde808df]35
[aa8e8301]36                        checkout()
[95fdb0a]37
[aa8e8301]38                        build()
[95fdb0a]39
[aa8e8301]40                        test()
[95fdb0a]41
[aa8e8301]42                        benchmark()
[7359098]43
[aa8e8301]44                        build_doc()
[9beae23]45
[aa8e8301]46                        publish()
[9beae23]47                }
[738cf8f]48        }
[aa8e8301]49}
[738cf8f]50
[aa8e8301]51//If an exception is caught we need to change the status and remember to
52//attach the build log to the email
53catch (Exception caughtError) {
54        //rethrow error later
55        err = caughtError
[738cf8f]56
[aa8e8301]57        echo err.toString()
[e966ec0]58
[aa8e8301]59        //An error has occured, the build log is relevent
60        log_needed = true
[9beae23]61
[aa8e8301]62        //Store the result of the build log
63        currentBuild.result = "${StageName} FAILURE".trim()
64}
[738cf8f]65
[aa8e8301]66finally {
67        //Send email with final results if this is not a full build
68        email(log_needed)
[9beae23]69
[aa8e8301]70        echo 'Build Completed'
[734891d]71
[aa8e8301]72        /* Must re-throw exception to propagate error */
73        if (err) {
74                throw err
[738cf8f]75        }
76}
[aa8e8301]77
[29f4fe62]78//===========================================================================================================
[9beae23]79// Main compilation routines
[29f4fe62]80//===========================================================================================================
[0dc3ac3]81def clean() {
[6c55a3d]82        build_stage('Cleanup', true) {
[0dc3ac3]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() {
[6c55a3d]92        build_stage('Checkout', true) {
[0dc3ac3]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() {
[e507c11]103        debug = true
104        release = Settings.RunAllTests || Settings.RunBenchmark
105        build_stage('Build : configure', true) {
[50f2cfc]106                // Build outside of the src tree to ease cleaning
[5b8413b4]107                dir (BuildDir) {
[50f2cfc]108                        //Configure the conpilation (Output is not relevant)
109                        //Use the current directory as the installation target so nothing escapes the sandbox
110                        //Also specify the compiler by hand
[3fc5f010]111                        targets=""
[d4510ea]112                        if( Settings.RunAllTests || Settings.RunBenchmark ) {
[6bde81d]113                                targets="--with-target-hosts='host:debug,host:nodebug'"
[3fc5f010]114                        } else {
[6bde81d]115                                targets="--with-target-hosts='host:debug'"
[3fc5f010]116                        }
117
[93fe3154]118                        sh "${SrcDir}/configure CXX=${Settings.Compiler.CXX} CC=${Settings.Compiler.CC} ${Settings.Architecture.flags} ${targets} --quiet"
[f253e4a]119
120                        // Configure libcfa
[e70e54e]121                        sh 'make -j 8 --no-print-directory configure-libcfa'
[e507c11]122                }
123        }
124
125        build_stage('Build : cfa-cpp', true) {
126                // Build outside of the src tree to ease cleaning
127                dir (BuildDir) {
128                        // Build driver
129                        sh 'make -j 8 --no-print-directory -C driver'
130
131                        // Build translator
132                        sh 'make -j 8 --no-print-directory -C src'
133                }
134        }
[1752d0e]135
[e507c11]136        build_stage('Build : libcfa(debug)', debug) {
137                // Build outside of the src tree to ease cleaning
138                dir (BuildDir) {
139                        sh "make -j 8 --no-print-directory -C libcfa/${Settings.Architecture.name}-debug"
140                }
141        }
142
143        build_stage('Build : libcfa(nodebug)', release) {
144                // Build outside of the src tree to ease cleaning
145                dir (BuildDir) {
146                        sh "make -j 8 --no-print-directory -C libcfa/${Settings.Architecture.name}-nodebug"
[50f2cfc]147                }
[620dd2b]148        }
[95fdb0a]149}
[24eecab]150
[95fdb0a]151def test() {
[4c1b9ea8]152        try {
153                build_stage('Test: short', !Settings.RunAllTests) {
154                        dir (BuildDir) {
[3e93c00]155                                //Run the tests from the tests directory
[4c51aca]156                                sh "make --no-print-directory -C tests archiveerrors=${BuildDir}/tests/crashes/short"
[3e93c00]157                        }
[4c1b9ea8]158                }
159
160                build_stage('Test: full', Settings.RunAllTests) {
161                        dir (BuildDir) {
162                                        //Run the tests from the tests directory
[4c51aca]163                                        sh """make --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=yes archiveerrors=${BuildDir}/tests/crashes/full-debug"""
164                                        sh """make --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=no  archiveerrors=${BuildDir}/tests/crashes/full-nodebug"""
[143e6f3]165                        }
[9beae23]166                }
[620dd2b]167        }
[4c1b9ea8]168        catch (Exception err) {
169                echo "Archiving core dumps"
[c95fdc9]170                dir (BuildDir) {
171                        archiveArtifacts artifacts: "tests/crashes/**/*", fingerprint: true
172                }
[4c1b9ea8]173                throw err
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//===========================================================================================================
[6b6c26e]221@NonCPS
222def SplitLines(String text) {
223        def list = []
224
225        text.eachLine {
226                list += it
227        }
228
229        return list
230}
231
[a336d46]232def GitLogMessage() {
233        if (!Settings || !Settings.GitOldRef || !Settings.GitNewRef) return "\nERROR retrieveing git information!\n"
[e8a22a7]234
[fce01e7]235        def oldRef = Settings.GitOldRef
236        def newRef = Settings.GitNewRef
[6badd87]237
[fdb6ac6]238        def revText = sh(returnStdout: true, script: "git rev-list ${oldRef}..${newRef}").trim()
[6b6c26e]239        def revList = SplitLines( revText )
[6e31c43]240
[fdb6ac6]241        def gitUpdate = ""
242        revList.each { rev ->
[249091f]243                def type = sh(returnStdout: true, script: "git cat-file -t ${rev}").trim()
[fce01e7]244                gitUpdate = gitUpdate + "       via  ${rev} (${type})"
245        }
246
247        def rev = oldRef
[249091f]248        def type = sh(returnStdout: true, script: "git cat-file -t ${rev}").trim()
249        gitUpdate = gitUpdate + "      from  ${rev} (${type})"
[fce01e7]250
[249091f]251        def gitLog    = sh(returnStdout: true, script: "git rev-list --format=short ${oldRef}...${newRef}").trim()
[fce01e7]252
[249091f]253        def gitDiff   = sh(returnStdout: true, script: "git diff --stat --color ${newRef} ${oldRef}").trim()
[fce01e7]254        gitDiff = gitDiff.replace('[32m', '<span style="color: #00AA00;">')
255        gitDiff = gitDiff.replace('[31m', '<span style="color: #AA0000;">')
256        gitDiff = gitDiff.replace('[m', '</span>')
[7a927ed0]257
[a336d46]258        return """
[13c98a4]259<pre>
[848fb00]260The branch ${env.BRANCH_NAME} has been updated.
[7a927ed0]261${gitUpdate}
[13c98a4]262</pre>
263
264<p>Check console output at ${env.BUILD_URL} to view the results.</p>
[7b1a604]265
[13c98a4]266<p>- Status --------------------------------------------------------------</p>
[7b1a604]267
[13c98a4]268<p>BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}</p>
[7b1a604]269
[13c98a4]270<p>- Log -----------------------------------------------------------------</p>
[e8a22a7]271
[13c98a4]272<pre>
[7a927ed0]273${gitLog}
[13c98a4]274</pre>
275
276<p>-----------------------------------------------------------------------</p>
277<pre>
[7b1a604]278Summary of changes:
[7a927ed0]279${gitDiff}
[13c98a4]280</pre>
[7b1a604]281"""
[a336d46]282}
283
284//Standard build email notification
[13c98a4]285def email(boolean log) {
[a336d46]286        //Since tokenizer doesn't work, figure stuff out from the environnement variables and command line
287        //Configurations for email format
288        echo 'Notifying users of result'
289
290        def project_name = (env.JOB_NAME =~ /(.+)\/.+/)[0][1].toLowerCase()
291        def email_subject = "[${project_name} git][BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}] - branch ${env.BRANCH_NAME}"
[13c98a4]292        def email_body = """<p>This is an automated email from the Jenkins build machine. It was
[a336d46]293generated because of a git hooks/post-receive script following
[986e260]294a ref change which was pushed to the C\u2200 repository.</p>
[a336d46]295""" + GitLogMessage()
[e8a22a7]296
[13c98a4]297        def email_to = !Settings.IsSandbox ? "cforall@lists.uwaterloo.ca" : "tdelisle@uwaterloo.ca"
[e8a22a7]298
[13c98a4]299        if( Settings && !Settings.Silent ) {
[094a42c]300                //send email notification
301                emailext body: email_body, subject: email_subject, to: email_to, attachLog: log
302        } else {
303                echo "Would send email to: ${email_to}"
304                echo "With title: ${email_subject}"
305                echo "Content: \n${email_body}"
306        }
[e8a22a7]307}
[5b8413b4]308
309//===========================================================================================================
310// Helper classes/variables/routines
311//===========================================================================================================
312//Description of a compiler (Must be serializable since pipelines are persistent)
313class CC_Desc implements Serializable {
[93fe3154]314        public String name
315        public String CXX
[6ebc13f]316        public String CC
[93fe3154]317
[6ebc13f]318        CC_Desc(String name, String CXX, String CC) {
[93fe3154]319                this.name = name
320                this.CXX = CXX
[6ebc13f]321                this.CC = CC
[5b8413b4]322        }
323}
324
325//Description of an architecture (Must be serializable since pipelines are persistent)
326class Arch_Desc implements Serializable {
327        public String name
328        public String flags
[5307c33]329        public String node
[5b8413b4]330
[5307c33]331        Arch_Desc(String name, String flags, String node) {
[5b8413b4]332                this.name  = name
333                this.flags = flags
[5307c33]334                this.node  = node
[5b8413b4]335        }
336}
337
338class BuildSettings implements Serializable {
339        public final CC_Desc Compiler
340        public final Arch_Desc Architecture
341        public final Boolean RunAllTests
342        public final Boolean RunBenchmark
343        public final Boolean BuildDocumentation
344        public final Boolean Publish
345        public final Boolean Silent
346        public final Boolean IsSandbox
347        public final String DescLong
348        public final String DescShort
349
[a336d46]350        public String GitNewRef
351        public String GitOldRef
352
[490cb3c]353        BuildSettings(java.util.Collections$UnmodifiableMap param, String branch) {
[5b8413b4]354                switch( param.Compiler ) {
355                        case 'gcc-6':
356                                this.Compiler = new CC_Desc('gcc-6', 'g++-6', 'gcc-6')
357                        break
358                        case 'gcc-5':
359                                this.Compiler = new CC_Desc('gcc-5', 'g++-5', 'gcc-5')
360                        break
361                        case 'gcc-4.9':
362                                this.Compiler = new CC_Desc('gcc-4.9', 'g++-4.9', 'gcc-4.9')
363                        break
364                        case 'clang':
365                                this.Compiler = new CC_Desc('clang', 'clang++', 'gcc-6')
366                        break
367                        default :
368                                error "Unhandled compiler : ${cc}"
369                }
370
371                switch( param.Architecture ) {
372                        case 'x64':
[a3e8281]373                                this.Architecture = new Arch_Desc('x64', '--host=x86_64', 'x64')
[5b8413b4]374                        break
375                        case 'x86':
[a3e8281]376                                this.Architecture = new Arch_Desc('x86', '--host=i386', 'x86')
[5b8413b4]377                        break
378                        default :
379                                error "Unhandled architecture : ${arch}"
380                }
381
[f95e8f0]382                this.IsSandbox          = (branch == "jenkins-sandbox")
[5b8413b4]383                this.RunAllTests        = param.RunAllTests
[7a230fd]384                this.RunBenchmark       = param.RunBenchmark
[5b8413b4]385                this.BuildDocumentation = param.BuildDocumentation
[7a230fd]386                this.Publish            = param.Publish
[5b8413b4]387                this.Silent             = param.Silent
388
389                def full = param.RunAllTests ? " (Full)" : ""
[490cb3c]390                this.DescShort = "${ this.Compiler.name }:${ this.Architecture.name }${full}"
[5b8413b4]391
[93fe3154]392                this.DescLong = """Compiler              : ${ this.Compiler.name } (${ this.Compiler.CXX }/${ this.Compiler.CC })
[5b8413b4]393Architecture            : ${ this.Architecture.name }
394Arc Flags               : ${ this.Architecture.flags }
395Run All Tests           : ${ this.RunAllTests.toString() }
396Run Benchmark           : ${ this.RunBenchmark.toString() }
397Build Documentation     : ${ this.BuildDocumentation.toString() }
398Publish                 : ${ this.Publish.toString() }
399Silent                  : ${ this.Silent.toString() }
400"""
[a336d46]401
402                this.GitNewRef = ''
403                this.GitOldRef = ''
[5b8413b4]404        }
405}
406
[490cb3c]407class PlotGroup implements Serializable {
408        public String name
409        public String unit
410        public boolean log
411
412        PlotGroup(String name, String unit, boolean log) {
413                this.name = name
414                this.unit = unit
415                this.log = log
416        }
417}
418
[5b8413b4]419def prepare_build() {
420        // prepare the properties
421        properties ([                                                                                                   \
422                [$class: 'ParametersDefinitionProperty',                                                                \
423                        parameterDefinitions: [                                                                         \
424                                [$class: 'ChoiceParameterDefinition',                                           \
425                                        description: 'Which compiler to use',                                   \
426                                        name: 'Compiler',                                                                       \
427                                        choices: 'gcc-6\ngcc-5\ngcc-4.9\nclang',                                        \
428                                        defaultValue: 'gcc-6',                                                          \
429                                ],                                                                                              \
430                                [$class: 'ChoiceParameterDefinition',                                           \
431                                        description: 'The target architecture',                                 \
432                                        name: 'Architecture',                                                           \
433                                        choices: 'x64\nx86',                                                            \
434                                        defaultValue: 'x64',                                                            \
435                                ],                                                                                              \
436                                [$class: 'BooleanParameterDefinition',                                                  \
437                                        description: 'If false, only the quick test suite is ran',              \
438                                        name: 'RunAllTests',                                                            \
439                                        defaultValue: false,                                                            \
440                                ],                                                                                              \
441                                [$class: 'BooleanParameterDefinition',                                                  \
442                                        description: 'If true, jenkins also runs benchmarks',           \
443                                        name: 'RunBenchmark',                                                           \
444                                        defaultValue: false,                                                            \
445                                ],                                                                                              \
446                                [$class: 'BooleanParameterDefinition',                                                  \
447                                        description: 'If true, jenkins also builds documentation',              \
448                                        name: 'BuildDocumentation',                                                     \
449                                        defaultValue: true,                                                             \
450                                ],                                                                                              \
451                                [$class: 'BooleanParameterDefinition',                                                  \
452                                        description: 'If true, jenkins also publishes results',                 \
453                                        name: 'Publish',                                                                        \
454                                        defaultValue: false,                                                            \
455                                ],                                                                                              \
456                                [$class: 'BooleanParameterDefinition',                                                  \
457                                        description: 'If true, jenkins will not send emails',           \
458                                        name: 'Silent',                                                                         \
459                                        defaultValue: false,                                                            \
460                                ],                                                                                              \
461                        ],
462                ]])
463
[4c55047]464        // It's unfortunate but it looks like we need to checkout the entire repo just to get the pretty git printer
465        checkout scm
[2407853]466
[490cb3c]467        final settings = new BuildSettings(params, env.BRANCH_NAME)
[5b8413b4]468
469        currentBuild.description = settings.DescShort
470        echo                       settings.DescLong
471
472        return settings
473}
474
[6c55a3d]475def build_stage(String name, boolean run, Closure block ) {
[5b8413b4]476        StageName = name
477        echo " -------- ${StageName} -------- "
[8ecb590]478        if(run) {
479                stage(name, block)
480        } else {
481                stage(name) { Utils.markStageSkippedForConditional(STAGE_NAME) }
482        }
[5b8413b4]483}
484
485def make_doc() {
486        def err = null
487        try {
488                sh 'make clean > /dev/null'
489                sh 'make > /dev/null 2>&1'
490        }
491        catch (Exception caughtError) {
492                err = caughtError //rethrow error later
[65f4a51]493                sh 'cat build/*.log'
[5b8413b4]494        }
495        finally {
496                if (err) throw err // Must re-throw exception to propagate error
497        }
[a2a0065]498}
499
[3221a2b]500def do_plot(boolean new_data, String file, PlotGroup group, boolean relative, String title) {
[8d63649]501
[1b3eef8]502        if(new_data) {
503                echo "Publishing new data"
504        }
505
[cdcd53dc]506        def series = new_data ? [[
[df57a84]507                                file: "${file}.csv",
[3c40dc2a]508                                exclusionValues: '',
509                                displayTableFlag: false,
510                                inclusionFlag: 'OFF',
511                                url: ''
[cdcd53dc]512                        ]] : [];
[8d63649]513
514        echo "file is ${BuildDir}/benchmark/${file}.csv, group ${group}, title ${title}"
515        dir("${BuildDir}/benchmark/") {
516                plot csvFileName: "cforall-${env.BRANCH_NAME}-${file}.csv",
517                        csvSeries: series,
[490cb3c]518                        group: "${group.name}",
[3c40dc2a]519                        title: "${title}",
520                        style: 'lineSimple',
521                        exclZero: false,
522                        keepRecords: false,
[3221a2b]523                        logarithmic: !relative && group.log,
[3c40dc2a]524                        numBuilds: '120',
525                        useDescr: true,
[490cb3c]526                        yaxis: group.unit,
[3c40dc2a]527                        yaxisMaximum: '',
528                        yaxisMinimum: ''
[df57a84]529        }
530}
Note: See TracBrowser for help on using the repository browser.