Passionate Engineer
Passionate Engineer

Reputation: 10412

Jenkins pipeline git command submodule update

I want to update submodule on git clone.

Is there a way to do this with Jenkins pipeline Git command?

Currently I'm doing this...

git branch: 'master',
    credentialsId: 'bitbucket',
    url: 'ssh://bitbucket.org/hello.git'

It doesn't however update submodule once cloned

Upvotes: 42

Views: 85018

Answers (5)

VonC
VonC

Reputation: 1324258

With the current Git plugin, you don't even need that.

The Git plugin supports repositories with submodules which in turn have submodules themselves.
This must be turned on though:

in Job Configuration -> Section Source Code Management, Git -> Advanced Button (under Branches to build) -> Recursively update submodules

But the OP is using pipeline.

So a simple first build step is enough:

git submodule update --init --recursive

However, the OP adds:

Yes but if I'm using sh 'git submodule update --init --recursive', this will use $HOME/id_rsa right? I want to pass in my private key for this command if possible.

It is possible: In the Pipeline syntax, you can define environment variables.
Which means you can set GIT_SSH_COMMAND (with Git 2.10+).
That allows you to reference your own private key.

pipeline {
    agent any

    environment {
        GIT_SSH_COMMAND = 'ssh -i /path/to/my/private/key'
    }

    stages {
        stage('Build') {
            steps {
                sh 'printenv'
                sh 'git submodule update --init --recursive'
            }
        }
    }
} 

If any clone involve an ssh url, that ssh clone will use the right private key.


Note that sancelot points out in the comments:

unfortunately this does not work: JENKINS-38860

The error reported above:

FATAL: Command "git config --get submodule.MySubModule.url" 
returned status code 1

Occurs for me whenever you have nested submodules.

Consider a scenario in which repo A contains submodule B, which contains submodule C.

If "Advanced submodule behaviour" with "Recursively update submodules" is not enabled, Jenkins will clone A, checkout/clone B, and fail to initialise/clone C.
This is probably expected behaviour.

If you enable "Recursively update submodules", you get the error:

FATAL: Command "git config --get submodule.C.url"
returned status code 1

Upvotes: 35

rw4680
rw4680

Reputation: 21

This is a minor variation on the previous answers but I believe it to be the best solution.

I swapped the branches parameter to use env.GIT_COMMIT so that it checks out the specific commit that has been triggered via the job. Otherwise it will build the latest commit of the specific branch, in the other examples, when using scm.branches, it will build the tip of the branch instead of the expected commit.

checkout([
    $class: 'GitSCM',
    branches: [[name: "${env.GIT_COMMIT}"]],
    doGenerateSubmoduleConfigurations: false,
    extensions: [[
        $class: 'SubmoduleOption',
        disableSubmodules: false,
        parentCredentials: true,
        recursiveSubmodules: true,
        reference: '',
        trackingSubmodules: false
    ]],
    submoduleCfg: [],
    userRemoteConfigs: scm.userRemoteConfigs
    ])

Upvotes: 2

shuckc
shuckc

Reputation: 2994

If you know the credential name that checkout scm is using, you can also explicitly pass that to a git command to update the submodules:

    stage ('Clone') {
        steps {
            checkout scm
            withCredentials([sshUserPrivateKey(credentialsId: 'bitbucket_ssh', keyFileVariable: 'SSH_KEY')]) {
                sh 'GIT_SSH_COMMAND="ssh -i $SSH_KEY" git submodule update --init'
            }
        }
    }

Upvotes: 3

deepelement
deepelement

Reputation: 2506

checkout([
    $class: 'GitSCM', 
    branches: scm.branches, 
    doGenerateSubmoduleConfigurations: false, 
    extensions: [[
      $class: 'SubmoduleOption', 
      disableSubmodules: false, 
      parentCredentials: true, 
      recursiveSubmodules: true, 
      reference: '', 
      trackingSubmodules: false
    ]], 
    submoduleCfg: [], 
    userRemoteConfigs: scm.userRemoteConfigs
  ])

Upvotes: 32

Pom12
Pom12

Reputation: 7880

The git command as a pipeline step is rather limited as it provides a default implementation of the more complex checkout command. For more advanced configuration, you should use checkout command, for which you can pass a whole lot of parameters, including the desired submodules configuration.

What you want to use is probably something like this :

checkout([$class: 'GitSCM',
          branches: [[name: '*/master']],
          doGenerateSubmoduleConfigurations: false,
          extensions: [[$class: 'SubmoduleOption',
                        disableSubmodules: false,
                        parentCredentials: false,
                        recursiveSubmodules: true,
                        reference: '',
                        trackingSubmodules: false]], 
          submoduleCfg: [], 
          userRemoteConfigs: [[url: 'your-git-server/your-git-repository']]])

From the documentation it is often cumbersome to write these kind of lines, I recommand you use instead Jenkins very good Snippet Generator (YourJenkins > yourProject > PipelineSyntax) to automatically generate the checkout line !

Upvotes: 64

Related Questions