Changeset 72a5a75 for Jenkinsfile


Ignore:
Timestamp:
Aug 17, 2018, 4:56:31 PM (6 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, no_list, persistent-indexer, pthread-emulation, qualifiedEnum
Children:
341bb80, 4bd3069, 5346dce
Parents:
b6830d74 (diff), eda8175 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'jenkins-sandbox'

File:
1 edited

Legend:

Unmodified
Added
Removed
  • Jenkinsfile

    rb6830d74 r72a5a75  
    66node ('master'){
    77
    8         boolean bIsSandbox = env.BRANCH_NAME == "jenkins-sandbox"
     8        // Globals
     9        BuildDir  = pwd tmp: true
     10        SrcDir    = pwd tmp: false
     11        Settings  = null
     12        StageName = ''
     13
     14        // Local variables
    915        def err = null
    1016        def log_needed = false
    11 
    12         stage_name              = ''
    13 
    14         compiler                = null
    15         arch_name               = ''
    16         architecture    = ''
    17 
    18         do_alltests             = false
    19         do_benchmark    = false
    20         do_doc          = false
    21         do_publish              = false
    22         do_sendemail    = true
    23 
    24         builddir = pwd tmp: true
    25         srcdir   = pwd tmp: false
    2617
    2718        currentBuild.result = "SUCCESS"
     
    3324                        notify_server(0)
    3425
    35                         prepare_build()
     26                        Settings = prepare_build()
    3627
    3728                        clean()
     
    6152                err = caughtError
    6253
     54                echo err.toString()
     55
    6356                //An error has occured, the build log is relevent
    6457                log_needed = true
    6558
    6659                //Store the result of the build log
    67                 currentBuild.result = "${stage_name} FAILURE".trim()
     60                currentBuild.result = "${StageName} FAILURE".trim()
    6861        }
    6962
    7063        finally {
    7164                //Send email with final results if this is not a full build
    72                 if( do_sendemail ) {
    73                         echo 'Notifying users of result'
    74                         email(currentBuild.result, log_needed, bIsSandbox)
     65                if( Settings && !Settings.Silent ) {
     66                        email(log_needed, Settings.IsSandbox)
    7567                }
    7668
     
    8577
    8678//===========================================================================================================
     79// Main compilation routines
     80//===========================================================================================================
     81def clean() {
     82        build_stage('Cleanup') {
     83                // clean the build by wipping the build directory
     84                dir(BuildDir) {
     85                        deleteDir()
     86                }
     87        }
     88}
     89
     90//Compilation script is done here but environnement set-up and error handling is done in main loop
     91def checkout() {
     92        build_stage('Checkout') {
     93                //checkout the source code and clean the repo
     94                final scmVars = checkout scm
     95                Settings.GitNewRef = scmVars.GIT_COMMIT
     96                Settings.GitOldRef = scmVars.GIT_PREVIOUS_COMMIT
     97
     98                echo GitLogMessage()
     99        }
     100}
     101
     102def build() {
     103        build_stage('Build') {
     104                // Build outside of the src tree to ease cleaning
     105                dir (BuildDir) {
     106                        //Configure the conpilation (Output is not relevant)
     107                        //Use the current directory as the installation target so nothing escapes the sandbox
     108                        //Also specify the compiler by hand
     109                        targets=""
     110                        if( Settings.RunAllTests ) {
     111                                targets="--with-target-hosts='host:debug,host:nodebug'"
     112                        } else {
     113                                targets="--with-target-hosts='host:debug'"
     114                        }
     115
     116                        sh "${SrcDir}/configure CXX=${Settings.Compiler.cpp_cc} ${Settings.Architecture.flags} ${targets} --with-backend-compiler=${Settings.Compiler.cfa_cc} --quiet"
     117
     118                        //Compile the project
     119                        sh 'make -j 8 --no-print-directory'
     120                }
     121        }
     122}
     123
     124def test() {
     125        build_stage('Test') {
     126
     127                dir (BuildDir) {
     128                        //Run the tests from the tests directory
     129                        if ( Settings.RunAllTests ) {
     130                                sh 'make --no-print-directory -C tests all-tests debug=yes'
     131                                sh 'make --no-print-directory -C tests all-tests debug=no '
     132                        }
     133                        else {
     134                                sh 'make --no-print-directory -C tests'
     135                        }
     136                }
     137        }
     138}
     139
     140def benchmark() {
     141        build_stage('Benchmark') {
     142
     143                if( !Settings.RunBenchmark ) return
     144
     145                dir (BuildDir) {
     146                        //Append bench results
     147                        sh "make --no-print-directory -C benchmark jenkins githash=${Settings.GitNewRef} arch=${Settings.Architecture} | tee ${SrcDir}/bench.json"
     148                }
     149        }
     150}
     151
     152def build_doc() {
     153        build_stage('Documentation') {
     154
     155                if( !Settings.BuildDocumentation ) return
     156
     157                dir ('doc/user') {
     158                        make_doc()
     159                }
     160
     161                dir ('doc/refrat') {
     162                        make_doc()
     163                }
     164        }
     165}
     166
     167def publish() {
     168        build_stage('Publish') {
     169
     170                if( !Settings.Publish ) return
     171
     172                //Then publish the results
     173                sh 'curl --silent --show-error -H \'Content-Type: application/json\' --data @bench.json https://cforall.uwaterloo.ca:8082/jenkins/publish > /dev/null || true'
     174        }
     175}
     176
     177//===========================================================================================================
     178//Routine responsible of sending the email notification once the build is completed
     179//===========================================================================================================
     180def GitLogMessage() {
     181        if (!Settings || !Settings.GitOldRef || !Settings.GitNewRef) return "\nERROR retrieveing git information!\n"
     182
     183        sh "${SrcDir}/tools/PrettyGitLogs.sh ${BuildDir} ${Settings.GitOldRef} ${Settings.GitNewRef}"
     184
     185        def gitUpdate = readFile("${BuildDir}/GIT_UPDATE")
     186        def gitLog    = readFile("${BuildDir}/GIT_LOG")
     187        def gitDiff   = readFile("${BuildDir}/GIT_DIFF")
     188
     189        return """
     190The branch ${env.BRANCH_NAME} has been updated.
     191${gitUpdate}
     192
     193Check console output at ${env.BUILD_URL} to view the results.
     194
     195- Status --------------------------------------------------------------
     196
     197BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}
     198
     199- Log -----------------------------------------------------------------
     200${gitLog}
     201-----------------------------------------------------------------------
     202Summary of changes:
     203${gitDiff}
     204"""
     205}
     206
     207//Standard build email notification
     208def email(boolean log, boolean bIsSandbox) {
     209        //Since tokenizer doesn't work, figure stuff out from the environnement variables and command line
     210        //Configurations for email format
     211        echo 'Notifying users of result'
     212
     213        def project_name = (env.JOB_NAME =~ /(.+)\/.+/)[0][1].toLowerCase()
     214        def email_subject = "[${project_name} git][BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}] - branch ${env.BRANCH_NAME}"
     215        def email_body = """This is an automated email from the Jenkins build machine. It was
     216generated because of a git hooks/post-receive script following
     217a ref change which was pushed to the Cforall repository.
     218""" + GitLogMessage()
     219
     220        def email_to = "cforall@lists.uwaterloo.ca"
     221
     222        if( Settings && !Settings.IsSandbox ) {
     223                //send email notification
     224                emailext body: email_body, subject: email_subject, to: email_to, attachLog: log
     225        } else {
     226                echo "Would send email to: ${email_to}"
     227                echo "With title: ${email_subject}"
     228                echo "Content: \n${email_body}"
     229        }
     230}
     231
     232//===========================================================================================================
    87233// Helper classes/variables/routines
    88234//===========================================================================================================
    89 //Helper routine to collect information about the git history
    90 def collect_git_info() {
    91 
    92         checkout scm
    93 
    94         //create the temporary output directory in case it doesn't already exist
    95         def out_dir = pwd tmp: true
    96         sh "mkdir -p ${out_dir}"
    97 
    98         //parse git logs to find what changed
    99         gitRefName = env.BRANCH_NAME
    100         sh "git reflog > ${out_dir}/GIT_COMMIT"
    101         git_reflog = readFile("${out_dir}/GIT_COMMIT")
    102         gitRefOldValue = (git_reflog =~ /moving from (.+) to (.+)/)[0][1]
    103         gitRefNewValue = (git_reflog =~ /moving from (.+) to (.+)/)[0][2]
     235//Description of a compiler (Must be serializable since pipelines are persistent)
     236class CC_Desc implements Serializable {
     237        public String cc_name
     238        public String cpp_cc
     239        public String cfa_cc
     240
     241        CC_Desc(String cc_name, String cpp_cc, String cfa_cc) {
     242                this.cc_name = cc_name
     243                this.cpp_cc = cpp_cc
     244                this.cfa_cc = cfa_cc
     245        }
     246}
     247
     248//Description of an architecture (Must be serializable since pipelines are persistent)
     249class Arch_Desc implements Serializable {
     250        public String name
     251        public String flags
     252
     253        Arch_Desc(String name, String flags) {
     254                this.name  = name
     255                this.flags = flags
     256        }
     257}
     258
     259class BuildSettings implements Serializable {
     260        public final CC_Desc Compiler
     261        public final Arch_Desc Architecture
     262        public final Boolean RunAllTests
     263        public final Boolean RunBenchmark
     264        public final Boolean BuildDocumentation
     265        public final Boolean Publish
     266        public final Boolean Silent
     267        public final Boolean IsSandbox
     268        public final String DescLong
     269        public final String DescShort
     270
     271        public String GitNewRef
     272        public String GitOldRef
     273
     274        BuildSettings(java.util.Collections$UnmodifiableMap param, String branch) {
     275                switch( param.Compiler ) {
     276                        case 'gcc-6':
     277                                this.Compiler = new CC_Desc('gcc-6', 'g++-6', 'gcc-6')
     278                        break
     279                        case 'gcc-5':
     280                                this.Compiler = new CC_Desc('gcc-5', 'g++-5', 'gcc-5')
     281                        break
     282                        case 'gcc-4.9':
     283                                this.Compiler = new CC_Desc('gcc-4.9', 'g++-4.9', 'gcc-4.9')
     284                        break
     285                        case 'clang':
     286                                this.Compiler = new CC_Desc('clang', 'clang++', 'gcc-6')
     287                        break
     288                        default :
     289                                error "Unhandled compiler : ${cc}"
     290                }
     291
     292                switch( param.Architecture ) {
     293                        case 'x64':
     294                                this.Architecture = new Arch_Desc('x64', '--host=x86_64')
     295                        break
     296                        case 'x86':
     297                                this.Architecture = new Arch_Desc('x86', '--host=i386')
     298                        break
     299                        default :
     300                                error "Unhandled architecture : ${arch}"
     301                }
     302
     303                this.RunAllTests        = param.RunAllTests
     304                this.RunBenchmark       = param.RunBenchmark
     305                this.BuildDocumentation = param.BuildDocumentation
     306                this.Publish            = param.Publish
     307                this.Silent             = param.Silent
     308                this.IsSandbox          = (branch == "jenkins-sandbox")
     309
     310                def full = param.RunAllTests ? " (Full)" : ""
     311                this.DescShort = "${ this.Compiler.cc_name }:${ this.Architecture.name }${full}"
     312
     313                this.DescLong = """Compiler              : ${ this.Compiler.cc_name } (${ this.Compiler.cpp_cc }/${ this.Compiler.cfa_cc })
     314Architecture            : ${ this.Architecture.name }
     315Arc Flags               : ${ this.Architecture.flags }
     316Run All Tests           : ${ this.RunAllTests.toString() }
     317Run Benchmark           : ${ this.RunBenchmark.toString() }
     318Build Documentation     : ${ this.BuildDocumentation.toString() }
     319Publish                 : ${ this.Publish.toString() }
     320Silent                  : ${ this.Silent.toString() }
     321"""
     322
     323                this.GitNewRef = ''
     324                this.GitOldRef = ''
     325        }
    104326}
    105327
    106328def prepare_build() {
     329        // prepare the properties
    107330        properties ([                                                                                                   \
    108331                [$class: 'ParametersDefinitionProperty',                                                                \
     
    148371                ]])
    149372
    150         compiler                = compiler_from_params( params.Compiler )
    151         arch_name               = params.Architecture
    152         architecture    = architecture_from_params( arch_name )
    153 
    154         do_alltests             = (params.RunAllTests == 'true')
    155         do_benchmark    = (params.RunBenchmark == 'true')
    156         do_doc          = (params.BuildDocumentation == 'true')
    157         do_publish              = (params.Publish == 'true')
    158         do_sendemail    = ! (params.Silent == 'true')
    159 
    160         collect_git_info()
    161 
    162         def full = do_alltests ? " (Full)" : ""
    163         currentBuild.description = "${compiler.cc_name}:${arch_name}${full}"
    164 
    165         echo """Compiler                 : ${ compiler.cc_name } (${ compiler.cpp_cc }/${ compiler.cfa_cc })
    166 Architecture            : ${ arch_name }
    167 Arc Flags               : ${ architecture }
    168 Run All Tests           : ${ params.RunAllTests.toString() }
    169 Run Benchmark           : ${ params.RunBenchmark.toString() }
    170 Build Documentation     : ${ params.BuildDocumentation.toString() }
    171 Publish                 : ${ params.Publish.toString() }
    172 Silent                  : ${ params.Silent.toString() }
    173 """
     373        final settings = new BuildSettings(params, env.BRANCH_NAME)
     374
     375        currentBuild.description = settings.DescShort
     376        echo                       settings.DescLong
     377
     378        return settings
    174379}
    175380
    176381def build_stage(String name, Closure block ) {
    177         stage_name = name
     382        StageName = name
     383        echo " -------- ${StageName} -------- "
    178384        stage(name, block)
    179385}
     
    198404        }
    199405}
    200 
    201 //Description of a compiler (Must be serializable since pipelines are persistent)
    202 class CC_Desc implements Serializable {
    203         public String cc_name
    204         public String cpp_cc
    205         public String cfa_cc
    206 
    207         CC_Desc(String cc_name, String cpp_cc, String cfa_cc) {
    208                 this.cc_name = cc_name
    209                 this.cpp_cc = cpp_cc
    210                 this.cfa_cc = cfa_cc
    211         }
    212 }
    213 
    214 def compiler_from_params(cc) {
    215         switch( cc ) {
    216                 case 'gcc-6':
    217                         return new CC_Desc('gcc-6', 'g++-6', 'gcc-6')
    218                 break
    219                 case 'gcc-5':
    220                         return new CC_Desc('gcc-5', 'g++-5', 'gcc-5')
    221                 break
    222                 case 'gcc-4.9':
    223                         return new CC_Desc('gcc-4.9', 'g++-4.9', 'gcc-4.9')
    224                 break
    225                 case 'clang':
    226                         return new CC_Desc('clang', 'clang++', 'gcc-6')
    227                 break
    228                 default :
    229                         error "Unhandled compiler : ${cc}"
    230         }
    231 }
    232 
    233 def architecture_from_params( arch ) {
    234         switch( arch ) {
    235                 case 'x64':
    236                         return '--host=x86_64'
    237                 break
    238                 case 'x86':
    239                         return '--host=i386'
    240                 break
    241                 default :
    242                         error "Unhandled architecture : ${arch}"
    243         }
    244 }
    245 
    246 //===========================================================================================================
    247 // Main compilation routines
    248 //===========================================================================================================
    249 def clean() {
    250         build_stage('Cleanup') {
    251                 // clean the build by wipping the build directory
    252                 dir(builddir) {
    253                         deleteDir()
    254                 }
    255 
    256                 //Clean all temporary files to make sure no artifacts of the previous build remain
    257                 sh 'git clean -fdqx'
    258 
    259                 //Reset the git repo so no local changes persist
    260                 sh 'git reset --hard'
    261         }
    262 }
    263 
    264 //Compilation script is done here but environnement set-up and error handling is done in main loop
    265 def checkout() {
    266         build_stage('Checkout') {
    267                 //checkout the source code and clean the repo
    268                 checkout scm
    269         }
    270 }
    271 
    272 def build() {
    273         build_stage('Build') {
    274                 // Build outside of the src tree to ease cleaning
    275                 dir (builddir) {
    276                         //Configure the conpilation (Output is not relevant)
    277                         //Use the current directory as the installation target so nothing escapes the sandbox
    278                         //Also specify the compiler by hand
    279                         targets=""
    280                         if(do_alltests) {
    281                                 targets="--with-target-hosts='host:debug,host:nodebug'"
    282                         } else {
    283                                 targets="--with-target-hosts='host:debug'"
    284                         }
    285 
    286                         sh "${srcdir}/configure CXX=${compiler.cpp_cc} ${architecture} ${targets} --with-backend-compiler=${compiler.cfa_cc} --quiet"
    287 
    288                         //Compile the project
    289                         sh 'make -j 8 --no-print-directory'
    290                 }
    291         }
    292 }
    293 
    294 def test() {
    295         build_stage('Test') {
    296 
    297                 dir (builddir) {
    298                         //Run the tests from the tests directory
    299                         if ( do_alltests ) {
    300                                 sh 'make --no-print-directory -C tests all-tests debug=yes'
    301                                 sh 'make --no-print-directory -C tests all-tests debug=no '
    302                         }
    303                         else {
    304                                 sh 'make --no-print-directory -C tests'
    305                         }
    306                 }
    307         }
    308 }
    309 
    310 def benchmark() {
    311         build_stage('Benchmark') {
    312 
    313                 if( !do_benchmark ) return
    314 
    315                 dir (builddir) {
    316                         //Append bench results
    317                         sh "make --no-print-directory -C benchmark jenkins githash=${gitRefNewValue} arch=${arch_name} | tee ${srcdir}/bench.json"
    318                 }
    319         }
    320 }
    321 
    322 def build_doc() {
    323         build_stage('Documentation') {
    324 
    325                 if( !do_doc ) return
    326 
    327                 dir ('doc/user') {
    328                         make_doc()
    329                 }
    330 
    331                 dir ('doc/refrat') {
    332                         make_doc()
    333                 }
    334         }
    335 }
    336 
    337 def publish() {
    338         build_stage('Publish') {
    339 
    340                 if( !do_publish ) return
    341 
    342                 //Then publish the results
    343                 sh 'curl --silent --show-error -H \'Content-Type: application/json\' --data @bench.json https://cforall.uwaterloo.ca:8082/jenkins/publish > /dev/null || true'
    344         }
    345 }
    346 
    347 //===========================================================================================================
    348 //Routine responsible of sending the email notification once the build is completed
    349 //===========================================================================================================
    350 def gitBranchUpdate(String gitRefOldValue, String gitRefNewValue) {
    351         def update = ""
    352         sh "git rev-list ${gitRefOldValue}..${gitRefNewValue} > GIT_LOG";
    353         readFile('GIT_LOG').eachLine { rev ->
    354                 sh "git cat-file -t ${rev} > GIT_TYPE"
    355                 def type = readFile('GIT_TYPE')
    356 
    357                 update += "       via  ${rev} (${type})\n"
    358         }
    359         def rev = gitRefOldValue
    360         sh "git cat-file -t ${rev} > GIT_TYPE"
    361         def type = readFile('GIT_TYPE')
    362 
    363         update += "      from  ${rev} (${type})\n"
    364         return update
    365 
    366 def output=readFile('result').trim()
    367 echo "output=$output";
    368 }
    369 
    370 //Standard build email notification
    371 def email(String status, boolean log, boolean bIsSandbox) {
    372         //Since tokenizer doesn't work, figure stuff out from the environnement variables and command line
    373         //Configurations for email format
    374         def project_name = (env.JOB_NAME =~ /(.+)\/.+/)[0][1].toLowerCase()
    375 
    376         def gitLog = 'Error retrieving git logs'
    377         def gitDiff = 'Error retrieving git diff'
    378         def gitUpdate = 'Error retrieving update'
    379 
    380         try {
    381                 gitUpdate = gitBranchUpdate(gitRefOldValue, gitRefNewValue)
    382 
    383                 sh "git rev-list --format=short ${gitRefOldValue}...${gitRefNewValue} > GIT_LOG"
    384                 gitLog = readFile('GIT_LOG')
    385 
    386                 sh "git diff --stat ${gitRefNewValue} ${gitRefOldValue} > GIT_DIFF"
    387                 gitDiff = readFile('GIT_DIFF')
    388         }
    389         catch (Exception error) {
    390                 echo error.toString()
    391                 echo error.getMessage()
    392         }
    393 
    394         def email_subject = "[${project_name} git][BUILD# ${env.BUILD_NUMBER} - ${status}] - branch ${env.BRANCH_NAME}"
    395         def email_body = """This is an automated email from the Jenkins build machine. It was
    396 generated because of a git hooks/post-receive script following
    397 a ref change was pushed to the repository containing
    398 the project "UNNAMED PROJECT".
    399 
    400 The branch ${env.BRANCH_NAME} has been updated.
    401 ${gitUpdate}
    402 
    403 Check console output at ${env.BUILD_URL} to view the results.
    404 
    405 - Status --------------------------------------------------------------
    406 
    407 BUILD# ${env.BUILD_NUMBER} - ${status}
    408 
    409 - Log -----------------------------------------------------------------
    410 ${gitLog}
    411 -----------------------------------------------------------------------
    412 Summary of changes:
    413 ${gitDiff}
    414 """
    415 
    416         def email_to = "cforall@lists.uwaterloo.ca"
    417 
    418         if( !bIsSandbox ) {
    419                 //send email notification
    420                 emailext body: email_body, subject: email_subject, to: email_to, attachLog: log
    421         } else {
    422                 echo "Would send email to: ${email_to}"
    423                 echo "With title: ${email_subject}"
    424                 echo "Content: \n${email_body}"
    425         }
    426 }
Note: See TracChangeset for help on using the changeset viewer.