source: Jenkinsfile @ 4b82db3

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprno_listpersistent-indexerpthread-emulationqualifiedEnum
Last change on this file since 4b82db3 was 4b82db3, checked in by Thierry Delisle <tdelisle@…>, 6 years ago

Groovy and Java interaction is weird

  • Property mode set to 100644
File size: 12.5 KB
RevLine 
[a63ad80]1#!groovy
2
[29f4fe62]3//===========================================================================================================
[9beae23]4// Main loop of the compilation
[29f4fe62]5//===========================================================================================================
[9beae23]6node ('master'){
[56a9ce6]7
[9beae23]8        def err = null
9        def log_needed = false
[0ef06b6]10
[c431138]11        Settings = null
12
[deb6185]13        stage_name         = ''
14
15        gitRefOldValue = ''
16        gitRefNewValue = ''
[734891d]17
[e93572a]18        builddir = pwd tmp: true
19        srcdir   = pwd tmp: false
[73787a9]20
[0ef06b6]21        currentBuild.result = "SUCCESS"
22
[9beae23]23        try {
[95fdb0a]24                //Wrap build to add timestamp to command line
25                wrap([$class: 'TimestamperBuildWrapper']) {
[23a14d86]26
[8c700c1]27                        notify_server(0)
[95fdb0a]28
[c431138]29                        Settings = prepare_build()
[7aebc62]30
[0dc3ac3]31                        clean()
32
[f408e1a]33                        checkout()
[fde808df]34
[8c700c1]35                        notify_server(0)
36
[f408e1a]37                        build()
[95fdb0a]38
[f408e1a]39                        test()
[95fdb0a]40
[f408e1a]41                        benchmark()
[95fdb0a]42
[f408e1a]43                        build_doc()
[7359098]44
[f408e1a]45                        publish()
[9beae23]46
[65f9dec]47                        notify_server(45)
[9beae23]48                }
[738cf8f]49        }
50
[9beae23]51        //If an exception is caught we need to change the status and remember to
52        //attach the build log to the email
[738cf8f]53        catch (Exception caughtError) {
54                //rethrow error later
55                err = caughtError
56
[e966ec0]57                echo err.toString()
58
[9beae23]59                //An error has occured, the build log is relevent
60                log_needed = true
61
62                //Store the result of the build log
[734891d]63                currentBuild.result = "${stage_name} FAILURE".trim()
[738cf8f]64        }
65
66        finally {
[9beae23]67                //Send email with final results if this is not a full build
[e966ec0]68                if( Settings && !Settings.Silent ) {
[9beae23]69                        echo 'Notifying users of result'
[094a42c]70                        email(currentBuild.result, log_needed, bIsSandbox)
[9beae23]71                }
72
[734891d]73                echo 'Build Completed'
74
[738cf8f]75                /* Must re-throw exception to propagate error */
76                if (err) {
77                        throw err
78                }
79        }
80}
81
[29f4fe62]82//===========================================================================================================
[95fdb0a]83// Helper classes/variables/routines
[29f4fe62]84//===========================================================================================================
[155c2a28]85class BuildSettings implements Serializable {
[5afeab9]86        public final CC_Desc Compiler
87        public final Arch_Desc Architecture
88        public final Boolean RunAllTests
89        public final Boolean RunBenchmark
90        public final Boolean BuildDocumentation
91        public final Boolean Publish
92        public final Boolean Silent
93        public final Boolean IsSandbox
94        public final String Branch
95        public final String Commit
96        public final String PrevCommit
97        public final String RepoUrl
98        public final String DescLong
99        public final String DescShort
100
[4b82db3]101
102        //Description of a compiler (Must be serializable since pipelines are persistent)
103        private class CC_Desc implements Serializable {
104                public String cc_name
105                public String cpp_cc
106                public String cfa_cc
107
108                CC_Desc(String cc_name, String cpp_cc, String cfa_cc) {
109                        this.cc_name = cc_name
110                        this.cpp_cc = cpp_cc
111                        this.cfa_cc = cfa_cc
112                }
113        }
114
115        private static CC_Desc compiler_from_params(String cc) {
116                switch( cc ) {
117                        case 'gcc-6':
118                                return new CC_Desc('gcc-6', 'g++-6', 'gcc-6')
119                        break
120                        case 'gcc-5':
121                                return new CC_Desc('gcc-5', 'g++-5', 'gcc-5')
122                        break
123                        case 'gcc-4.9':
124                                return new CC_Desc('gcc-4.9', 'g++-4.9', 'gcc-4.9')
125                        break
126                        case 'clang':
127                                return new CC_Desc('clang', 'clang++', 'gcc-6')
128                        break
129                        default :
130                                error "Unhandled compiler : ${cc}"
131                }
132        }
133
134        //Description of an architecture (Must be serializable since pipelines are persistent)
135        private class Arch_Desc implements Serializable {
136                public String name
137                public String flags
138
139                Arch_Desc(String name, String flags) {
140                        this.name  = name
141                        this.flags = flags
142                }
143        }
144
145        private static Arch_Desc architecture_from_params( String arch ) {
146                switch( arch ) {
147                        case 'x64':
148                                return new Arch_Desc('x64', '--host=x86_64')
149                        break
150                        case 'x86':
151                                return new Arch_Desc('x86', '--host=i386')
152                        break
153                        default :
154                                error "Unhandled architecture : ${arch}"
155                }
156        }
157
[5afeab9]158        BuildSettings(java.util.Collections$UnmodifiableMap param, java.util.TreeMap scmVars) {
[8f466d4]159                this.Compiler         = compiler_from_params( param.Compiler )
160                this.Architecture       = architecture_from_params( param.Architecture )
161                this.RunAllTests        = param.RunAllTests
162                this.RunBenchmark       = param.RunBenchmark
163                this.BuildDocumentation = param.BuildDocumentation
164                this.Publish            = param.Publish
165                this.Silent             = param.Silent
[5afeab9]166                this.IsSandbox          = scmVars.GIT_BRANCH == "jenkins-sandbox"
167                this.Branch             = scmVars.GIT_BRANCH
168                this.Commit             = scmVars.GIT_COMMIT
169                this.PrevCommit         = scmVars.GIT_PREVIOUS_COMMIT
170                this.RepoUrl            = scmVars.GIT_URL
171
[8f466d4]172                def full = param.RunAllTests ? " (Full)" : ""
[5afeab9]173                this.DescShort = "${ this.Compiler.cc_name }:${ this.Architecture.name }${full}"
174
175                this.DescLong """Compiler                : ${ this.Compiler.cc_name } (${ this.Compiler.cpp_cc }/${ this.Compiler.cfa_cc })
176Architecture            : ${ this.Architecture.name }
177Arc Flags               : ${ this.Architecture.flags }
178Run All Tests           : ${ this.RunAllTests.toString() }
179Run Benchmark           : ${ this.RunBenchmark.toString() }
180Build Documentation     : ${ this.BuildDocumentation.toString() }
181Publish                 : ${ this.Publish.toString() }
182Silent                  : ${ this.Silent.toString() }
183"""
[155c2a28]184        }
185}
186
[0ef06b6]187def prepare_build() {
[5afeab9]188        // prepare the properties
[95fdb0a]189        properties ([                                                                                                   \
190                [$class: 'ParametersDefinitionProperty',                                                                \
191                        parameterDefinitions: [                                                                         \
192                                [$class: 'ChoiceParameterDefinition',                                           \
193                                        description: 'Which compiler to use',                                   \
[0c1d240]194                                        name: 'Compiler',                                                                       \
[95fdb0a]195                                        choices: 'gcc-6\ngcc-5\ngcc-4.9\nclang',                                        \
196                                        defaultValue: 'gcc-6',                                                          \
197                                ],                                                                                              \
198                                [$class: 'ChoiceParameterDefinition',                                           \
199                                        description: 'The target architecture',                                 \
[0c1d240]200                                        name: 'Architecture',                                                           \
[8fa3c7e6]201                                        choices: 'x64\nx86',                                                            \
202                                        defaultValue: 'x64',                                                            \
[95fdb0a]203                                ],                                                                                              \
204                                [$class: 'BooleanParameterDefinition',                                                  \
205                                        description: 'If false, only the quick test suite is ran',              \
[0c1d240]206                                        name: 'RunAllTests',                                                            \
[95fdb0a]207                                        defaultValue: false,                                                            \
208                                ],                                                                                              \
209                                [$class: 'BooleanParameterDefinition',                                                  \
210                                        description: 'If true, jenkins also runs benchmarks',           \
[0c1d240]211                                        name: 'RunBenchmark',                                                           \
[7caea53]212                                        defaultValue: false,                                                            \
[95fdb0a]213                                ],                                                                                              \
214                                [$class: 'BooleanParameterDefinition',                                                  \
215                                        description: 'If true, jenkins also builds documentation',              \
[0c1d240]216                                        name: 'BuildDocumentation',                                                     \
[26a63f0]217                                        defaultValue: true,                                                             \
[95fdb0a]218                                ],                                                                                              \
219                                [$class: 'BooleanParameterDefinition',                                                  \
220                                        description: 'If true, jenkins also publishes results',                 \
[0c1d240]221                                        name: 'Publish',                                                                        \
[3831b58]222                                        defaultValue: false,                                                            \
[fd6d74e]223                                ],                                                                                              \
224                                [$class: 'BooleanParameterDefinition',                                                  \
225                                        description: 'If true, jenkins will not send emails',           \
[0c1d240]226                                        name: 'Silent',                                                                         \
[95fdb0a]227                                        defaultValue: false,                                                            \
228                                ],                                                                                              \
229                        ],
[0ef06b6]230                ]])
231
[5afeab9]232        // Collect git information
233        final scmVars = checkout scm
[155c2a28]234
[5afeab9]235        final settings = new BuildSettings(params, scmVars)
[ab5cd196]236
[5afeab9]237        currentBuild.description = settings.DescShort
238        echo                       settings.DescLong
[e6ab994]239
[5afeab9]240        return settings
[95fdb0a]241}
[0ef06b6]242
[620dd2b]243def build_stage(String name, Closure block ) {
[734891d]244        stage_name = name
[620dd2b]245        stage(name, block)
[734891d]246}
247
[65f9dec]248def notify_server(int wait) {
[50f2cfc]249        sh """curl --silent --show-error --data "wait=${wait}" -X POST https://cforall.uwaterloo.ca:8082/jenkins/notify > /dev/null || true"""
[ed50f0b]250        return
[95fdb0a]251}
252
253def make_doc() {
254        def err = null
255        try {
256                sh 'make clean > /dev/null'
257                sh 'make > /dev/null 2>&1'
[a5b7905]258        }
[95fdb0a]259        catch (Exception caughtError) {
260                err = caughtError //rethrow error later
261                sh 'cat *.log'
262        }
263        finally {
264                if (err) throw err // Must re-throw exception to propagate error
[bd34bcf5]265        }
266}
267
[29f4fe62]268//===========================================================================================================
[9beae23]269// Main compilation routines
[29f4fe62]270//===========================================================================================================
[0dc3ac3]271def clean() {
272        build_stage('Cleanup') {
273                // clean the build by wipping the build directory
[ece8a80]274                dir(builddir) {
[d4cd491]275                        deleteDir()
[ece8a80]276                }
277
[9beae23]278                //Clean all temporary files to make sure no artifacts of the previous build remain
279                sh 'git clean -fdqx'
[40b1df9]280
[9beae23]281                //Reset the git repo so no local changes persist
282                sh 'git reset --hard'
[620dd2b]283        }
[95fdb0a]284}
[29f4fe62]285
[0dc3ac3]286//Compilation script is done here but environnement set-up and error handling is done in main loop
287def checkout() {
288        build_stage('Checkout') {
289                //checkout the source code and clean the repo
290                checkout scm
291        }
292}
293
[95fdb0a]294def build() {
[620dd2b]295        build_stage('Build') {
[50f2cfc]296                // Build outside of the src tree to ease cleaning
[0dc3ac3]297                dir (builddir) {
[50f2cfc]298                        //Configure the conpilation (Output is not relevant)
299                        //Use the current directory as the installation target so nothing escapes the sandbox
300                        //Also specify the compiler by hand
[3fc5f010]301                        targets=""
[5afeab9]302                        if( Settings.RunAllTests ) {
[6bde81d]303                                targets="--with-target-hosts='host:debug,host:nodebug'"
[3fc5f010]304                        } else {
[6bde81d]305                                targets="--with-target-hosts='host:debug'"
[3fc5f010]306                        }
307
[5afeab9]308                        sh "${srcdir}/configure CXX=${Settings.Compiler.cpp_cc} ${Settings.Architecture.flags} ${targets} --with-backend-compiler=${Settings.Compiler.cfa_cc} --quiet"
[1752d0e]309
[50f2cfc]310                        //Compile the project
311                        sh 'make -j 8 --no-print-directory'
312                }
[620dd2b]313        }
[95fdb0a]314}
[24eecab]315
[95fdb0a]316def test() {
[620dd2b]317        build_stage('Test') {
[9e5f409]318
[0dc3ac3]319                dir (builddir) {
320                        //Run the tests from the tests directory
[5afeab9]321                        if ( Settings.RunAllTests ) {
[ea5b7d6]322                                sh 'make --no-print-directory -C tests all-tests debug=yes'
323                                sh 'make --no-print-directory -C tests all-tests debug=no '
[0dc3ac3]324                        }
325                        else {
[ea5b7d6]326                                sh 'make --no-print-directory -C tests'
[0dc3ac3]327                        }
[9beae23]328                }
[620dd2b]329        }
[95fdb0a]330}
331
332def benchmark() {
[620dd2b]333        build_stage('Benchmark') {
[29f4fe62]334
[5afeab9]335                if( !Settings.RunBenchmark ) return
[ae28ee2]336
[0dc3ac3]337                dir (builddir) {
338                        //Append bench results
[5afeab9]339                        sh "make --no-print-directory -C benchmark jenkins githash=${gitRefNewValue} arch=${Settings.Architecture} | tee ${srcdir}/bench.json"
[0dc3ac3]340                }
[620dd2b]341        }
[9beae23]342}
[efd60d67]343
[95fdb0a]344def build_doc() {
[620dd2b]345        build_stage('Documentation') {
[9beae23]346
[5afeab9]347                if( !Settings.BuildDocumentation ) return
[9beae23]348
349                dir ('doc/user') {
350                        make_doc()
351                }
352
353                dir ('doc/refrat') {
354                        make_doc()
355                }
[620dd2b]356        }
[9beae23]357}
358
[95fdb0a]359def publish() {
[620dd2b]360        build_stage('Publish') {
[95fdb0a]361
[5afeab9]362                if( !Settings.Publish ) return
[95fdb0a]363
364                //Then publish the results
[50f2cfc]365                sh 'curl --silent --show-error -H \'Content-Type: application/json\' --data @bench.json https://cforall.uwaterloo.ca:8082/jenkins/publish > /dev/null || true'
[620dd2b]366        }
[95fdb0a]367}
368
[29f4fe62]369//===========================================================================================================
370//Routine responsible of sending the email notification once the build is completed
371//===========================================================================================================
[3f9876e]372def gitBranchUpdate(String gitRefOldValue, String gitRefNewValue) {
373        def update = ""
[db583df]374        sh "git rev-list ${gitRefOldValue}..${gitRefNewValue} > GIT_LOG";
[3f9876e]375        readFile('GIT_LOG').eachLine { rev ->
376                sh "git cat-file -t ${rev} > GIT_TYPE"
377                def type = readFile('GIT_TYPE')
378
379                update += "       via  ${rev} (${type})\n"
380        }
381        def rev = gitRefOldValue
382        sh "git cat-file -t ${rev} > GIT_TYPE"
383        def type = readFile('GIT_TYPE')
384
385        update += "      from  ${rev} (${type})\n"
386        return update
387
388def output=readFile('result').trim()
389echo "output=$output";
390}
391
[a235d09]392//Standard build email notification
[094a42c]393def email(String status, boolean log, boolean bIsSandbox) {
[e8a22a7]394        //Since tokenizer doesn't work, figure stuff out from the environnement variables and command line
395        //Configurations for email format
396        def project_name = (env.JOB_NAME =~ /(.+)\/.+/)[0][1].toLowerCase()
397
[0a346e5]398        def gitLog = 'Error retrieving git logs'
399        def gitDiff = 'Error retrieving git diff'
[3f9876e]400        def gitUpdate = 'Error retrieving update'
[7b1a604]401
[0a346e5]402        try {
[5afeab9]403                gitUpdate = gitBranchUpdate(Settings.PrevCommit, Settings.Commit)
[0a346e5]404
[5afeab9]405                sh "git rev-list --format=short ${Settings.PrevCommit}...${Settings.Commit} > GIT_LOG"
[0a346e5]406                gitLog = readFile('GIT_LOG')
407
[5afeab9]408                sh "git diff --stat ${Settings.Commit} ${Settings.PrevCommit} > GIT_DIFF"
[0a346e5]409                gitDiff = readFile('GIT_DIFF')
410        }
[fb975a50]411        catch (Exception error) {
412                echo error.toString()
413                echo error.getMessage()
414        }
[7b1a604]415
[992c26d]416        def email_subject = "[${project_name} git][BUILD# ${env.BUILD_NUMBER} - ${status}] - branch ${env.BRANCH_NAME}"
[848fb00]417        def email_body = """This is an automated email from the Jenkins build machine. It was
418generated because of a git hooks/post-receive script following
419a ref change was pushed to the repository containing
420the project "UNNAMED PROJECT".
[e8a22a7]421
[848fb00]422The branch ${env.BRANCH_NAME} has been updated.
[3f9876e]423${gitUpdate}
[7b1a604]424
425Check console output at ${env.BUILD_URL} to view the results.
426
427- Status --------------------------------------------------------------
428
429BUILD# ${env.BUILD_NUMBER} - ${status}
[e8a22a7]430
[7b1a604]431- Log -----------------------------------------------------------------
432${gitLog}
433-----------------------------------------------------------------------
434Summary of changes:
435${gitDiff}
436"""
[e8a22a7]437
[e39647e]438        def email_to = "cforall@lists.uwaterloo.ca"
[e8a22a7]439
[094a42c]440        if( !bIsSandbox ) {
441                //send email notification
442                emailext body: email_body, subject: email_subject, to: email_to, attachLog: log
443        } else {
444                echo "Would send email to: ${email_to}"
445                echo "With title: ${email_subject}"
446                echo "Content: \n${email_body}"
447        }
[e8a22a7]448}
Note: See TracBrowser for help on using the repository browser.