Changeset 4bd3069 for Jenkinsfile
- Timestamp:
- Aug 19, 2018, 10:21:35 AM (7 years ago)
- 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:
- 90ed538
- Parents:
- 90cac45 (diff), 72a5a75 (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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified Jenkinsfile ¶
r90cac45 r4bd3069 6 6 node ('master'){ 7 7 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 9 15 def err = null 10 16 def log_needed = false 11 12 stage_name = ''13 14 compiler = null15 arch_name = ''16 architecture = ''17 18 do_alltests = false19 do_benchmark = false20 do_doc = false21 do_publish = false22 do_sendemail = true23 24 builddir = pwd tmp: true25 srcdir = pwd tmp: false26 17 27 18 currentBuild.result = "SUCCESS" … … 33 24 notify_server(0) 34 25 35 prepare_build()26 Settings = prepare_build() 36 27 37 28 clean() … … 61 52 err = caughtError 62 53 54 echo err.toString() 55 63 56 //An error has occured, the build log is relevent 64 57 log_needed = true 65 58 66 59 //Store the result of the build log 67 currentBuild.result = "${ stage_name} FAILURE".trim()60 currentBuild.result = "${StageName} FAILURE".trim() 68 61 } 69 62 70 63 finally { 71 64 //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) 75 67 } 76 68 … … 85 77 86 78 //=========================================================================================================== 87 // Helper classes/variables/routines88 //===========================================================================================================89 //Helper routine to collect information about the git history90 def collect_git_info() {91 92 checkout scm93 94 //create the temporary output directory in case it doesn't already exist95 def out_dir = pwd tmp: true96 sh "mkdir -p ${out_dir}"97 98 //parse git logs to find what changed99 gitRefName = env.BRANCH_NAME100 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]104 }105 106 def prepare_build() {107 properties ([ \108 [$class: 'ParametersDefinitionProperty', \109 parameterDefinitions: [ \110 [$class: 'ChoiceParameterDefinition', \111 description: 'Which compiler to use', \112 name: 'pCompiler', \113 choices: 'gcc-6\ngcc-5\ngcc-4.9\nclang', \114 defaultValue: 'gcc-6', \115 ], \116 [$class: 'ChoiceParameterDefinition', \117 description: 'The target architecture', \118 name: 'pArchitecture', \119 choices: 'x64\nx86', \120 defaultValue: 'x64', \121 ], \122 [$class: 'BooleanParameterDefinition', \123 description: 'If false, only the quick test suite is ran', \124 name: 'pRunAllTests', \125 defaultValue: false, \126 ], \127 [$class: 'BooleanParameterDefinition', \128 description: 'If true, jenkins also runs benchmarks', \129 name: 'pRunBenchmark', \130 defaultValue: false, \131 ], \132 [$class: 'BooleanParameterDefinition', \133 description: 'If true, jenkins also builds documentation', \134 name: 'pBuildDocumentation', \135 defaultValue: true, \136 ], \137 [$class: 'BooleanParameterDefinition', \138 description: 'If true, jenkins also publishes results', \139 name: 'pPublish', \140 defaultValue: false, \141 ], \142 [$class: 'BooleanParameterDefinition', \143 description: 'If true, jenkins will not send emails', \144 name: 'pSilent', \145 defaultValue: false, \146 ], \147 ],148 ]])149 150 compiler = compiler_from_params( pCompiler )151 arch_name = pArchitecture152 architecture = architecture_from_params( arch_name )153 154 do_alltests = (pRunAllTests == 'true')155 do_benchmark = (pRunBenchmark == 'true')156 do_doc = (pBuildDocumentation == 'true')157 do_publish = (pPublish == 'true')158 do_sendemail = ! (pSilent == '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 : ${ pRunAllTests.toString() }169 Run Benchmark : ${ pRunBenchmark.toString() }170 Build Documentation : ${ pBuildDocumentation.toString() }171 Publish : ${ pPublish.toString() }172 Silent : ${ pSilent.toString() }173 """174 }175 176 def build_stage(String name, Closure block ) {177 stage_name = name178 stage(name, block)179 }180 181 def notify_server(int wait) {182 sh """curl --silent --show-error --data "wait=${wait}" -X POST https://cforall.uwaterloo.ca:8082/jenkins/notify > /dev/null || true"""183 return184 }185 186 def make_doc() {187 def err = null188 try {189 sh 'make clean > /dev/null'190 sh 'make > /dev/null 2>&1'191 }192 catch (Exception caughtError) {193 err = caughtError //rethrow error later194 sh 'cat *.log'195 }196 finally {197 if (err) throw err // Must re-throw exception to propagate error198 }199 }200 201 //Description of a compiler (Must be serializable since pipelines are persistent)202 class CC_Desc implements Serializable {203 public String cc_name204 public String cpp_cc205 public String cfa_cc206 207 CC_Desc(String cc_name, String cpp_cc, String cfa_cc) {208 this.cc_name = cc_name209 this.cpp_cc = cpp_cc210 this.cfa_cc = cfa_cc211 }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 break219 case 'gcc-5':220 return new CC_Desc('gcc-5', 'g++-5', 'gcc-5')221 break222 case 'gcc-4.9':223 return new CC_Desc('gcc-4.9', 'g++-4.9', 'gcc-4.9')224 break225 case 'clang':226 return new CC_Desc('clang', 'clang++', 'gcc-6')227 break228 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 break238 case 'x86':239 return '--host=i386'240 break241 default :242 error "Unhandled architecture : ${arch}"243 }244 }245 246 //===========================================================================================================247 79 // Main compilation routines 248 80 //=========================================================================================================== … … 250 82 build_stage('Cleanup') { 251 83 // clean the build by wipping the build directory 252 dir( builddir) {84 dir(BuildDir) { 253 85 deleteDir() 254 86 } 255 256 //Clean all temporary files to make sure no artifacts of the previous build remain257 sh 'git clean -fdqx'258 259 //Reset the git repo so no local changes persist260 sh 'git reset --hard'261 87 } 262 88 } … … 266 92 build_stage('Checkout') { 267 93 //checkout the source code and clean the repo 268 checkout scm 94 final scmVars = checkout scm 95 Settings.GitNewRef = scmVars.GIT_COMMIT 96 Settings.GitOldRef = scmVars.GIT_PREVIOUS_COMMIT 97 98 echo GitLogMessage() 269 99 } 270 100 } … … 273 103 build_stage('Build') { 274 104 // Build outside of the src tree to ease cleaning 275 dir ( builddir) {105 dir (BuildDir) { 276 106 //Configure the conpilation (Output is not relevant) 277 107 //Use the current directory as the installation target so nothing escapes the sandbox 278 108 //Also specify the compiler by hand 279 109 targets="" 280 if( do_alltests) {110 if( Settings.RunAllTests ) { 281 111 targets="--with-target-hosts='host:debug,host:nodebug'" 282 112 } else { … … 284 114 } 285 115 286 sh "${ srcdir}/configure CXX=${compiler.cpp_cc} ${architecture} ${targets} --with-backend-compiler=${compiler.cfa_cc} --quiet"116 sh "${SrcDir}/configure CXX=${Settings.Compiler.cpp_cc} ${Settings.Architecture.flags} ${targets} --with-backend-compiler=${Settings.Compiler.cfa_cc} --quiet" 287 117 288 118 //Compile the project … … 295 125 build_stage('Test') { 296 126 297 dir ( builddir) {127 dir (BuildDir) { 298 128 //Run the tests from the tests directory 299 if ( do_alltests ) {129 if ( Settings.RunAllTests ) { 300 130 sh 'make --no-print-directory -C tests all-tests debug=yes' 301 131 sh 'make --no-print-directory -C tests all-tests debug=no ' … … 311 141 build_stage('Benchmark') { 312 142 313 if( ! do_benchmark ) return314 315 dir ( builddir) {143 if( !Settings.RunBenchmark ) return 144 145 dir (BuildDir) { 316 146 //Append bench results 317 sh "make --no-print-directory -C benchmark jenkins githash=${ gitRefNewValue} arch=${arch_name} | tee ${srcdir}/bench.json"147 sh "make --no-print-directory -C benchmark jenkins githash=${Settings.GitNewRef} arch=${Settings.Architecture} | tee ${SrcDir}/bench.json" 318 148 } 319 149 } … … 323 153 build_stage('Documentation') { 324 154 325 if( ! do_doc) return155 if( !Settings.BuildDocumentation ) return 326 156 327 157 dir ('doc/user') { … … 338 168 build_stage('Publish') { 339 169 340 if( ! do_publish ) return170 if( !Settings.Publish ) return 341 171 342 172 //Then publish the results … … 348 178 //Routine responsible of sending the email notification once the build is completed 349 179 //=========================================================================================================== 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 180 def 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 """ 400 190 The branch ${env.BRANCH_NAME} has been updated. 401 191 ${gitUpdate} … … 405 195 - Status -------------------------------------------------------------- 406 196 407 BUILD# ${env.BUILD_NUMBER} - ${ status}197 BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result} 408 198 409 199 - Log ----------------------------------------------------------------- … … 413 203 ${gitDiff} 414 204 """ 205 } 206 207 //Standard build email notification 208 def 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 216 generated because of a git hooks/post-receive script following 217 a ref change which was pushed to the Cforall repository. 218 """ + GitLogMessage() 415 219 416 220 def email_to = "cforall@lists.uwaterloo.ca" 417 221 418 if( !bIsSandbox ) {222 if( Settings && !Settings.IsSandbox ) { 419 223 //send email notification 420 224 emailext body: email_body, subject: email_subject, to: email_to, attachLog: log … … 425 229 } 426 230 } 231 232 //=========================================================================================================== 233 // Helper classes/variables/routines 234 //=========================================================================================================== 235 //Description of a compiler (Must be serializable since pipelines are persistent) 236 class 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) 249 class 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 259 class 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 }) 314 Architecture : ${ this.Architecture.name } 315 Arc Flags : ${ this.Architecture.flags } 316 Run All Tests : ${ this.RunAllTests.toString() } 317 Run Benchmark : ${ this.RunBenchmark.toString() } 318 Build Documentation : ${ this.BuildDocumentation.toString() } 319 Publish : ${ this.Publish.toString() } 320 Silent : ${ this.Silent.toString() } 321 """ 322 323 this.GitNewRef = '' 324 this.GitOldRef = '' 325 } 326 } 327 328 def prepare_build() { 329 // prepare the properties 330 properties ([ \ 331 [$class: 'ParametersDefinitionProperty', \ 332 parameterDefinitions: [ \ 333 [$class: 'ChoiceParameterDefinition', \ 334 description: 'Which compiler to use', \ 335 name: 'Compiler', \ 336 choices: 'gcc-6\ngcc-5\ngcc-4.9\nclang', \ 337 defaultValue: 'gcc-6', \ 338 ], \ 339 [$class: 'ChoiceParameterDefinition', \ 340 description: 'The target architecture', \ 341 name: 'Architecture', \ 342 choices: 'x64\nx86', \ 343 defaultValue: 'x64', \ 344 ], \ 345 [$class: 'BooleanParameterDefinition', \ 346 description: 'If false, only the quick test suite is ran', \ 347 name: 'RunAllTests', \ 348 defaultValue: false, \ 349 ], \ 350 [$class: 'BooleanParameterDefinition', \ 351 description: 'If true, jenkins also runs benchmarks', \ 352 name: 'RunBenchmark', \ 353 defaultValue: false, \ 354 ], \ 355 [$class: 'BooleanParameterDefinition', \ 356 description: 'If true, jenkins also builds documentation', \ 357 name: 'BuildDocumentation', \ 358 defaultValue: true, \ 359 ], \ 360 [$class: 'BooleanParameterDefinition', \ 361 description: 'If true, jenkins also publishes results', \ 362 name: 'Publish', \ 363 defaultValue: false, \ 364 ], \ 365 [$class: 'BooleanParameterDefinition', \ 366 description: 'If true, jenkins will not send emails', \ 367 name: 'Silent', \ 368 defaultValue: false, \ 369 ], \ 370 ], 371 ]]) 372 373 final settings = new BuildSettings(params, env.BRANCH_NAME) 374 375 currentBuild.description = settings.DescShort 376 echo settings.DescLong 377 378 return settings 379 } 380 381 def build_stage(String name, Closure block ) { 382 StageName = name 383 echo " -------- ${StageName} -------- " 384 stage(name, block) 385 } 386 387 def notify_server(int wait) { 388 sh """curl --silent --show-error --data "wait=${wait}" -X POST https://cforall.uwaterloo.ca:8082/jenkins/notify > /dev/null || true""" 389 return 390 } 391 392 def make_doc() { 393 def err = null 394 try { 395 sh 'make clean > /dev/null' 396 sh 'make > /dev/null 2>&1' 397 } 398 catch (Exception caughtError) { 399 err = caughtError //rethrow error later 400 sh 'cat *.log' 401 } 402 finally { 403 if (err) throw err // Must re-throw exception to propagate error 404 } 405 }
Note: See TracChangeset
for help on using the changeset viewer.