Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-54285

Changeset not reflective of Pull Request

    Details

    • Similar Issues:

      Description

      I'm using Blue Ocean's default multi-branch setup for GitHub. I am using Jenkins to build and test Pull Requests from GitHub.

      I have a repository with multiple subproject directories that I would like to selectively build and test depending on changes in the Pull Request. Looking at the documentation it seems like I should use `when { changeset 'my-dir/**' }` to do this; however the changeset does not contain the changes from the Pull Request, but instead contains the changes since last build + the changes merged to master since the last build.

       

      I think the behavior here should be to consider the changes in the Pull Request to make it possible to use this conditional.

        Attachments

          Activity

          Hide
          gauthierm Michael Gauthier added a comment - - edited

          I was able to work around this issue by defining a function for my pipeline:

          def boolean hasChangesIn(String module) {
            return !env.CHANGE_TARGET || sh(
              returnStatus: true,
              script: "git diff --name-only origin/${env.CHANGE_TARGET}...${env.GIT_COMMIT} | grep ^${module}/"
            ) == 0
          }
          

          and then using:

          when {
            expression {
              return hasChangesIn('my-dir')
            }
          }
          

          in my pipeline stages

          Show
          gauthierm Michael Gauthier added a comment - - edited I was able to work around this issue by defining a function for my pipeline: def boolean hasChangesIn( String module) { return !env.CHANGE_TARGET || sh( returnStatus: true , script: "git diff --name-only origin/${env.CHANGE_TARGET}...${env.GIT_COMMIT} | grep ^${module}/" ) == 0 } and then using: when { expression { return hasChangesIn( 'my-dir' ) } } in my pipeline stages
          Hide
          gauthierm Michael Gauthier added a comment -

          After a bit more testing, there's an improved version of the hasChangesIn that works for our monorepo:

          def boolean hasChangesIn(String module) {
              if (env.CHANGE_TARGET == null) {
                  return true;
              }
          
              def MASTER = sh(
                  returnStdout: true,
                  script: "git rev-parse origin/${env.CHANGE_TARGET}"
              ).trim()
          
              // Gets commit hash of HEAD commit. Jenkins will try to merge master into
              // HEAD before running checks. If this is a fast-forward merge, HEAD does
              // not change. If it is not a fast-forward merge, a new commit becomes HEAD
              // so we check for the non-master parent commit hash to get the original
              // HEAD. Jenkins does not save this hash in an environment variable.
              def HEAD = sh(
                  returnStdout: true,
                  script: "git show -s --no-abbrev-commit --pretty=format:%P%n%H%n HEAD | tr ' ' '\n' | grep -v ${MASTER} | head -n 1"
              ).trim()
          
              return sh(
                  returnStatus: true,
                  script: "git diff --name-only ${MASTER}...${HEAD} | grep ^${module}/"
              ) == 0
          }
          
          Show
          gauthierm Michael Gauthier added a comment - After a bit more testing, there's an improved version of the hasChangesIn that works for our monorepo: def boolean hasChangesIn( String module) { if (env.CHANGE_TARGET == null ) { return true ; } def MASTER = sh( returnStdout: true , script: "git rev-parse origin/${env.CHANGE_TARGET}" ).trim() // Gets commit hash of HEAD commit. Jenkins will try to merge master into // HEAD before running checks. If this is a fast-forward merge, HEAD does // not change. If it is not a fast-forward merge, a new commit becomes HEAD // so we check for the non-master parent commit hash to get the original // HEAD. Jenkins does not save this hash in an environment variable. def HEAD = sh( returnStdout: true , script: "git show -s --no-abbrev-commit --pretty=format:%P%n%H%n HEAD | tr ' ' '\n' | grep -v ${MASTER} | head -n 1" ).trim() return sh( returnStatus: true , script: "git diff --name-only ${MASTER}...${HEAD} | grep ^${module}/" ) == 0 }
          Hide
          atikhonova Anna Tikhonova added a comment -

          I wanted to use 'when { changeset ... }' to test changes in my monorepo as well (I'm using Bitbucket branch source, Bitbucket Server) and then came to find this... Why don't we have pull request changes? Webhook payload has the destination branch, so why not have the behaviour the author suggested in the description?

          Show
          atikhonova Anna Tikhonova added a comment - I wanted to use 'when { changeset ... }' to test changes in my monorepo as well (I'm using Bitbucket branch source, Bitbucket Server) and then came to find this... Why don't we have pull request changes? Webhook payload has the destination branch, so why not have the behaviour the author suggested in the description?

            People

            • Assignee:
              Unassigned
              Reporter:
              gauthierm Michael Gauthier
            • Votes:
              5 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

              • Created:
                Updated: