Git分支在Jenkins中用groovy脚本选择

时间:2014-08-26 15:00:25

标签: git groovy jenkins

我想在詹金斯做一个Parameterized build。通过这种方式,用户可以从级联菜单中选择他/她想要部署的git分支。

有两种可能的方式:

  1. 在文件中编写分支名称并配置Jenkins以读取此文件(project configuration > extend choice parameter and selecting Property file)。

    问题:您必须将本地存储库作为远程存储库的镜像,并使此本地存储库与远程存储库保持同步。换句话说,您必须更新包含更新的可用分支名称的文件。这需要cron的预定工作,我不允许使用这种方法。

  2. 使用Groovy脚本(project configuration > extend choice parameter and selecting "Groovy script")。然后,您需要一个groovy脚本来检索分支名称,如下所示:branches=master,feature/Feature-1,feature/Feature-2,hotfix/Hotfix-1,release/Release-1

  3. 我在here找到了一个时髦的脚本,但它不起作用。我在我的机器上安装了groovy。

    任何人都可以帮助我吗?为了简化故事:我需要一个groovy脚本,它返回远程存储库的可用分支名称。

7 个答案:

答案 0 :(得分:12)

下面的脚本应该会有所帮助。它基于linked question的脚本。它使用简单的正则表达式过滤git命令输出,并为指定的git存储库创建分支名称列表。在grails-core github repo上测试:

def gitURL = "https://github.com/grails/grails-core.git"
def command = "git ls-remote -h $gitURL"

def proc = command.execute()
proc.waitFor()              

if ( proc.exitValue() != 0 ) {
   println "Error, ${proc.err.text}"
   System.exit(-1)
}

def branches = proc.in.text.readLines().collect { 
    it.replaceAll(/[a-z0-9]*\trefs\/heads\//, '') 
}

println branches

答案 1 :(得分:3)

你不需要一个Groovy脚本。 Git Parameter Plugin允许您添加git分支作为参数。

答案 2 :(得分:2)

您可以使用Extensible Choice Parameter plugin检索克隆存储库的Git分支。为此,请向Master-Node属性添加.git目录路径的环境变量,例如:

enter image description here

然后使用以下groovy脚本添加Extensible Choice参数(并选中“使用预定义变量”):

def envVars = jenkins.getNodeProperties()[0].getEnvVars() 
def NODE_PROJECT_PATH = envVars.get('NODE_PROJECT_PATH') 
def gettags = "git ls-remote -t --heads origin".execute(null, new File(NODE_PROJECT_PATH))

return gettags.text.readLines()
         .collect { it.split()[1].replaceAll('\\^\\{\\}', '').replaceAll('refs/\\w+/', '')  }
         .unique()
         .findAll { !it.startsWith('Branch_') }

那应该列出你的分支(我从列表中筛选出所有“Branch_ *”):

enter image description here

备注: 如果在验证脚本时没有看到任何内容(使用“立即运行脚本”按钮),则可能是由于需要用户/密码提示 - 所以最初在.git目录中运行“git ls-remote -t​​ --heads origin”。 要在Windows上保存凭据,请尝试运行“git config --global credential.helper wincred”。

答案 3 :(得分:2)

尝试使用

使用以下步骤:

  1. 为作业添加可扩展的选择参数

    enter image description here

  2. 在选择参数字段

    中选择 System Groovy Choice参数

    enter image description here

  3. 将以下脚本放在 Groovy脚本文本框中,并替换占位符“<>”具有所需的值。

    import groovy.json.JsonSlurper;
    try{
       List<String>params = new ArrayList<String>()
       URL apiUrl = "https://api.github.com/users/<repo-owner>/repos?access_token=<github-access-token>".toURL()
       List branches = new JsonSlurper().parse(apiUrl.newReader())
       for (branch in branches ) { 
         params.add(branch.name) 
       }
       return params
    }
    catch(IOException ex){
       print ex
    }
    
  4. 为作业添加有效选择反应参数

    enter image description here

  5. 参考参数置于存储库,并在Groovy脚本文本框中添加以下脚本

    import groovy.json.JsonSlurper;
    try{
       List<String>params = new ArrayList<String>()
       URL apiUrl = "https://api.github.com/repos/<repo-owner>/$repository/branches?access_token=<github-access-token>".toURL()
       List json = new JsonSlurper().parse(apiUrl.newReader())
       for (repo in json ) { 
       params.add(repo.name) 
      }
    return params
    }
    catch(IOException ex){
       print ex
    }
    

    enter image description here

    注意:

    • $repository从存储库参数中获取动态值。
    • 忽略公共存储库。
  6. 现在尝试使用参数

    构建作业

    enter image description here enter image description here

  7. checkout github api docs获取更多信息。希望这对你有帮助.. !! ; - )

答案 4 :(得分:0)

这是我提出的唯一一种技术,它不需要你从工作区中挖出git repo信息。这使用Groovy代码检查Git URI的作业参数,然后发送到git以完成剩余的工作。

应该可以使用JGit以本机Groovy方式访问存储库,但我无法弄明白。

import jenkins.*
import jenkins.model.*
import hudson.*
import hudson.model.*
import org.eclipse.jgit.transport.RemoteConfig;
import org.eclipse.jgit.transport.URIish;

def build = Thread.currentThread().toString()
def regexp= ".+?/job/([^/]+)/.*"
def match = build  =~ regexp
def jobName = match[0][1]
def job = Jenkins.instance.getJob(jobName)
def workspace = job.lastBuild.workspace

for(project in Hudson.instance.items) {
  scm = job.scm;
  if (scm instanceof hudson.plugins.git.GitSCM) {
    for (RemoteConfig cfg : scm.getRepositories()) {
      for (URIish uri : cfg.getURIs()) {
        gitUri = uri
      }
    }
  }
}

def branchlist = ["/bin/bash", "-c", "git ls-remote --heads ${gitUri}"].execute() | ["/bin/bash", "-c", "cut -f2"].execute()
branchlist.waitFor()

return branchlist.in.text.readLines()

扩展选择参数上将 Groovy脚本设置为源代码,如下所示:

Extended choice parameter

然后,您将能够从分支列表中选择构建参数:

Branch list

答案 5 :(得分:0)

我一直在关注此https://stackoverflow.com/a/47880463/11951486,并且运行正常。但是问题是,现在github将禁用url中使用access_token,更多详细信息可以找到here

因此,我将常规脚本更改为使用带有用户名和令牌或密码的curl

请在下面找到用于回购的代码。

import groovy.json.JsonSlurper;

try{
def user = "<username>"
def tokenId = "<tokenid>"
def url = "https://api.github.com/user/repos?per_page=200"
def command = "curl -u $user:$tokenId $url"
   List<String>params = new ArrayList<String>()
   apiUrl = command.execute().text
   List json = new JsonSlurper().parseText(apiUrl)
   for (repo in json ) { 
    params.add(repo.name)
  }
return params
}
catch(IOException ex){
   print ex
}

请在下面找到分支的代码

import groovy.json.JsonSlurper;


try{
def user = "<username>"
def tokenId = "<tokenID>"
def url = "https://api.github.com/repos/<org_name>/${REPO}/branches?per_page=400"
def command = "curl -u $user:$tokenId $url"
   List<String>params = new ArrayList<String>()
   apiUrl = command.execute().text
   List json = new JsonSlurper().parseText(apiUrl)
   for (branch in json ) { 
    params.add(branch.name) 
  }
params.add(0, 'master:selected')// this is for default select master branch
return params
}
catch(IOException ex){
   print ex
}

$ {REPO} =这是用于列出存储库的参数名称,因此,根据您选择的存储库,以上代码将列出分支。

答案 6 :(得分:0)

此方法描述了组成Jenkins管道所需的设置,该管道动态“轮询”(列出)特定存储库的所有分支,然后让用户在运行此作业的构建时使用某个特定分支来运行管道。 / p>

这里的假设是:

  • Jenkins服务器为 2.204.2 (托管在 Ubuntu 18.04 上)
  • 该存储库托管在 BitBucket 中。

要做的第一件事是提供Jenkins凭据以连接(并“获取”)到BitBucket中的私有存储库。这可以通过创建SSH密钥对来实现,以在托管Jenkins服务器的计算机上的Jenkins(!!)用户与(专用)BitBucket存储库之间“链接”。

  1. 第一件事是为Jenkins用户(运行Jenkins服务器的用户-很有可能在安装时默认创建)创建SSH密钥:

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

    输出应类似于以下内容:

生成公用/专用rsa密钥对。输入要保存密钥的文件
(/var/lib/jenkins/.ssh/id_rsa):创建目录“ /var/lib/jenkins/.ssh”。输入密码(无密码时为空):再次输入相同的密码:您的标识已保存在/var/lib/jenkins/.ssh/id_rsa中。您的公钥已保存在/var/lib/jenkins/.ssh/id_rsa.pub中。密钥指纹为:SHA256:q6PfEthg + 74QFwO + esLbOtKbwLG1dhtMLfxIVSN8fQY jenkins @ ubuntu_jenkins密钥的randomart图像为: + --- [RSA 2048] ---- + | 。 .. o.E. | | 。 。 .o ... o | | 。 o .. o | | + .oo | | 。 ooX..S | | .. +。Bo *。 | |。++ oo * o。 | | .. + * .. * o | | 。= + o == +。 | + ---- [SHA256] ----- + jenkins @ ubuntu_jenkins:/ home / guya $

  1. 现在,需要在BitBucket存储库中按以下方式设置此SSH密钥的内容:
  • 转到Settings --> Access keys --> Add key,在BitBucket存储库中创建(添加)SSH密钥。
  • 提供密钥读取权限,并将PUBLIC密钥的内容复制到密钥的“主体”。可以通过运行以下命令显示密钥的内容:cat /var/lib/jenkins/.ssh/id_rsa.pub
  1. 在BitBucket存储库中设置了SSH密钥后,当它试图获取(在这种情况下为该存储库)内容时,我们需要“告诉” Jenkins实际使用它。注意,通过让詹金斯知道,实际上意味着让用户jenkins拥有此“特权”。

这可以通过向Jenkins --> Credentials --> System --> Global Credentials --> Add credentials添加带有私钥的新SSH用户名来完成。

  • 在“ ID”部分,将任何描述性名称添加到密钥中。
  • 在“用户名”部分中,输入Jenkins服务器的用户名jenkins
  • 勾选“私钥”部分,然后粘贴通过复制粘贴以下内容生成的“私钥”的内容:~/.ssh/id_rsa。这是私钥,其起始于字符串:-----BEGIN RSA PRIVATE KEY-----,结束于字符串:-----END RSA PRIVATE KEY-----。请注意,应将整个“块”复制粘贴到上面的部分。
  1. 安装可在其official page here

    中找到的Git Parameter插件
  2. (动态地)列出给定存储库的所有分支所需的最小管道如下:

    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" 
               } 
          } 
       } 
    }
    

注意:

  • defaultValue设置为master,因此,如果不存在分支,它将显示在管道的“删除列表”中。
  • credentialsId具有先前配置的凭据的名称。
  • 在这种情况下,我在url参数中使用了存储库的SSH URL。
  • 此答案假定(并配置)git服务器为BitBucket。我假设在初始步骤中完成的所有“管理”设置都在GitHub中具有相同的设置。