jenkinsci / generic-webhook-trigger-plugin

Can receive any HTTP request, extract any values from JSON or XML and trigger a job with those values available as variables. Works with GitHub, GitLab, Bitbucket, Jira and many more.
https://plugins.jenkins.io/generic-webhook-trigger
410 stars 162 forks source link

Existing jobs configured with JobDSL are not immediately registered with generic webook #311

Closed ntfc closed 5 months ago

ntfc commented 6 months ago

Jenkins and plugins versions report

Here is my system info (other plugins omitted):

Jenkins: 2.458
OS: Linux - 5.10.215-203.850.amzn2.x86_64
Java: 17.0.11 - Eclipse Adoptium (OpenJDK 64-Bit Server VM)
---
job-dsl:1.87
generic-webhook-trigger:2.2.1
pipeline-build-step:540.vb_e8849e1a_b_d8
pipeline-graph-analysis:216.vfd8b_ece330ca_
pipeline-groovy-lib:704.vc58b_8890a_384
pipeline-input-step:491.vb_07d21da_1a_fb_
pipeline-milestone-step:119.vdfdc43fc3b_9a_
pipeline-model-api:2.2184.v0b_358b_953e69
pipeline-model-definition:2.2184.v0b_358b_953e69
pipeline-model-extensions:2.2184.v0b_358b_953e69
pipeline-rest-api:2.34
pipeline-stage-step:312.v8cd10304c27a_
pipeline-stage-tags-metadata:2.2184.v0b_358b_953e69
pipeline-stage-view:2.34
workflow-aggregator:596.v8c21c963d92d
workflow-api:1291.v51fd2a_625da_7
workflow-basic-steps:1049.v257a_e6b_30fb_d
workflow-cps:3894.vd0f0248b_a_fc4
workflow-durable-task-step:1336.v768003e07199
workflow-job:1400.v7fd111b_ec82f
workflow-multibranch:783.va_6eb_ef636fb_d
workflow-scm-step:427.v4ca_6512e7df1
workflow-step-api:657.v03b_e8115821b_
workflow-support:896.v175a_a_9c5b_78f

Hi,

I am running into an issue registering an existent job to use the generic webhook plugin. This job was previously relying on a git push trigger and even though it is now shown as correctly configured in the UI to use the generic webhook, it is not being returned on the webhook response until I restart Jenkins or manually re-save the job.

I can reproduce it by:

  1. Use a job to process a JobDSL script (attached further down) that creates a job not configured with the generic webhook plugin.
  2. Now re-run the JobDSL to enable the generic-webhook-plugin.
  3. The job is correctly configured in with the generic-webhook-plugin but it is not returned in the /generic-webhook-trigger response.
  4. Now if either restart Jenkins or "Configured" and "Save" the job via the UI (with no changes) then it starts being returned in the /generic-webhook-trigger response.

It seems that somehow the plugin is not picking the event where the job is updated, but looking at the code it seems totally correct so I am not even sure where the issue is.

I am currently reproducing this using a parameterized job (boolean parameter USE_GENERIC_WEBHOOK) that processes the following JobDSL:

job("test-webhook") {
    label('built-in')

    triggers {
      if ("${USE_GENERIC_WEBHOOK}" == "false") {
            gitHubPushTrigger()
        } else {
            genericTrigger {
                genericVariables {
                    genericVariable {
                        key("GIT_TAG")
                        value("\$.ref")
                        expressionType("JSONPath")
                        regexpFilter("refs/tags/")
                        defaultValue("main")
                    }
                }

                tokenCredentialId("generic-webhook-trigger-url-token")
                printContributedVariables(true)
            }
        }
    }
}

I am not entirely sure if this is a problem with this plugin or JobDSL but maybe others have found (automated) ways around this or there is a way to fix in this plugin.

Thanks in advance!

ntfc commented 6 months ago

Seems to be a JobDSL limitation: https://issues.jenkins.io/browse/JENKINS-64553 😭

tomasbjerre commented 6 months ago

Ok! Thanks for reporting. Will probably help other users if they have this problem.

ntfc commented 5 months ago

I crafted a nasty workaround that could help solving this, basically have the seed job trigger a downstream pipeline job that in turn uses the Groovy API to manually call the JobFinderImpersonater#onUpdated.

Here is its definition in case it helps others:

stage("call generic-webhook-trigger JobFinderImpersonator") {
    def upstreamProject = currentBuild.rawBuild.getCause(hudson.model.Cause$UpstreamCause)?.upstreamProject
    if (upstreamProject == null) {
        error "Job must be automatically triggered by seed job and not manually executed"
    }

    def seedJob = Jenkins.instance.getItem(upstreamProject)
    if (seedJob == null) {
        error "Seed job ${upstreamProject} does not exist"
    }

    def gwtExtensions = Jenkins.getInstance().getExtensionList(JobFinderImpersonater.class)
    if (gwtExtensions == null || gwtExtensions.size() == 0) {
        error "Could not find the JobFinderImpersonator extension from the generic-webhook-trigger plugin."
    }
    if (gwtExtensions.size() > 1) {
        error "Unexpectedly found more than 1 JobFinderImpersonator from the generic-webhook-trigger plugin."
    }

    def gwtJobFinderImpersonator = gwtExtensions.get(0)

    def lastBuild = seedJob.lastBuild

    def generatedJobsAction = lastBuild.getAction(GeneratedJobsBuildAction)

    if (generatedJobsAction == null) {
        echo "No generated jobs found in last seed job build '${lastBuild}'."
        return
    }

    def generatedJobs = lastBuild.getAction(GeneratedJobsBuildAction).items
    echo "Last seed job build '${lastBuild}' has generated ${generatedJobs.size()} jobs."

    generatedJobs.each {
        echo "Sending ${it.getDisplayName()} to generic-webhook-trigger"
        // we can send everything since it will be filtered by the plugin
        gwtJobFinderImpersonator.onUpdated(it)
    }
}

This should require approving the following method signatures in script approval:

method org.jenkinsci.plugins.workflow.support.steps.build.RunWrapper getRawBuild
method hudson.model.Run getCause java.lang.Class
method hudson.model.Cause$UpstreamCause getUpstreamProject
staticMethod jenkins.model.Jenkins getInstance
method hudson.model.ItemGroup getItem java.lang.String
method jenkins.model.Jenkins getExtensionList java.lang.Class
method hudson.model.Job getLastBuild
method hudson.model.Actionable getAction java.lang.Class
method javaposse.jobdsl.plugin.actions.GeneratedJobsBuildAction getItems
method hudson.model.listeners.ItemListener onUpdated hudson.model.Item
mawinter69 commented 5 months ago

Opened https://github.com/jenkinsci/jenkins/pull/9304 to fix the issue from JENKINS-64553 which also solve this here

mawinter69 commented 5 months ago

Fix will be included in next LTS 2.452.2

ntfc commented 5 months ago

Also tested it works as expected now with 2.460.

Thank you @mawinter69 !

tomasbjerre commented 4 months ago

Continuing this in #319