source: Jenkinsfile @ 8d63649

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

Jenkins has to unconditionnaly plot otherwise the plot get URLs get invalidated

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