Jenkins 脚本管道或声明性管道

我试图转换我的旧风格的项目基础工作流程为基于 Jenkins 的管道。在浏览 医生时,我发现有两种不同的语法,分别命名为 scripteddeclarative。比如最近发布的 Jenkins web declarative语法(2016年底)。尽管有一个新的语法版本,Jenkins 仍然支持脚本语法。

现在,我不确定在哪种情况下,这两种类型会是最佳匹配。那么 declarative会成为詹金斯管道的未来吗?

任何人都可以分享一些关于这两种语法类型的想法。

78252 次浏览

陈述式似乎是更加未来的选择和人们推荐的一种。它是可视化管道编辑器可以支持的唯一一个。它支持验证。它最终拥有了脚本的大部分力量,因为你可以回到脚本在大多数情况下。偶尔有人会提出一个用例,在这个用例中,他们不能完全使用声明式来完成他们想要做的事情,但这通常是那些已经使用脚本一段时间的人,这些特性差距可能会及时消失。

更多内容: https://jenkins.io/blog/2017/02/03/declarative-pipeline-ga/

Jenkins 文档正确地解释并比较了这两种类型。

To quote: 脚本管道为 Jenkins 用户提供了巨大的灵活性和扩展性。Groovy 学习曲线通常并不适用于给定团队的所有成员,所以创建 Declarative 管道是为了提供一种更简单、更固执己见的语法来创建 Jenkins 管道。

两者在根本上是同一个管道子系统。”

Read more here:https://jenkins.io/doc/book/pipeline/syntax/#compare

当 Jenkins 管道最初创建时,Groovy 被选为基础。Jenkins 长期以来一直使用嵌入式 Groovy 引擎为管理员和用户提供先进的脚本功能。此外,Jenkins 管道的实现者发现 Groovy 是构建现在称为“脚本管道”DSL 的坚实基础。

由于它是一个功能齐全的编程环境,Scripted Pipele.com 为 Jenkins 用户提供了大量的灵活性和可扩展性。Groovy 学习曲线通常并不适用于给定团队的所有成员,所以创建 Declarative 管道是为了提供一种更简单、更固执己见的语法来创建 Jenkins 管道。

这两者在本质上是相同的管道子系统。它们都是“管道作为代码”的持久实现它们都能够使用内置在管道中或由插件提供的步骤。两者都能够利用共享库

然而,它们的不同之处在于语法和灵活性。声明式结构以更严格和预先定义的结构限制用户可用的内容,使其成为更简单的持续交付管道的理想选择。Scripted 提供的限制非常少,因为结构和语法的限制往往由 Groovy 本身定义,而不是任何特定于管道的系统,这使得它成为高级用户和需求更复杂的用户的理想选择。顾名思义,声明管道鼓励宣告式编程模式。然而脚本管道遵循一个更命令式编程的模型。

语法比较复制

另一件需要考虑的事情是声明性管道具有 Script ()步骤。这可以运行任何脚本管道。因此,我的建议是使用声明性管道,如果需要,还可以对脚本管道使用 script()。因此你得到了两个世界的最好结果。

我最近从库伯内特经纪人的剧本改成了陈述性的。直到7月18日宣布的管道还没有完全能够指定库伯内特豆荚。然而,通过添加 yamlFile步骤,您现在可以从回购文件中的 yaml 文件读取您的 pod 模板。

这样你就可以使用例如 vscode 的 kubernetes 插件来验证你的 pod 模板,然后把它读入你的 Jenkins 文件,并按照你喜欢的步骤使用这些容器。

pipeline {
agent {
kubernetes {
label 'jenkins-pod'
yamlFile 'jenkinsPodTemplate.yml'
}
}
stages {
stage('Checkout code and parse Jenkinsfile.json') {
steps {
container('jnlp'){
script{
inputFile = readFile('Jenkinsfile.json')
config = new groovy.json.JsonSlurperClassic().parseText(inputFile)
containerTag = env.BRANCH_NAME + '-' + env.GIT_COMMIT.substring(0, 7)
println "pipeline config ==> ${config}"
} // script
} // container('jnlp')
} // steps
} // stage

如上所述,您可以添加脚本块。

apiVersion: v1
kind: Pod
metadata:
name: jenkins-pod
spec:
containers:
- name: jnlp
image: jenkins/jnlp-slave:3.23-1
imagePullPolicy: IfNotPresent
tty: true
- name: rsync
image: mrsixw/concourse-rsync-resource
imagePullPolicy: IfNotPresent
tty: true
volumeMounts:
- name: nfs
mountPath: /dags
- name: docker
image: docker:17.03
imagePullPolicy: IfNotPresent
command:
- cat
tty: true
volumeMounts:
- name: docker
mountPath: /var/run/docker.sock
volumes:
- name: docker
hostPath:
path: /var/run/docker.sock
- name: nfs
nfs:
server: 10.154.0.3
path: /airflow/dags
  1. 声明性管道是在标记为“管道”的块中定义的,而脚本化管道是在“节点”中定义的。
  2. Syntax - Declarative pipeline has 'Stages' , 'Steps'
  3. 如果构建失败,声明性构建提供了一个选项,可以从该阶段再次重新启动构建,这在脚本选项中是不正确的
  4. 如果脚本中有任何问题,那么声明性的脚本将在您构建作业时立即通知您,但是如果是脚本的话,它将通过“ OK”阶段,并在“ Not ok”阶段中抛出错误

一个非常好的阅读 https://e.printstacktrace.blog/jenkins-scripted-pipeline-vs-declarative-pipeline-the-4-practical-differences/ @ szymon. Stepniak < a href = “ https://stackoverflow./users/2194470/szymon-steppniak? tab = profile”> https://stackoverflow.com/users/2194470/szymon-Stepniak?tab=profile

I also have this question, which brought me here. Declarative pipeline certainly seems like the preferred method and I personally find it much more readable, but I'm trying to convert a mid-level complexity Freestyle job to Declarative and I've found at least one plugin, the Build Blocker plugin, that I can't get to run even in the a script block in a step (I've tried putting the corresponding "blockOn" command everywhere with no luck, and the return error is usually "No such DSL method 'blockOn' found among steps".) So I think plugin support is a separate issue even with the script block (someone please correct me if I'm wrong in this.) I've also had to use the script block several times to get what I consider simple behaviors to work such as setting the build display name.

根据我的经验,我倾向于按照脚本重做我的工作,因为对 Declarative 的支持仍然不能满足我们的需要,但是不幸的是,我同意这似乎是最未来的证明选项,并且它得到了官方的支持。在做出选择之前,也许要考虑一下你打算使用多少个插件。