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

"checkout scm" should give the same guarantees on standalone pipeline jobs as on multibranch jobs

      Disclaimer: I know that this might never get implemented, but I still would like to state that this would be an improvement...

      JENKINS-31386 implemented checkout scm for standalone jobs.
      As stated here and here and in the `scm` global variable documentation, this behaves differently from the multibranch checkout scm:

      You may also use this in a standalone project configured with Pipeline script from SCM, though in that case the checkout will just be of the latest revision in the branch, possibly newer than the revision from which the Pipeline script was loaded.

      This has the nasty side effect that your sources might not come from the same commit as your build definition.

      So the request is to give the same guarantee of always checking out the same commit when doing checkout scm also in standalone projects.

      Workaround (if you have access to currentBuild.rawBuild and you know that you are using git:

      def scmEnv = new HashMap<String, String>()
      scm.buildEnvironment(currentBuild.rawBuild, scmEnv)
      echo "$scmEnv"
      node {
          sh "sleep 5"
          echo "first"
          checkout([
                 $class: 'GitSCM',
                 branches: [[name: scmEnv.GIT_COMMIT]],
                 userRemoteConfigs: scm.userRemoteConfigs
          ])
       
          sh "sleep 5"
      }
       
      node {
          echo "second"
          checkout([
                  $class: 'GitSCM',
                  branches: [[name: scmEnv.GIT_COMMIT]],
                  userRemoteConfigs: scm.userRemoteConfigs
          ])
      }
      

          [JENKINS-45808] "checkout scm" should give the same guarantees on standalone pipeline jobs as on multibranch jobs

          Another workaround is to ask scm-api to give you a sensible scm...

          def sources = resolveScm(source: github(...), targets: ['master'])
          node {
            checkout sources
            ...
          }
          node {
            checkout sources
            ...
          }
          

          though the resolveScm for git is not as nice due to $class references, it works just the same

          resolveScm source: [$class: 'GitSCMSource', credentialsId: '', id: '_', remote: '', traits: [[$class: 'jenkins.plugins.git.traits.BranchDiscoveryTrait']]], targets: ['']
          

          Stephen Connolly added a comment - Another workaround is to ask scm-api to give you a sensible scm... def sources = resolveScm(source: github(...), targets: [ 'master' ]) node { checkout sources ... } node { checkout sources ... } though the resolveScm for git is not as nice due to $class references, it works just the same resolveScm source: [$class: 'GitSCMSource' , credentialsId: '', id: ' _ ', remote: ' ', traits: [[$class: ' jenkins.plugins.git.traits.BranchDiscoveryTrait ']]], targets: [' ']

          Jesse Glick added a comment -

          Essentially the same as JENKINS-36453, albeit with a slightly different impact. Either way, we would need a new CpsSCMSourceFlowDefinition.

          Jesse Glick added a comment - Essentially the same as  JENKINS-36453 , albeit with a slightly different impact. Either way, we would need a new CpsSCMSourceFlowDefinition .

          Jesse Glick added a comment -

          Using recent-ish updates, you can just use

          def hash
          node {
              sh "sleep 5"
              echo "first"
              hash = checkout(scm).GIT_COMMIT
              sh "sleep 5"
          }
           node {
              echo "second"
              checkout([
                      $class: 'GitSCM',
                      branches: [[name: hash]],
                      userRemoteConfigs: scm.userRemoteConfigs
              ])
          }
          

          Jesse Glick added a comment - Using recent-ish updates, you can just use def hash node { sh "sleep 5" echo "first" hash = checkout(scm).GIT_COMMIT sh "sleep 5" } node { echo "second" checkout([ $class: 'GitSCM' , branches: [[name: hash]], userRemoteConfigs: scm.userRemoteConfigs ]) }

          Jesse Glick added a comment -

          Yet another workaround is of course to just create a multibranch folder configured to only match one branch.

          Jesse Glick added a comment - Yet another workaround is of course to just create a multibranch folder configured to only match one branch.

          Martin Sander added a comment -

          Hey jglick, thanks for considering this.

          Using recent-ish updates, you can just use

          ...

          That one still has the problem that the commit checked out by `checkout` might not be the same as the one that contained the Jenkinsfile that you are running.
          I have to admit that this is kind of unlikely (although the sleep 5 does not really help in that respect), but it might happen either way.

          Martin Sander added a comment - Hey jglick , thanks for considering this. Using recent-ish updates, you can just use ... That one still has the problem that the commit checked out by `checkout` might not be the same as the one that contained the Jenkinsfile that you are running. I have to admit that this is kind of unlikely (although the sleep 5 does not really help in that respect), but it might happen either way.

            Unassigned Unassigned
            0x89 Martin Sander
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: