Jenkins Groovy读文件生成复选框参数始终触发fallbackScript问题
Jenkins流水线动态复选框参数读取外部文件触发回退脚本问题
更新
搭建简易Jenkins流水线,需要从外部文件读取内容生成多选构建参数。目标文件内容如下:
@Test1,Accounts @Test2,Services @Test3,Accesses
需求为将文件中每行逗号分隔的第一列内容@Test1、@Test2、@Test3生成为复选框参数选项,构建时仅运行选中的测试用例,当前代码运行未达预期。
当前使用的流水线代码如下:
def code = """tests = getChoices() return tests def getChoices() { def filecontent = readFile "/var/jenkins_home/test.txt" def stringList = [] for (line in filecontent.readLines()) {stringList.add(line.split(",")[0].toString())} List modifiedList = stringList.collect{'"' + it + '"'} return modifiedList }""".stripIndent() properties([ parameters([ [$class : 'CascadeChoiceParameter', choiceType : 'PT_CHECKBOX', description : 'Select a choice', filterLength : 1, filterable : false, name : 'choice1', referencedParameters: 'role', script : [$class : 'GroovyScript', fallbackScript: [ classpath: [], sandbox : true, script : 'return ["ERROR"]' ], script : [ classpath: [], sandbox : true, script : code ] ] ] ]) ]) pipeline { agent { docker { image 'node:latest' } } stages { stage('Tags') { steps { getChoices() } } } } def getChoices() { def filecontent = readFile "/var/jenkins_home/test.txt" def stringList = [] for (line in filecontent.readLines()) { stringList.add(line.split(',')[0].toString()) } List modifiedList = stringList.collect { '"' + it + '"' } echo "$modifiedList" return modifiedList }
已验证多选复选框基础功能正常:将code变量替换为直接返回固定列表的脚本时,可以正常展示预期的复选框选项,替换代码如下:
def code = """ tests = ["Test1", "Test2", "Test3"] return tests""".stripIndent()
当前异常现象:运行编写的流水线时,构建状态显示为成功,但构建参数的复选框区域始终展示fallbackScript返回的ERROR结果,需要定位始终触发回退脚本的根本原因。
根本原因
触发回退脚本的核心问题有3个:
- 执行上下文不匹配:
CascadeChoiceParameter的参数渲染脚本运行在Jenkins主控的Script Security沙箱环境,和流水线运行时的上下文完全隔离。脚本里调用的readFile是Pipeline专属步骤,不是原生Groovy方法,沙箱环境无法识别该方法,脚本执行直接抛出异常,因此触发fallback逻辑返回ERROR。 - 无效的引号包裹:对列表元素手动拼接双引号的操作完全多余,
CascadeChoiceParameter只需要接收普通字符串构成的列表即可,多余的引号会导致后续获取参数值时拿到带冗余引号的错误内容。 - 路径匹配问题:参数脚本读取文件时访问的是Jenkins主控节点的文件系统路径,如果把
test.txt放在流水线运行的docker agent内部,主控节点对应路径下不存在该文件,也会触发脚本执行失败。
修复方案
- 将参数脚本内的文件读取逻辑替换为原生Groovy的文件操作API,不要调用Pipeline专属步骤。
- 删除给选项值手动拼接双引号的逻辑,直接返回拆分后的原始字符串即可。
- 确认
/var/jenkins_home/test.txt存放在Jenkins主控节点的对应路径下,而非agent节点或docker容器内。 - 首次运行修复后的脚本时,需要Jenkins管理员在「管理Jenkins-脚本安全」页面批准对应Groovy方法的执行权限,否则沙箱会拦截方法调用。
修复后参数部分的code变量写法如下:
def code = """ def getChoices() { def choiceList = [] // 原生Groovy读文件,适配主控沙箱环境 new File("/var/jenkins_home/test.txt").eachLine { line -> def content = line?.trim() if (content) { // 跳过空行 choiceList.add(content.split(",")[0].trim()) } } return choiceList } return getChoices() """.stripIndent()
补充说明:流水线stages外层定义的getChoices()方法运行在pipeline执行上下文,其中的readFile步骤可以正常工作,但这个方法和参数渲染脚本内的逻辑完全独立,不会参与参数选项的生成过程。
内容的提问来源于stack exchange,提问作者wsn
相关产品推荐
相关产品推荐

