You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Jenkins属性中使用凭证获取SVN分支与标签列表?

解决方案

核心实现思路

通过Jenkins的withCredentials块安全获取「jenkins-svn」凭证的用户名和密码,替换硬编码内容,同时保留原有的properties参数配置结构,用Groovy脚本调用SVN命令(或内置SVNKit库)生成指定格式的路径列表。

基于Shell命令的可行代码

// 保留原参数配置结构
properties([
    parameters([
        choice(
            name: 'SVN_PATH',
            choices: getSVNPaths(),
            description: '选择要构建的SVN路径'
        )
    ])
])

def getSVNPaths() {
    def svnRepoUrl = '你的SVN仓库根URL' // 替换为实际仓库地址
    def paths = []
    
    // 绑定jenkins-svn凭证到环境变量
    withCredentials([usernamePassword(
        credentialsId: 'jenkins-svn',
        usernameVariable: 'SVN_USER',
        passwordVariable: 'SVN_PASS'
    )]) {
        // 获取SVN根目录下的一级目录
        def rootDirs = sh(
            script: "svn list --username ${SVN_USER} --password ${SVN_PASS} --non-interactive ${svnRepoUrl}",
            returnStdout: true
        ).trim().split('\n')
        
        rootDirs.each { dir ->
            def dirName = dir.replace('/', '')
            if (dirName == 'trunk') {
                paths.add('trunk')
            } else if (dirName in ['branches', 'tags']) {
                // 遍历branches/tags下的子目录,拼接成目标格式
                def subDirs = sh(
                    script: "svn list --username ${SVN_USER} --password ${SVN_PASS} --non-interactive ${svnRepoUrl}/${dirName}",
                    returnStdout: true
                ).trim().split('\n')
                subDirs.each { subDir ->
                    paths.add("${dirName}/${subDir.replace('/', '')}")
                }
            }
        }
    }
    return paths
}

// 后续Pipeline执行逻辑...

关键说明

  • 凭证安全注入:通过usernamePassword类型的凭证绑定,将「jenkins-svn」的用户名和密码分别存入SVN_USER、SVN_PASS环境变量,完全避免硬编码风险。
  • 参数配置保留:properties块直接调用getSVNPaths()方法生成选项列表,原参数结构完全保留。
  • 格式匹配:脚本遍历根目录和子目录后,生成的路径格式完全符合[branches/myBranche1, branches/myBranche2, tags/myTag, trunk]的要求。
  • 无交互执行:svn list命令添加--non-interactive参数,确保Pipeline自动执行,不会触发交互提示。

替代方案(基于SVNKit库)

如果不想依赖系统SVN客户端,可使用Jenkins内置的SVNKit库实现,代码如下:

import org.tmatesoft.svn.core.*
import org.tmatesoft.svn.core.auth.*
import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory
import org.tmatesoft.svn.core.wc.SVNWCUtil

// 保留原参数配置
properties([
    parameters([
        choice(
            name: 'SVN_PATH',
            choices: getSVNPaths(),
            description: '选择要构建的SVN路径'
        )
    ])
])

def getSVNPaths() {
    def svnRepoUrl = '你的SVN仓库根URL'
    def paths = []
    
    withCredentials([usernamePassword(
        credentialsId: 'jenkins-svn',
        usernameVariable: 'SVN_USER',
        passwordVariable: 'SVN_PASS'
    )]) {
        // 初始化SVNKit
        DAVRepositoryFactory.setup()
        def repository = DAVRepositoryFactory.create(SVNURL.parseURIEncoded(svnRepoUrl))
        
        // 设置凭证认证
        def authManager = SVNWCUtil.createDefaultAuthenticationManager(SVN_USER, SVN_PASS.toCharArray())
        repository.setAuthenticationManager(authManager)
        
        // 获取根目录条目
        def rootEntries = repository.getDir('', -1, null, (Collection)null)
        rootEntries.each { entry ->
            def entryName = entry.getName()
            if (entryName == 'trunk') {
                paths.add(entryName)
            } else if (entryName in ['branches', 'tags']) {
                // 获取子目录条目并拼接路径
                def subEntries = repository.getDir(entryName, -1, null, (Collection)null)
                subEntries.each { subEntry ->
                    paths.add("${entryName}/${subEntry.getName()}")
                }
            }
        }
    }
    return paths
}

内容的提问来源于stack exchange,提问作者Pantelisy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 12:24:52