如何从 Groovy 代码解析 Jenkinsfile

How to parse Jenkinsfile from Groovy code

我有一个带有一些属性的 Jenkinsfile,例如

trace = false

userNotifications = [
    build_master :                 [name : 'name',
                                    email : 'email',
                                    slackid: 'slack id',
                                    slackchannel: 'slack channel']
]
env.aProperty = "aValue"
node('COMPILE')
{
...
}

我想在 groovy 代码中解析上述 Jenkinsfile,以便访问某些 属性 值。

当我这样使用GroovyShell时

        Binding binding = new Binding()
        GroovyShell shell = new GroovyShell(binding)
        Object groovyDsl = shell.evaluate(clean)

我收到这个错误

groovy.lang.MissingMethodException: No signature of method: Script1.node() is applicable for argument types: (String, Script1$_run_closure1) values: [COMPILE, Script1$_run_closure1@7d804e7]

我也许可以通过某些 Groovy 元编程来解决特定错误,但是,我不确定这是否是正确的方向。我的问题是在 Groovy 代码中解析 Jenkinsfile 的最佳方法是什么?这是一天结束时的 Groovy DSL,我希望它会更直接。

DSL 是特定于上下文的,不能运行脱离上下文。

你可以试试

  • 管理 Jenkins 下的脚本控制台。

以下是我最终完成我想要的事情的方式:

import org.codehaus.groovy.control.CompilerConfiguration

class JenkinsfileParser {
    static void main(String[] args) {
        LinkedHashMap vars = JenkinsfileParser.parse('Jenkinsfile' as File)
        println vars.toString()
    }

    static LinkedHashMap parse(File jenkinsfile) {
        CompilerConfiguration config = new CompilerConfiguration()
        config.scriptBaseClass = JenkinsfileBaseClass.class.name
        Binding binding = new Binding()
        GroovyShell shell = new GroovyShell(this.class.classLoader, binding, config)
        String clean = jenkinsfile.text.replace('import hudson.model.*', '')
                .replace('import hudson.EnvVars', '')
        Script script = shell.parse(clean)
        script.run()
        return binding.variables
    }

    static abstract class JenkinsfileBaseClass extends Script {
        LinkedHashMap<String, Closure> nodeClosures = new LinkedHashMap<>()
        LinkedHashMap env = new LinkedHashMap()
        CurrentBuild currentBuild = new CurrentBuild()
        LinkedHashMap parallelClosures = new LinkedHashMap<>()

        void node(String name, Closure closure) {
            nodeClosures.put(name, closure)
        }

        void parallel(LinkedHashMap closures) {
            parallelClosures.putAll(closures)
        }

        class CurrentBuild {
            List<String> expectedResults = new ArrayList<>()

            boolean resultIsBetterOrEqualTo(String expected) {
                expectedResults << expected
                return true
            }
        }
    }
}

JenkinsfileBaseClass 特定于我的 Jenkinsfile,需要针对不同的 Jenkinsfile 进行调整。

相关文档可以在这里找到:https://groovy-lang.org/integrating.html

我尝试使用 Maven 存储库 http://repo.jenkins-ci.org/public/ 中的 implementation group: 'org.jenkins-ci.main', name: 'jenkins-core', version: '2.9' 包,但是,其中似乎没有任何对我的情况有用的东西。

如果有更好或更优雅的方法,请告诉我。