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 }

            People

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

              Dates

              • Created:
                Updated: