首页 文章

使用指定回购中的Git分支动态填充Jenkins选择参数

提问于
浏览
51

我有一个参数化的Jenkins作业,需要在特定的Git仓库中输入特定的Git分支 . 目前,此参数是字符串参数 .

有没有办法让这个参数成为一个选择参数,并用Git分支动态填充下拉列表?我不希望有人通过在每次创建新分支时手动配置下拉列表来维护此选项参数 .

10 回答

  • 0

    Extended Choice Parameter plugin将允许您从文件中读取选项 .

    当然,现在您还有另一个问题:如何确保文件是最新的(可以使用提交后挂钩完成)并传播给所有用户(可以通过将其放在共享上来完成)文件服务器) . 但可能有更好的解决方案 .

  • 17

    我尝试了这个链接中提到的几个答案,但无法弄清楚如何告诉Jenkins有关用户选择的分支 . 正如我在上面的线程中的前一条评论中所提到的,我将分支选择器字段留空了 .

    但是,在进一步的调查中,我发现了另一种做同样事情的方法 - https://wiki.jenkins-ci.org/display/JENKINS/Git+Parameter+Plugin我发现这种方法更简单,并且配置的东西更少!

    这是我配置的 -

    • 安装了git参数插件

    • 检查了'This build is parameterized'并添加了'Git parameter'

    • 添加了以下值:
      Git Parameter plugin config in the job

    • 然后在作业的git SCM部分,我添加了'Name'部分中提到的相同值,就像它是一个环境变量一样 . (如果你仔细阅读了这个git参数插件的帮助,你会意识到这一点)
      Branch Selector

    在此之后我刚刚运行构建,选择了我的分支(Jenkins在构建之前检查了这个分支)并且它成功完成了构建,并选择了我指定的分支 .

  • 70

    我能够使用Jenkins Dynamic Parameter Plug-in实现这个结果 . 我使用了动态选择参数选项,对于选择脚本,我使用了以下内容:

    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()
    
  • 10

    使用"Git Parameter Plug-in"非常简单 .

    添加名称,如“SELECT_BRANCH”##确保此变量,因为稍后将使用此变量 . 然后参数类型:分支

    然后联系SCM:选择:Git和分支说明符:$

    要验证,请在jenkins中执行以下shell:

    echo $

    env.enter这里的图像描述

    enter image description here

  • 2

    扩展@ malenkiy_scot的答案 . 我创建了一个新的jenkins作业来构建Extended Choice Plugin使用的文件 .

    您可以执行以下操作(我在jenkins中执行shell步骤,但您可以在脚本中执行此操作):

    git ls-remote git@github.com:my/repo.git |grep refs/heads/* >tmp.txt
    sed -e 's/.*refs\/heads\///' tmp.txt > tmp2.txt
    tr '\n' ',' < tmp2.txt > tmp3.txt
    sed '1i\branches=' tmp3.txt > tmp4.txt
    tr -d '\n'  < tmp4.txt > branches.txt
    

    然后我使用Artifact deployer插件将该文件推送到一个共享位置,该位置位于web url中,然后使用Extended Choice插件中的“http://localhost/branches.txt”作为url . 奇迹般有效 .

  • 2

    您可以使用之前由malenkiy_scot提到的扩展选项参数插件和一个简单的PHP脚本完成相同的操作(假设您有一个服务器来部署可以从Jenkins机器命中的PHP脚本)

    <?php
    chdir('/path/to/repo');
    exec('git branch -r', $output);
    print('branches='.str_replace('  origin/','',implode(',', $output)));
    ?>
    

    要么

    <?php
    exec('git ls-remote -h http://user:pass@repo.git', $output);
    print('branches='.preg_replace('/[a-z0-9]*\trefs\/heads\//','',implode(',', $output)));
    ?>
    

    使用第一个选项,您需要克隆repo . 第二个你没有,但在这两种情况下你需要在托管你的php脚本的服务器上安装git . Whit任何这个选项都可以完全动态,你不需要构建一个列表文件 . 只需将URL放在扩展选项参数“属性文件”字段中的脚本中即可 .

  • 2

    是的,我写了一个简单的groovy脚本来完成这个技巧你应该为你的工作添加一个'动态选择参数',并根据你的需要定制以下groovy脚本:

    #!/usr/bin/groovy
    
    def gitURL = "git repo url"
    def command = "git ls-remote --heads --tags ${gitURL}"
    
    def proc = command.execute()
    proc.waitFor()              
    
    if ( proc.exitValue() != 0 ) {
       println "Error, ${proc.err.text}"
       System.exit(-1)
    }
    
    def text = proc.in.text
    # put your version string match
    def match = /<REGEX>/
    def tags = []
    
    text.eachMatch(match) { tags.push(it[1]) }
    tags.unique()
    tags.sort( { a, b ->
             def a1 = a.tokenize('._-')
             def b1 = b.tokenize('._-')
             try {
                for (i in 1..<[a1.size(), b1.size()].min()) { 
                     if (a1[i].toInteger() != b1[i].toInteger()) return a1[i].toInteger() <=> b1[i].toInteger()
                }
                return 1
             } catch (e) {
                return -1;
             }
    } )
    tags.reverse()
    

    我的情况下,版本字符串采用以下格式X.X.X.X,并且可以使用X.X.X-username等格式的用户分支...所以我必须编写自己的排序函数 . 这是我的第一个groovy脚本,所以如果有更好的方法做我想知道的事情 .

  • 14

    以下groovy脚本很有用, if your job does not use "Source Code Management" directly (同样"Git Parameter Plugin"),但仍然可以访问本地(克隆)git存储库:

    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()
    

    请在此处查看完整说明:https://stackoverflow.com/a/37810768/658497

  • 0

    我们可以使用 text 消除不必要的文件读/写 . 我的完整解决方案如下:

    proc1 = ['/bin/bash', '-c', 
      "/usr/bin/git ls-remote --heads ssh://repo_url.git"].execute()
    proc2 = ['/bin/bash', '-c', 
      "/usr/bin/awk ' { gsub(/refs\\/heads\\//, \"\"); print \$2 }' "].execute()
    all = proc1 | proc2
    
    choices = all.text
    return choices.split().toList();
    
  • 0

    对我来说,我使用输入阶段参数:

    • 我通过检查git项目来启动我的管道 .

    • 我使用awk commade生成一个包含所有分支列表的barnch.txt文件

    • 在阶段设置中,我读取了文件并使用它来生成输入选择参数

    当用户启动管道时,这个管道将等待他在列表选择上进行选择 .

    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()
            }
        }
    }
    

    }

    然后用户将与构建进行交互:

    enter image description here

    enter image description here

相关问题