Trigger jenkins build if only a specific file is changed

Viewed 17499

I have my codebase in GIT. There are 5 files in the code base i.e.

  • File1
  • File2
  • File3
  • File4
  • File5

I want to trigger a jenkins build only if File 2 is changed.Please note that, post the build is triggered it should pull the entire codebase.

I tried using poll SCM, but the problem is that the build gets triggered if any of the files in the repository are changed.I want to trigger it only if File 2 changes.

Is it possible?

5 Answers

Here's how I would do it.

  1. Configure your Jenkins job to Trigger builds remotely.

    This enables a build trigger URL in the form of JENKINS_URL/job/MYJOB/build?token=TOKEN_NAME. You have to specify the token name yourself.

  2. Configure a git post-receive hook on your repo to call that trigger.

    The script for the hook is usually under .git/hooks/post-receive. The post-receive hook runs after the entire process is completed and can be used to update other services or notify users.

    A post-receive hook gets its arguments from stdin, in the form <oldrev> <newrev> <refname>.

    You can retrieve the file list from the new HEAD commit and then only proceed to the next step if it includes File2. Something like this (not tested):

    #!/bin/bash
    while read oldrev newrev refname
    do
        # list of changed files for a commit
        filelist=$(git diff-tree --no-commit-id --name-only -r $newrev)
        if [[ $filelist == *"File2"* ]]; then
            # call the URL according to your build trigger config
        fi
    done
    

More details on git hooks.

When you configure the git checkout in Jenkins, there is a button to add additional behaviors. One of those options is to Polling ignores commits in certain paths. I haven't actually used it, but it is my understanding that this will do what you are looking for. There is an option for includes and excludes. You would just use the includes, I believe.

I was able to do it using this plugin and it worked like a charm.

You need to install the plugin Generic Webhook Plugin in Jenkins and provide the following values in configuration.

variable : changed_files

expression : $.commits[].['modified','added','removed'][]

expressionType: JSONPath

Under options: text: $changed_files

expression: path/to/your/file

https://github.com/jenkinsci/generic-webhook-trigger-plugin/blob/master/src/test/resources/org/jenkinsci/plugins/gwt/bdd/gitlab/gitlab-push-specific-folder.feature

Before I start, you should probably do this in github actions and it would be very simple, unless like me you're forced to use Jenkins then this is for you.
So after a bit of searching for this answer I was able to do it with generic webhook trigger, which is the comment above me that got 0 votes, I'll try to be a bit more clear on the process:

  1. Install the generic webhook trigger plugin to Jenkins there you can pull variables from the github webhook payload
  2. You can then create a job using the generic webhook trigger plugin
  3. I used 3 variables from the github webhook payload: (written in the plugins json path expression)
    • $.ref (branch)
    • $.head_commit.modified (squashed commit modified files array)
    • $.html_url (the repo url - since I want to do action on repo if changed)
  4. In Job under the generic webhook trigger section you can use the optional filter to decide if the job should be triggered or not. for me it was a simple regex of checking branch master and that the "VERSION" file is among the modified files
  5. Go to your Github repo and configure in settings > hooks > new webhook with url http://JENKINS_URL/generic-webhook-trigger/invoke (I picked it to trigger on PUSH events which is what matters to me)

Debugging:
Github is actually great on this, once you configure the webhook you can see every POST sent to Jenkins and see the Jenkins response. There's also good examples in the generic webhook trigger docs.

Notes:
Pay attention that different github actions have different payloads: a PR action will not have any modified files array etc.

Related