8

I can call another jenkins job using the build command. Is there a way I can tell another job to do a branch scan?

A multibranch pipeline job has a UI button "Scan Repository Now". When you press this button, it will do a checkout of the configured SCM repository and detect all the branches and create subjobs for each branch.

I have a multibranch pipeline job for which I have selected the "Suppress automatic SCM triggering" option because I only want it to run when I call it from another job. Because this option is selected, the multibranch pipeline doesn't automatically detect when new branches are added to the repository. (If I click "Scan Repository Now" in the UI it will detect them.)

Essentially I have a multibranch pipeline job and I want to call it from another multibranch pipeline job that uses the same git repository.

node {
  if(env.BRANCH_NAME == "the-branch-I-want" && other_criteria) {
    //scanScm "../my-other-multibranch-job" <--- scanScm is a fake command I made up
    build "../my-other-multibranch-job/${env.BRANCH_NAME}"

I get an error on that build line, because the target multibranch pipeline job does not yet know that BRANCH_NAME exists. I need a way to trigger an SCM re-scan in the target job from this current job.

daspilker
  • 8,154
  • 1
  • 35
  • 49
Jonathan Lynch
  • 557
  • 1
  • 5
  • 12

2 Answers2

9

Similar to what you figured out yourself, I can contribute my optimization that actually waits until the scan has finished (but is subject to Script Security):

// Helper functions to trigger branch indexing for a certain multibranch project.
// The permissions that this needs are pretty evil.. but there's currently no other choice
//
// Required permissions:
// - method jenkins.model.Jenkins getItemByFullName java.lang.String
// - staticMethod jenkins.model.Jenkins getInstance
//
// See:
// https://github.com/jenkinsci/pipeline-build-step-plugin/blob/3ff14391fe27c8ee9ccea9ba1977131fe3b26dbe/src/main/java/org/jenkinsci/plugins/workflow/support/steps/build/BuildTriggerStepExecution.java#L66
// https://stackoverflow.com/questions/41579229/triggering-branch-indexing-on-multibranch-pipelines-jenkins-git
void scanMultiBranchAndWaitForJob(String multibranchProject, String branch) {
    String job = "${multibranchProject}/${branch}"
    // the `build` step does not support waiting for branch indexing (ComputedFolder job type),
    // so we need some black magic to poll and wait until the expected job appears
    build job: multibranchProject, wait: false
    echo "Waiting for job '${job}' to appear..."

    while (Jenkins.instance.getItemByFullName(job) == null || Jenkins.instance.getItemByFullName(job).isDisabled()) {
        sleep 3
    }
}
StephenKing
  • 36,187
  • 11
  • 83
  • 112
8

Ended up figuring this out shortly after posting the question. Calling build against the base multibranch pipeline job as opposed to a branch causes it to re-scan. The solution to my above snippet would have ended up looking something like...

node {
  if(env.BRANCH_NAME == "the-branch-I-want" && other_criteria) {
    build job: "../my-other-multibranch-job", wait: false, propagate: false // scan for branches
    sleep 2 // scanning takes time
    build "../my-other-multibranch-job/${env.BRANCH_NAME}"

The wait: false is important because otherwise you get "ERROR: Waiting for non-job items is not supported". The multibranch "parent" job is closer to a folder than a job, but it's a folder that supports the build command, and it does so by scanning the SCM.

But solving this just led to another problem, which is that with wait: false we have no way of knowing when the SCM Scan finished. If you have a large repository (or you're short on jenkins agents), the branch won't get discovered until after the second build command has already failed due to the branch not existing. You could bump the sleep time even higher, but that doesn't scale.

Fortunately, it turns out manually initiating the SCM scan isn't even needed if you have github webhooks set up for your jenkins. The branch will be discovered more-or-less instantly, so for my purposes this is solved another way. The reason I was running into it is we don't have webhooks set up in our dev jenkins, but once I move this code to prod it will work fine.

If you're trying to use JobDSL to set up multibranches calling multibranches and you don't have webhooks or something equivalent, the better path is probably to abandon multibranch for your second tier of jobs and use JobDSL to create folders and manage the branch jobs yourself.

Jonathan Lynch
  • 557
  • 1
  • 5
  • 12