source: Jenkinsfile @ d2c58be

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

Trying to eliminate redundant checkouts

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