Dynamically Fill Jenkins Choice Parameter With Git Branches In a Specified Repo

后端 未结 13 912
离开以前
离开以前 2020-11-29 16:41

I have a parameterized Jenkins job which requires the input of a specific Git branch in a specific Git repo. Currently this parameter is a string parameter.

Is ther

相关标签:
13条回答
  • 2020-11-29 17:37

    I'm aware to the fact that in the original question Jenkins pipeline was not mentioned, but if it is still applicable (using it), I find this solution easy to maintain and convenient.

    This approach describe the settings required to compose a Jenkins pipeline that "polls" (list) dynamically all branches of a particular repository, which then lets the user run the pipeline with some specific branch when running a build of this job.

    The assumptions here are:

    • The Jenkins server is 2.204.2 (hosted on Ubuntu 18.04)
    • The repository is hosted in a BitBucket.

    First thing to do is to provide Jenkins credentials to connect (and "fetch") to the private repository in BitBucket. This can be done by creating an SSH key pair to "link" between the Jenkins (!!) user on the machine that hosts the Jenkins server and the (private) BitBucket repository.

    1. First thing is to create an SSH key to the Jenkins user (which is the user that runs the Jenkins server - it is most likely created by default upon the installation):

      guya@ubuntu_jenkins:~$ sudo su jenkins 
      [sudo] password for guya:
      jenkins@ubuntu_jenkins:/home/guya$ ssh-keygen
      

      The output should look similar to the following:

    Generating public/private rsa key pair. Enter file in which to save the key
    (/var/lib/jenkins/.ssh/id_rsa): Created directory '/var/lib/jenkins/.ssh'. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /var/lib/jenkins/.ssh/id_rsa. Your public key has been saved in /var/lib/jenkins/.ssh/id_rsa.pub. The key fingerprint is: SHA256:q6PfEthg+74QFwO+esLbOtKbwLG1dhtMLfxIVSN8fQY jenkins@ubuntu_jenkins The key's randomart image is: +---[RSA 2048]----+ | . .. o.E. | | . . .o... o | | . o.. o | | +.oo | | . ooX..S | |..+.Bo* . | |.++oo* o. | |..+*..*o | | .=+o==+. | +----[SHA256]-----+ jenkins@ubuntu_jenkins:/home/guya$

    1. Now the content of this SSH key needs to be set in the BitBucket repository as follows:
    • Create (add) an SSH key in the BitBucket repository by going to: Settings --> Access keys --> Add key.
    • Give the key Read permissions and copy the content of the PUBLIC key to the "body" of the key. The content of the key can be displayed by running: cat /var/lib/jenkins/.ssh/id_rsa.pub
    1. After that the SSH key was set in the BitBucket repository, we need to "tell" Jenkins to actually USE it when it tries to fetch (read in this case) the content of the repository. NOTE that by letting Jenkins know, actually means let user jenkins this "privilege".

    This can be done by adding a new  SSH User name with private key to the Jenkins --> Credentials --> System --> Global Credentials --> Add credentials.

    • In the ID section put any descriptive name to the key.
    • In the Username section put the user name of the Jenkins server which is jenkins.
    • Tick the Private key section and paste the content of the PRIVATE key that was generated earlier by copy-paste the content of: ~/.ssh/id_rsa. This is the private key which start with the string:-----BEGIN RSA PRIVATE KEY----- and ends with the string: -----END RSA PRIVATE KEY-----. Note that this entire "block" should be copied-paste into the above section.
    1. Install the Git Parameter plugin that can be found in its official page here

    2. The very minimum pipeline that is required to list (dynamically) all the branches of a given repository is as follows:

      pipeline 
      { 
          agent any parameters
          { 
              gitParameter branchFilter: 'origin/(.*)', defaultValue: 'master', name: 'BRANCH', type: 'PT_BRANCH' 
          }
          stages 
          { 
             stage("list all branches") 
             { 
                 steps 
                 { 
                      git branch: "${params.BRANCH}", credentialsId: "SSH_user_name_with_private_key", url: "ssh://git@myCompanyBitBucketSite.com:port/myRepository.git" 
                 } 
            } 
         } 
      }
      

    NOTES:

    • The defaultValue is set to master so that if no branches exist - it will be displayed in the "drop list" of the pipeline.
    • The credentialsId has the name of the credentials configured earlier.
    • In this case I used the SSH URL of the repository in the url parameter.
    • This answer assumes (and configured) that the git server is BitBucket. I assume that all the "administrative" settings done in the initial steps, have their equivalent settings in GitHub.
    0 讨论(0)
  • 2020-11-29 17:38

    I was able to achieve this result using the Jenkins Dynamic Parameter Plug-in. I used the Dynamic Choice Parameter option and, for the choices script, I used the following:

    proc1 = ['/bin/bash', '-c', "/usr/bin/git ls-remote -h ssh://user@server.com/path/to/repo.git"].execute()
    proc2 = ['/bin/bash', '-c', "awk '{print \$2}'"].execute()
    proc3 = ['/bin/bash', '-c', "sed s%^refs/heads%origin%"].execute()
    
    all = proc1 | proc2 | proc3
    String result = all.text
    
    String filename = "/tmp/branches.txt"
    boolean success = new File(filename).write(result) 
    
    def multiline = "cat /tmp/branches.txt".execute().text
    def list = multiline.readLines()
    
    0 讨论(0)
  • 2020-11-29 17:38

    For Me I use the input stage param:

    1. I start my pipeline by checking out the git project.
    2. I use a awk commade to generate a barnch.txt file with list of all branches
    3. In stage setps, i read the file and use it to generate a input choice params

    When a user launch a pipeline, this one will be waiting him to choose on the list choice.

    pipeline{
    agent any
    
    stages{
    
        stage('checkout scm') {
            steps {
                script{
                    git credentialsId: '8bd8-419d-8af0-30960441fcd7', url: 'ssh://jenkins@git.company.com:/usr/company/repositories/repo.git'
                    sh 'git branch -r | awk \'{print $1}\' ORS=\'\\n\' >>branch.txt'
                }
    
            }
        }
         stage('get build Params User Input') {
            steps{
                script{
    
                    liste = readFile 'branch.txt'
                    echo "please click on the link here to chose the branch to build"
                    env.BRANCH_SCOPE = input message: 'Please choose the branch to build ', ok: 'Validate!',
                            parameters: [choice(name: 'BRANCH_NAME', choices: "${liste}", description: 'Branch to build?')]
    
    
                }
            }
        } 
        stage("checkout the branch"){
            steps{
                echo "${env.BRANCH_SCOPE}"
                git  credentialsId: 'ea346a50-8bd8-419d-8af0-30960441fcd7', url: 'ssh://jenkins@git.company.com/usr/company/repositories/repo.git'
                sh "git checkout -b build ${env.BRANCH_NAME}"
            }
        }
        stage(" exec maven build"){
            steps{
                withMaven(maven: 'M3', mavenSettingsConfig: 'mvn-setting-xml') {
                   sh "mvn clean install "
                }
            }
        }
        stage("clean workwpace"){
            steps{
                cleanWs()
            }
        }
    }
    

    }

    And then user will interact withim the build :

    enter image description here

    enter image description here

    0 讨论(0)
  • 2020-11-29 17:39

    The following groovy script would be useful, if your job does not use "Source Code Management" directly (likewise "Git Parameter Plugin"), but still have access to a local (cloned) git repository:

    import jenkins.model.Jenkins
    
    def envVars = Jenkins.instance.getNodeProperties()[0].getEnvVars() 
    def GIT_PROJECT_PATH = envVars.get('GIT_PROJECT_PATH') 
    def gettags = "git ls-remote -t --heads origin".execute(null, new File(GIT_PROJECT_PATH))
    
    return gettags.text.readLines()
             .collect { it.split()[1].replaceAll('\\^\\{\\}', '').replaceAll('refs/\\w+/', '')  }
             .unique()
    

    See full explanation here: https://stackoverflow.com/a/37810768/658497

    0 讨论(0)
  • 2020-11-29 17:40

    I tried a couple of answers mentioned in this link, but couldn't figure out how to tell Jenkins about the user-selected branch. As mentioned in my previous comment in above thread, I had left the branch selector field empty.

    But, during further investigations, I found another way to do the same thing - https://wiki.jenkins-ci.org/display/JENKINS/Git+Parameter+Plugin I found this method was a lot simpler, and had less things to configure!

    Here's what I configured -

    1. Installed the git parameter plugin
    2. Checked the 'This build is parameterized' and added a 'Git parameter'
    3. Added the following values: Git Parameter plugin config in the job

    4. Then in the git SCM section of the job I added the same value mentioned in the 'Name' section, as if it were an environment variable. (If you read the help for this git parameter plugin carefully, you will realize this) Branch Selector

    After this I just ran the build, chose my branch(Jenkins checks out this branch before building) and it completed the build successfully, AND by choosing the branch that I had specified.

    0 讨论(0)
  • 2020-11-29 17:41

    I am facing a similar problem here. Our users are migrating their jobs from freestyle to pipeline. They do not want Jenkinsfile stored in their repos(historical reason) and still want to use "Git Parameter" plugin

    So we have to use use "Pipeline script" and develop a different plugin which works like "Git Parameter".

    This new plugin does not integrate with SCM setting in the project. The plugin is at https://plugins.jenkins.io/list-git-branches-parameter

    Hope it helps you as well

    0 讨论(0)
提交回复
热议问题