如何在Jenkins管道中注入阶段或步骤

如何在Jenkins管道中注入阶段或步骤,jenkins,jenkins-pipeline,Jenkins,Jenkins Pipeline,这个python eval的输出看起来可能是jenkins管道中的阶段 $ python3 -c 'print("\n".join(["stage({val}) {{ do something with {val} }}".format(val=i) for i in range(3)]))' stage(0) { do something with 0 } stage(1) { do something with 1 } stage(2) { do something with 2 } j

这个python eval的输出看起来可能是jenkins管道中的阶段

 $ python3 -c 'print("\n".join(["stage({val}) {{ do something with {val} }}".format(val=i) for i in range(3)]))'
stage(0) { do something with 0 }
stage(1) { do something with 1 }
stage(2) { do something with 2 }
jenkins是否可以使用类似这样的输出在管道中创建步骤或阶段,以便运行的python脚本能够更新jenkins?这样做的目的是让蓝海管道有一个由运行单独作业的外部脚本生成的阶段点

要详细说明这个例子。。。如果此demo.py脚本在一个阶段中输出正常运行时间

#!/bin/env python3.6
import subprocess, time

def uptime():
    return (subprocess.run('uptime', stdout=subprocess.PIPE, encoding='utf8')).stdout.strip()

for i in range(3):
    print("stage({val}) {{\n    echo \"{output}\" \n}}".format(val=i, output=uptime()))
    time.sleep(1)
詹金斯管道中的设置位置

node {
    stage("start demo"){
        sh "/tmp/demo.py"

    }
}
这个演示只输出文本,不在蓝海中创建任何阶段

[Pipeline] sh
+ /tmp/demo.py
stage(0) {
    echo "03:17:16 up 182 days, 12:17,  8 users,  load average: 0.00, 0.03, 0.05" 
}
stage(1) {
    echo "03:17:17 up 182 days, 12:17,  8 users,  load average: 0.00, 0.03, 0.05" 
}
stage(2) {
    echo "03:17:18 up 182 days, 12:17,  8 users,  load average: 0.00, 0.03, 0.05" 
}

同样,这一点是让Blue Ocean pipeline有一个带有日志的阶段点,您可以计算一个表达式,然后调用它

node(''){
 Closure x = evaluate("{it -> evaluate(it)}" )
 x(" stage('test'){ script { echo 'hi'}}")
}

由于Jenkins将Groovy脚本转换为Java,对其进行编译,然后执行结果,因此很难使用外部程序生成更多的Groovy来执行,因为需要转换额外的Groovy代码。但是生成的代码是运行的结果,这意味着转换已经完成

相反,您可能希望在Groovy中以编程方式构建stage


some_array = ["/tmp/demo.py", "sleep 10", "uptime"] 

def getBuilders()
{
    def builders = [:]

    some_array.eachWithIndex { it, index ->
        // name the stage
        def name = 'Stage #' + (index + 1)
        builders[name] = {
            stage (name) {
                def my_label = "jenkins_label" // can choose programmatically if needed
                node(my_label) {
                        try {
                            doSomething(it)
                        }
                        catch (err) { println "Failed to run ${it}"; throw err  }
                        finally {  }
                    }
            }
        }
    };
    return builders
}

def doSomething(something) {
    sh "${something}"
}
然后在你的主管道中

        stage('Do it all') {
            steps {
                script {
                    def builders = getBuilders()
                    parallel builders
                }
            }

这将运行三个并行阶段,其中一个将运行
/tmp/demo.py
,第二个
sleep 10
,第三个
正常运行时间

您的示例很有趣,但只有在打开到外部脚本的管道时才能工作。因此,如果doSomething从管道中获得消息,那么它将在何处创建一个阶段。你知道这是否可行吗?恐怕我不明白你的问题。你在说什么“管道”?你可以调用外部程序,并用
def to_Do=sh(脚本:“1.sh”,returnStdout:true)读取其输出。trim()
然后将其作为
doSomething(to_Do)
传递。因此,如果
echo sleep 90
1.sh
中,这将被传递并在以后调用。evaluate是一个新功能,但如何将外部脚本输出作为其运行?我假设,您可以使用脚本的输出初始化一个变量,然后调用闭包。我想我需要更多的帮助。python(或其他)脚本正在服务器上运行,完成一个步骤后需要将状态发送给jenkins。然后,它应该能够将其作为一个步骤注入管道中,并继续执行另一个任务,然后将其作为一个新步骤进行更新。那么,评估是如何实现的呢?