jimklimov

Jenkinsfile-rescan-MBPs

Mar 16th, 2018 (edited)
427
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/env groovy
  2.  
  3. // Jenkinsfile-rescan-MBPs
  4. // (C) 2018 by Jim Klimov
  5. // This Jenkinsfile makes-believe it is a Declarative pipeline for
  6. // the sake of commonality of our pipeline scripts (build args,
  7. // various options and stuff), but in fact this is a scripted
  8. // pipeline most of the way.
  9. // Its job is to find MultiBranchPipeline items spawned inside an
  10. // organization folder and issue a rescan request (build operation),
  11. // so we can detect new or closed PRs and branches quickly (due to
  12. // JENKINS-49526 MBPs are otherwise polled once a day, hardcoded).
  13.  
  14. import jenkins.model.*
  15. import hudson.model.*
  16. import hudson.util.PersistedList
  17. import jenkins.branch.*
  18.  
  19. // This shared array variable will be populated with the list of parallel stages
  20. def scan_stages = [:]
  21.  
  22. // WARNING: Nowadays generated clauses with pipeline steps must be CPS!
  23. //@NonCPS
  24. def parallelSubtasks(String verbose) {
  25.     def subbuilds = [:]
  26.     def jobs = Jenkins.instance.getAllItems()
  27.  
  28.     jobs.each { j ->
  29.         if (j instanceof com.cloudbees.hudson.plugins.folder.Folder) {
  30.             if (verbose.equals("true")) {
  31.                 echo 'Ignoring JOB which is a com.cloudbees.hudson.plugins.folder.Folder : ' + j.fullName
  32.             }
  33.             return
  34.         }
  35.         if (j instanceof jenkins.branch.OrganizationFolder) {
  36.             if (verbose.equals("true")) {
  37.                 echo 'Ignoring JOB which is a jenkins.branch.OrganizationFolder : ' + j.fullName
  38.             }
  39.             return
  40.         }
  41.         if (! (j instanceof org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject) ) {
  42.             if (verbose.equals("true")) {
  43.                 echo 'Ignoring JOB which is not an MBP: ' + j.fullName
  44.             }
  45.             return;
  46.         }
  47.         if ( ! j.fullName.contains("/") ) {
  48.             echo 'Ignoring MBP JOB which is not under a (organization) folder, so has and hopefully honours a schedule of its own: ' + j.fullName
  49.             return;
  50.         }
  51.         // TODO: Determine that MBP's schedule and only fire below if it is "once a day" (hardcoded)?
  52.  
  53.         subbuilds["${j.fullName}"] = {
  54.             stage("Scan ${j.fullName}") {
  55.                 // Per non-declarative pipeline syntax, no steps{} here
  56.                     echo "Rescanning '${j.fullName}' ..."
  57.                     // Jenkins refuses to "wait" for this type of job...
  58.                     // TODO: Sleep-poll the results (and logs?) of the
  59.                     // spawned child jobs.
  60.                     try {
  61.                         def bbb = build job: "${j.fullName}", quietPeriod: 0, wait: false, propagate: true
  62.                     } catch (Exception e) {
  63.                         // e.g. a disabled repo, like one where a Jenkinsfile
  64.                         // script existed earlier but was removed
  65.                         echo "Failed to trigger scan for ${j.fullName}, skipped"
  66.                     }
  67.             }
  68.         } // end of def subbuilds[j.fullName]
  69.  
  70.     } // jobs.each() clause
  71.  
  72.     return subbuilds
  73. }
  74.  
  75.  
  76. // A declarative pipeline shiny wrapper (we need it
  77. // for common ways of autosetup and params, mostly)
  78. pipeline {
  79.     options {
  80. /*
  81.         description("This job runs regularly to find and rescan multibranch pipeline jobs (e.g. generated via organization folders) to add monitoring of new PRs (and disable monitoring of merged PRs) in a timely fashion.")
  82. */
  83.         disableConcurrentBuilds()
  84.         disableResume()
  85.         durabilityHint('PERFORMANCE_OPTIMIZED')
  86.         buildDiscarder(logRotator(numToKeepStr: '10'))
  87.         skipDefaultCheckout true
  88.     }
  89.     triggers {
  90.         cron('H/15 * * * *')
  91.     }
  92.     agent {label "master||master-real||master-worker"}
  93.     parameters {
  94.         booleanParam (
  95.             defaultValue: false,
  96.             description: 'Print found and skipped items?',
  97.             name: 'JOBLIST_VERBOSE'
  98.         )
  99.     }
  100.     stages {
  101.         stage('Single-exec milestone') {
  102.             steps {
  103.                 milestone 1
  104.             } // steps clause
  105.         }
  106.     }
  107. }
  108.  
  109. // Non-declarative pipeline payload.
  110. // This code below does not work inside a pipeline{} stage{}
  111. // clause nor in the post{} clause - not even with the added
  112. // try/catches for exceptions all around.
  113. // Curiously, when this pipeline job is built by hand
  114. // or triggered by timer, it fails with lots of CPS and
  115. // marshalling exception messages in the end. Replaying
  116. // the same groovy script with no changes just works.
  117. try {
  118.     echo "DISCOVERING JOBS..."
  119.     scan_stages = parallelSubtasks( "${params.JOBLIST_VERBOSE}" )
  120. } catch (java.io.NotSerializableException e) {
  121.     echo "Ignoring NotSerializableException during parallelSubtasks()"
  122. } catch (Exception e) {
  123.     echo "Failed to find jobs or set up parallel scans"
  124.     currentBuild.result = 'FAILED'
  125.     manager.buildAborted()
  126. }
  127.  
  128. try {
  129.     echo "SCHEDULING RESCANS..."
  130.     parallel scan_stages
  131.     echo "SCHEDULING OF RESCANS COMPLETED"
  132. } catch (java.io.NotSerializableException e) {
  133.     echo "Ignoring NotSerializableException during parallelized work"
  134. } catch (Exception e) {
  135.     echo "Failed to trigger parallel scans"
  136.     currentBuild.result = 'FAILED'
  137.     manager.buildAborted()
  138. }
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×