Triggering Branch Indexing on Multibranch Pipelines (Jenkins/Git)
Asked Answered
Q

3

12

I'm trying to automatically trigger 'Branch Indexing' on a Multibranch Pipelines job in Jenkins.

At the moment, only one method seems to actually work, which is polling, but I am unable to do that and polling is a bad solution anyway.

The plug-in doesn't support 'Trigger builds remotely (e.g., from scripts)' (options are not saved), so I cannot trigger it via a web hook on push etc.

I tried creating a 'trigger' freestyle build on the repo but the 'Post-build Actions - Build other projects' claims the Multibranch Pipeline project is not a buildable project.

If polling is the only way I can do this, then I need to disable automatic SCM triggering (otherwise we get duplicate builds when we re-index) because I'll need to enable web hook triggering on the branch projects.

But that doesn't work, because I'm setting up the web hook via a pipeline script in the branch project, and you need to have built it at least once to have that property registered.

I've been going around in circles for a while, so hopefully I've just missed something obvious, but any help would be appreciated.

I imagined being able to do one of the following

  • Somehow trigger the multi-branch project as a downstream project

  • Poll the multibranch project, and only build branch projects which have not been built before

Cheers

Quadrinomial answered 10/1, 2017 at 22:2 Comment(0)
F
9

The method ComputedFolder.scheduleBuild() can be invoked from a groovy script.

I have just triggered branch indexing in one multibranch pipeline project from the groovy code in a different multibranch pipeline project, which is then triggering a downstream build in that project.

The code is something like:

@NonCPS
void scanRepo(String downStreamProjectName) {
    Jenkins.instance.getItemByFullName(downStreamProjectName).scheduleBuild()
}
...
String downStreamProject = 'my-folder/my-multibranch-project'
String downStreamJob = "${downStreamProject}/${env.BRANCH_NAME}"
if (Jenkins.instance.getItemByFullName(downStreamJob) == null) {
    scanRepo(downStreamProject)
    while (Jenkins.instance.getItemByFullName(downStreamJob) == null) {
        sleep(1)
    }
}
build([job: downStreamJob, wait: false, quietPeriod: 0])

Notice that Jenkins.instance.getItemByFullName(downStreamProjectName) is the WorkflowMultiBranchProject which is not Serializable, so some care needs to be taken.

Fourpenny answered 31/3, 2017 at 23:41 Comment(4)
Thanks! Jenkins.instance.getItemByFullName(downStreamProjectName).scheduleBuild() was exactly what I was looking for to trigger a rescan of my Multibranch PipelineShellbark
Is there a way to wait for this job to finish rather than doing 'sleep(1)'?Unreserved
The only downside of this approach are the pretty evil permissions that it needs (through script approval). The pipeline-build-step plugin's build step unfortunately does not yet support it (TODO in code), which would be probably a better approach.Paragon
Probably this is a bit hard exactly because we cannot wait for it, as the call is non-blocking.Paragon
P
3

Based on @jjc's answer, I've created a version using the build step also for triggering the scan:

String downStreamProject = 'my-folder/my-multibranch-project'
String downStreamJob = "${downStreamProject}/${env.BRANCH_NAME}"
if (Jenkins.instance.getItemByFullName(downStreamJob) == null) {
    // we would need "wait: true", which is not possible as of now
    // https://github.com/jenkinsci/pipeline-build-step-plugin/blob/3ff14391fe27c8ee9ccea9ba1977131fe3b26dbe/src/main/java/org/jenkinsci/plugins/workflow/support/steps/build/BuildTriggerStepExecution.java#L66
    build job: downStreamProject, wait: false
    // continue only once the expected job appears
    while (Jenkins.instance.getItemByFullName(downStreamJob) == null) {
        sleep(1)
    }
}
build downStreamJob

This requires the following signatures to be approved:

  • method jenkins.model.Jenkins getItemByFullName java.lang.String
  • staticMethod jenkins.model.Jenkins getInstance
Paragon answered 4/12, 2017 at 9:6 Comment(0)
M
0

The easiest option by far (that I'm aware of) is to remotely tell the Jenkins Git plugin that there's a new commit for a defined repository. However, this will not trigger Jenkins to start a job immediately. What happens is that the Git plugin starts (re-)indexing the specific repository. The Jenkins job is then started if changes are detected.

From your repository (GitHub, GitLab, etc.) you should trigger the following URL:

http://my-jenkins-host/git/[email protected]:group/repository.git&delay=0sec

The value for url must match the SCM URL you configured in the Jenkins job (Git plugin)!

Gotcha: it may be that your Jenkins is not deployed under the root context (/) in which case the URL would be http://my-jenkins-host/context-path/git/...

Meteorograph answered 26/1, 2018 at 7:24 Comment(1)
Can you explain what is configurable in this url - my-jenkins-host/git/…? For eg http://<jenkins-host>/git/notifyCommit?url=<github-repo-url>&delay=0s is this correct? Also how to trigger this URL? What are headers? Can you give a working example? in python preferably? ThanksOeuvre

© 2022 - 2024 — McMap. All rights reserved.