source: Jenkinsfile @ 6c55a3d

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

Change jenkins file to mark staged as skipped rather than lasted 0s

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