使用指定存储库中的 Git 分支动态填充 Jenkins 选择参数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10433105/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 13:36:41  来源:igfitidea点击:

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

gitparametersbranchjenkinschoice

提问by mkez00

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.

我有一个参数化的 Jenkins 作业,它需要在特定的 Git 存储库中输入特定的 Git 分支。目前这个参数是一个字符串参数。

Is there any way to make this parameter a choice parameter and dynamically fill the drop down list with the Git branches? I don't want to require someone to maintain this choice parameter by manually configuring the drop down every time a new branch is created.

有没有办法让这个参数成为选择参数并用 Git 分支动态填充下拉列表?我不想要求有人在每次创建新分支时手动配置下拉菜单来维护这个选择参数。

采纳答案by malenkiy_scot

Extended Choice Parameter pluginwill allow you to read the choices from a file.

扩展选择参数插件将允许您从文件中读取选择。

Of course, now you have another problem: how to make sure the file is up-to-date (that can be done with a post-commit hook) and propagated to all the users (that can be done by placing it on a shared file server). But there may be better solutions.

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

回答by Ravindra Mijar

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.

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

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

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

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

  1. 安装了git参数插件
  2. 检查“此构建已参数化”并添加了“Git 参数”
  3. 添加了以下值: 作业中的 Git 参数插件配置

  4. 然后在作业的 git SCM 部分中,我添加了“名称”部分中提到的相同值,就好像它是一个环境变量一样。(如果你仔细阅读这个 git 参数插件的帮助,你就会意识到这一点) 分支选择器

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.

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

回答by veritius

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:

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

proc1 = ['/bin/bash', '-c', "/usr/bin/git ls-remote -h ssh://[email protected]/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()

回答by Smit Jain

Its quite simple using the "Git Parameter Plug-in".

使用“Git Parameter Plug-in”非常简单。

Add Name like "SELECT_BRANCH" ## Make sure for this variable as this would be used later. Then Parameter Type : Branch

添加 Name like "SELECT_BRANCH" ## 确保这个变量,因为这将在以后使用。然后参数类型:分支

Then reach out to SCM : Select : Git and branch specifier : ${SELECT_BRANCH}

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

To verify, execute below in shell in jenkins:

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

echo ${SELECT_BRANCH}

回声 ${SELECT_BRANCH}

env.enter image description here

env.enter 图片描述在这里

enter image description here

enter image description here

回答by idriss Eliguene

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
  1. 我通过检查 git 项目来开始我的管道。
  2. 我使用 awk 命令生成一个包含所有分支列表的 barnch.txt 文件
  3. 在 stage setps 中,我读取文件并使用它来生成输入选择参数

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://[email protected]:/usr/company/repositories/repo.git'
                sh 'git branch -r | awk \'{print }\' 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://[email protected]/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

在此处输入图片说明

回答by u5698324

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

我在这里面临类似的问题。我们的用户正在将他们的工作从自由式迁移到流水线。他们不希望 Jenkinsfile 存储在他们的存储库中(历史原因)并且仍然想使用“Git Parameter”插件

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

所以我们必须使用“管道脚本”并开发一个不同的插件,它的工作原理类似于“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

这个新插件没有与项目中的 SCM 设置集成。该插件位于https://plugins.jenkins.io/list-git-branches-parameter

Hope it helps you as well

希望对你也有帮助

回答by idriss Eliguene

I have a new response for this case: the easy way to solve this is having you jenkinsFile from source code.

我对这种情况有一个新的回应:解决这个问题的简单方法是从源代码中获取 jenkinsFile。

Then you chose: this job have a git parameter

然后你选择了:这个作业有一个 git 参数

enter image description here

enter image description here

And and the Pipeline setup, unchecked the "Lightweight checkout" checkbox, this will perform a really git checkout on job workspace.

和管道设置,取消选中“轻量级结账”复选框,这将在作业工作区执行真正的 git 结账。

enter image description here

enter image description here

After, the parameter will be autopopulate by your git branch

之后,该参数将由您的 git 分支自动填充

回答by Ben

expanding on @malenkiy_scot's answer. I created a new jenkins job to build up the file that is used by Extended Choice Plugin.

扩展@malenkiy_scot 的答案。我创建了一个新的 jenkins 作业来构建扩展选择插件使用的文件。

you can do the following (I did it as execute shell steps in jenkins, but you could do it in a script):

您可以执行以下操作(我在 jenkins 中执行 shell 步骤是这样做的,但您可以在脚本中执行):

git ls-remote [email protected]: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

I then use the Artifact deployer plugin to push that file to a shared location, which is in a web url, then just use 'http://localhost/branches.txt' in the Extended Choice plugin as the url. works like a charm.

然后,我使用 Artifact 部署器插件将该文件推送到共享位置,该位置位于 Web url 中,然后仅使用扩展选择插件中的“http://localhost/branches.txt”作为 url。奇迹般有效。

回答by Ulises

You can accomplish the same using the extended choice parameter plugin before mentioned by malenkiy_scot and a simple php script as follows(assuming you have somewhere a server to deploy php scripts that you can hit from the Jenkins machine)

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

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

or

或者

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

With the first option you would need to clone the repo. With the second one you don't, but in both cases you need git installed in the server hosting your php script. Whit any of this options it gets fully dynamic, you don't need to build a list file. Simply put the URL to your script in the extended choice parameter "property file" field.

使用第一个选项,您需要克隆存储库。对于第二个,您不需要,但在这两种情况下,您都需要在托管 php 脚本的服务器中安装 git。由于这些选项中的任何一个都变得完全动态,因此您无需构建列表文件。只需将 URL 放到您的脚本的扩展选择参数“属性文件”字段中。

回答by sagi

Yes, I wrote a little groovy script which does the trick You should add a 'Dynamic Choice Parameter' to your job and customize the following groovy script to your needs :

是的,我写了一个小 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()

I my case the version string was in the following format X.X.X.X and could have user branches in the format X.X.X-username ,etc... So I had to write my own sort function. This was my first groovy script so if there are better ways of doing thing I would like to know.

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