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
411 stars 162 forks source link

How to Variabilize the Expression in the Optional filter section #109

Closed prudhvishankar closed 5 years ago

prudhvishankar commented 5 years ago

Hey @tomasbjerre I have a query regarding the generic webhook plugin , i will tell my usecase can you please tell me how can i achieve that.

How can i variablize the regex in the optional filter section. can u please let me know how can i acheive this

tomasbjerre commented 5 years ago

https://github.com/jenkinsci/generic-webhook-trigger-plugin/blob/master/ISSUE_TEMPLATE

prudhvishankar commented 5 years ago
tomasbjerre commented 5 years ago

What does $branch resolve to? What is the branch name that does not match?

Your current regexp: https://jex.im/regulex/#!flags=&re=epic_%7C%5Erp_%7C%5Erel_%7C%5Emajor_%7C%5Emaster%24%7C%5Edevelop%24%7C%5Ebau_%7Chotifx_

Looks a bit strange. Perhaps this is what you want: https://jex.im/regulex/#!flags=&re=%5Erefs%2Fheads%2F(epic_.*%7Crp_.*%7Crel_.*%7Cmajor_.*%7Cmaster%7Cdevelop%7Cbau_.*%7Chotifx_.*)%24

prudhvishankar commented 5 years ago

Hi @tomasbjerre i am having a requiremet to dynamically pass the regex in the optional filter instead of hardcoding the regex in the "regexpFilterExpression"

Example: pipeline { agent { label 'TEST' } branchFilter = '^epic*|^rp|^rel_|^major_*|^master$|^develop$' triggers { GenericTrigger( genericVariables: [ [key: 'branch', value: '$.push.changes[0].old.name'] ],

 causeString: 'Triggered on $branch',

 token: '123',

 printContributedVariables: true,
 printPostContent: true,

 regexpFilterText: '$branch',
 regexpFilterExpression: '$branchFilter'

)

} stages { stage('builds') { steps { sh''' echo $branch ''' } } } }

how can variabilize the regexpFilterExpression is what my concern and i have tried using the above code it dint worked.

tomasbjerre commented 5 years ago

Single quotes means variables are not rendered. So this:

 regexpFilterText: '$branch',
 regexpFilterExpression: '$branchFilter'

Should be:

 regexpFilterText: '$branch',
 regexpFilterExpression: branchFilter
prudhvishankar commented 5 years ago

pipeline { agent { label 'TEST' } branchFilter = '^major_*' triggers { GenericTrigger( genericVariables: [ [key: 'branch', value: '$.push.changes[0].old.name'] ],

 causeString: 'Triggered on $branch',

 token: '123',

 printContributedVariables: true,
 printPostContent: true,

 regexpFilterText: '$branch',
 regexpFilterExpression: branchFilter
)

} stages { stage('setup') { steps { sh''' echo $branch ''' } } } }

I have tested the way you suggested but unable to acheive it throwing the error as :

jenkins log :

org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: WorkflowScript: 3: Not a valid section definition: "branchFilter = '^major*'". Some extra configuration is required. @ line 3, column 3. branchFilter = '^major*' ^

tomasbjerre commented 5 years ago

Because your regexp has invalid syntax.

This: branchFilter = '^major_*'

Should be: branchFilter = '^major_.*'

prudhvishankar commented 5 years ago

Again i got the same error @tomasbjerre

org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: WorkflowScript: 3: Not a valid section definition: "branchFilter = '^major.*'". Some extra configuration is required. @ line 3, column 3. branchFilter = '^major.*'

tomasbjerre commented 5 years ago

Try again, without changig anything. You need to run it twice when changing configuration. It is described in the "Pipeline" section in the readme.

tomasbjerre commented 5 years ago

Actually, that is probably not the problem...

This:

pipeline {
    agent { label 'TEST' }
  branchFilter = '^major_.*'
  triggers {

Needs to be changed. I think this should work:

branchFilter = '^major_.*'

pipeline {
    agent { label 'TEST' }
  triggers {
prudhvishankar commented 5 years ago

Thanks @tomasbjerre issue got resolved and thanku very much for your quick response

prudhvishankar commented 5 years ago

Hi @tomasbjerre is it possible to give the branch name which we get from the bitbucket payload in the regexpFilterExpression :

branchFilter = '$branch' pipeline { agent { label 'TEST' } triggers { GenericTrigger( genericVariables: [ [key: 'branch', value: '$.push.changes[0].old.name'] ],

 causeString: 'Triggered on $branch',

 token: '123',

 printContributedVariables: true,
 printPostContent: true,

 regexpFilterText: '$branch',
 regexpFilterExpression: branchFilter
)

} stages { stage('setup') { steps { sh''' echo $branch ''' } } } } i tried giving that but it is not triggering the job when a commit happened.

can you please help me in sorting out this

tomasbjerre commented 5 years ago

No the regexpFilterExpression i static. Variables are only resolved in the regexpFilterText.

prudhvishankar commented 5 years ago

I have a use case in that i have a pipeline job major_testing_CI and epic_testing_CI and these job names are nothing but (branch_name + CI) . Now when ever i commited to the epic_testing branch then corresonding epic_testing_CI job should be triggered similarly the other job (major_testing_CI) needs to be triggered whenever there is commit in the major_testing.

How can i acheive this using the plugin

tomasbjerre commented 5 years ago

With regexpFilterText: '$branch' perhaps first job can have:

regexpFilterExpression: '^refs/heads/epic_testing$'

And second job:

regexpFilterExpression: '^refs/heads/major_testing$'

And if you are using multibranch pipeline, there is a BRANCH_NAME variable, you can just do:

regexpFilterExpression: 'refs/heads/' + BRANCH_NAME
prudhvishankar commented 5 years ago

HI @tomasbjerre thanks for your response but in my requirement we wont create the jobs manually so when ever a branch got created in the bitbucket, jenkins will get branch using api call and after that a job is created dynamically with the naming convention as branchname-CI . Sooo this job will use my code where the plugin is configured and when ever there is commit in respective branch (ex: major-develop) then it should automatically should trigger the respective jenkins job (ex: major-develop-CI)

This is my overview of my usecase. can u please help me in acheving this

tomasbjerre commented 5 years ago

There is example of job dsl in the readme.

prudhvishankar commented 5 years ago

Hi,

Thanks for clarifying most of my queries. I think I have one more that needs a clarity. Is there a ways I can add the branch name to the webhook url?

The reason I ask this is, I am working on an automation where I will setup the Jenkins Jobs on the fly for the branches created in my repository. So I will be defining a template job which I will clone every time I need to create a new job for the branch thats been created. In this case, the regular expression that matches the $branch cant be hard coded.

I would want this to be passed externally after I clone my template job. The options I am considering are,

a) Add the branch name as request parameters to the webhook URL so that the same I can define in the plugin (as request parameter)

b) Configure the regular expression outside the job - Injecting the parameter as job level parameters.

tomasbjerre commented 5 years ago

I think I would go with option a.

prudhvishankar commented 5 years ago

Thanks for the quick reply. Is there a way we can get the branch name in the webhook dynamically (without hardcoding). Is something like this possible? https://jenkinslocalurl.com/generic-webhook-trigger/invoke?branchname=$branch

tomasbjerre commented 5 years ago

That depends on what git service you are using.

prudhvishankar commented 5 years ago

We are using bitbucket. In your experience is the above case is possible with bitbucket?

tomasbjerre commented 5 years ago

I don't know what variables, if any, are available like that. It is definitely available in the webhook payload.

Perhaps you want to have the same job triggered for any branch. And in that job you trigger other jobs depending on what branch you identified.

prudhvishankar commented 5 years ago

Thats is the last option i am considering .

Thanks for ur response

Thilaknath commented 4 years ago

Hello @tomasbjerre, How do I extract the variables from the trigger section to a stage I plan to execute below. For example:

pipeline {
    agent any
    triggers {
        GenericTrigger(
                genericVariables: [
                        [key: 'prNumber', value: 'number'],
                        [key: 'prAction', value: 'action'],
                        [key: 'prMergeStatus', value: 'pull_request.merged']
                ],

                causeString: '$prNumber merged',

                printContributedVariables: true,
                printPostContent: true,

                silentResponse: false,

                regexpFilterText: '$prMergeStatus',
                regexpFilterExpression: '\\b(\\w*true\\w*)\\b'
        )
    }
    stages {
        stage('Nightly Job to Delete Stale Apps'){
            steps{
                echo "Start excecution of stage: ${prNumber}"
                catchError(buildResult: 'FAILURE', stageResult: 'FAILURE'){
                    dockerExecute(
                            script: this,
                            dockerImage: '***********',
                            dockerWorkspace: '/home/piper',
                            dockerEnvVars: [CF_HOME: "/home/piper", CF_PLUGIN_HOME: "/home/piper"]
                    ){
                        withCredentials(
                                [usernamePassword(credentialsId: '**********', passwordVariable: 'pwd', usernameVariable: 'user')]
                        ) {
                            script{
                                sh "cf login -u \"${user}\" -p '${pwd}' -a '**********' -o '*********' -s '********'"
                                sh "cf apps"
                            }
                        }
                    }
                }
            }
            post{
                always{
                    deleteDir()
                }
            }
        }
    }
}

When I try to do the above I get the error

groovy.lang.MissingPropertyException: No such property: prNumber for class: groovy.lang.Binding