“这是一本非常理想的书,既适合CI/CD的新手,也适合使用Jenkins多年的老手。这本书将帮助你发现以及重新发现Jenkins中的未知世界。”
—— Jenkins创始人 Kohsuke Kawaguchi
Jenkins 2的概念比较宽泛,在特定的上下文环境中,它用来泛指支持流水线即代码以及其他类似Jenkinsfile等新特性的新版Jenkins,这些新特性将始终贯穿Jenkins的新版。
其中的部分特性在Jenkins 1.X版本中已经通过插件的方式实现(确切地讲,Jenkins 2也是通过对已有插件的重点升级和新插件的引入来获得新功能的)。但是Jenkins 2则更进一步,它将这些特性视为一种同Jenkins交互的核心方式,并且也是Jenkins推荐的方式。相比之前用户只能通过Web界面进行配置的方式来定义Jenkins任务,现在通过使用Jenkins DSL和Groovy语言编写程序,用户可以定义流水线并执行各种任务。
DSL是Jenkins 2的核心组件,作为构建模块让其他核心的用户导向特性成为可能。让我们来大致看下这些特性如何使Jenkins 2区别于传统版本的Jenkins。我们会快速体验一种全新的方式,将原本写在Jenkins中的代码提取到一个Jenkinsfile文件中,以一种更加结构化的方法来创建工作流——声明式流水线,同时还有一个更加令人兴奋的全新用户界面——Blue Ocean。
Jenkinsfile
在Jenkins 2中,流水线配置可以从Jenkins中分离出来。在以前版本的Jenkins中,任务配置都是以配置文件的形式保存在Jenkins的主目录中的。这就意味着所有的配置变更都依赖于Jenkins可以识别和管理这些文件(除非你想直接修改XML文件,但这是非常有挑战性的事情)。在Jenkins 2中,你可以在Web可视化界面的文本区中以DSL脚本来编写流水线配置。当然,你同样可以将这些文本形式的DSL代码和其他保存源码的文本文件一起保存在外部的版本控制系统中。这使得你可以像管理其他源码一样通过文件的形式来管理Jenkins任务,支持历史追溯、差异对比等功能。
Jenkins 2推荐使用名为Jenkinsfile的文件保存任务配置和流水线信息。不同的项目和分支都会有自己的Jenkinsfile,其内容各不相同。你可以将全部代码写在一个Jenkinsfile中,也可以通过共享库的方式调用外部代码。另外,DSL语句也允许在脚本中加载外部代码。
Jenkinsfile可以起到标记文件(marker file)的作用,这意味着只要Jenkins发现你的工程源码中包含了Jenkinsfile文件,那么这个项目或分支就可以被Jenkins自动解析和运行。Jenkins同样可以识别出需要用到的源码版本控制管理(SCM)项目和分支,并加载和执行Jenkinsfile中的代码。如果你熟悉Gradle构建工具,这个理念与应用中定义的build.gradle文件类似。我会在本书中对Jenkinsfile进行更加详细的描述。
图1-1展示了一个用于源码版本控制的Jenkinsfile的例子。
图1-1 一个用于源码版本控制的Jenkinsfile的例子
声明式流水线
在以前版本的Jenkins中,流水线即代码大体就是Groovy脚本,其中插入了部分针对Jenkins的DSL步骤。这种方式几乎没有结构上的约束,程序流程也基于Groovy语法结构实现。错误报告和检查同样基于Groovy程序的执行,而非从期望通过Jenkins实现功能的角度来检查。
这种模式现在被称为脚本式流水线。然而,流水线的DSL语言也在不断进化。
在脚本式流水线中,DSL支持为数众多的任务步骤,但是仍然缺失了部分面向Jenkins任务的核心特性,比如,构建后处理、流水线结构错误检查以及基于不同执行状态发送通知的功能。当然大多数功能都可以通过Groovy编程机制来模拟实现,比如trycatch-finally语法。但是这在面向Jenkins编程的基础上对Groovy语言的技能提出了更高的要求。图1-1中的Jenkinsfile展示了带有try-catch的做通知处理的脚本式流水线样例。
在2016年和2017年间,作为Jenkins主要贡献者的企业级公司CloudBees引入了一种高级流水线即代码的编程语法,这就是声明式流水线。这种语法为流水线带来了一种清晰、可预期的结构,以及更强大的DSL元素和结构体。这种方式更加接近通过Web界面构建流水线的工作方法(即自由风格类型项目)。
这里有一个构建后过程的示例,现在我们可以使用内建的 DSL机制,通过简单定义就能实现基于构建状态发送通知的功能。这减少了使用Groovy代码提供流水线定义来模拟传统Jenkins特性的需求。
声明式流水线更加严谨的结构同样有助于错误检查。于是我们不再需要在发生错误时查看Groovy的调试信息(traceback),而是将错误信息以更加直观、简单的方式展现给用户,在大多数情况下可以直接定位到具体的错误。图1-2给出了具有增强错误检查功能的声明式流水线所输出的代码片段:
图1-2 具有增强错误检查功能的声明式流水线
Blue Ocean界面
声明式流水线的结构同时也是Jenkins 2的另一项创新——Blue Ocean,全新Jenkins可视化界面——的基础。BlueOcean为流水线的每个阶段添加了图形化展示,可以显示成功/失败和进展等标识,并对每个任务都提供了点选式日志查看功能。Blue Ocean还提供了一个简单的可视化编辑器。图1-3展示了一个在Blue Ocean中成功运行的流水线及其日志显示的例子。
图1-3 Blue Ocean界面的运行成功和查看日志的例子
Jenkins 2的全新任务类型
Jenkins 2增加了一些新的任务类型,主要是围绕利用流水线即代码和Jenkinsfile等关键功能来设计的。这些类型比以往任何时候都更容易自动化任务、流水线创建以及组织项目。每个新任务/工作项/项目的创建都以相同的方式开始。
这里需要说明一下,只有安装了相关插件,才能拥有这些新的任务类型。如果你在Jenkins 2初始化安装向导中选择了安装系统推荐的插件,才可以使用这里讨论的任务类型。
一旦安装了Jenkins 2并登录成功,就可以像以前一样创建新的任务。如图1-4所示,欢迎来到Jenkins!欢迎标语下面有一个建议用户新建任务的链接,这个链接对应菜单栏里面的新建工作项。在绝大多数情况下新建工作项就是指项目。在本书中将交替使用“任务”、“工作项”和“项目”这几个术语。
图1-4 Jenkins欢迎页:新建任务、工作项和项目入口
当选择在Jenkins 2中创建一个新的工作项时,屏幕中会提示选择新建任务的类型(见图1-5)。你会看到一些熟悉的类型,比如,自由风格类型项目,同时还有一些你以前没见过的类型。
图1-5 Jenkins 2的项目选项
顾名思义,流水线类型的项目旨在创建流水线。这是通过Jenkins DSL编写代码来实现的。流水线项目是我们在本书中主要讨论的项目类型。
正如已经指出的,流水线既可以用“脚本式”语法风格编写,也可以用“声明式”语法风格编写。这种项目类型的流水线可以很容易地转换成Jenkinsfile。
这是一种可以把多个项目归类到一起的方式,而不是项目本身的类型。请注意,这并不像Jenkins仪表板上传统的“视图”选项卡那样,让你按照项目列表筛选。更确切地说,它就像操作系统中的目录文件夹。文件夹名称是项目路径的一部分。
有些源码版本控制平台提供了将多个代码库聚合成“组织”的机制。Jenkins集成允许将Jenkins流水线脚本存储为组织内代码库中的Jenkinsfile文件,并基于这些库执行。目前已经支持GitHub和Bitbucket平台的组织功能,未来将会逐步支持其他的平台。为简单起见,在本书中主要以GitHub的组织项目作为例子。
假设有足够的访问权限,Jenkins可以在代码托管侧自动建立一个组织的webhook(来自网站的通知),从而任何代码库中的变更都会通知Jenkins实例。当Jenkins收到通知时,它会检测代码库中作为一种标记而使用的Jenkinsfile文件,并执行其中的命令来运行流水线。
在这种类型的项目中,Jenkins再次使用Jenkinsfile作为标记的功能。在一个有Jenkinsfile的项目中,如果创建了一个新的分支,Jenkins将自动基于这个新分支创建一个新项目。此类型项目可应用于任何Git或SVN代码库。
值得注意的是,Jenkins仍然支持之前的自由风格类型项目,仍然可以使用基于Web的表单创建任务,并像以前一样执行它们。但Jenkins 2更加关注的是流水线任务。
很容易看出,相对于传统的Jenkins模式,Jenkins 2发生了重大转变。因此,值得花几分钟来讨论转变的原因。
本文节选自电子工业出版社博文视点新书《Jenkins 2权威指南》(胡狼书),无论你是构建管理员、开发人员、测试人员,还是其他任何角色,本书都是你学习Jenkins演变的最佳选择。通过本书,你可以轻松地使用Jenkins 2的新特性来设计、实现和执行流水线,在灵活性、管控和易于维护等方面的提升都是之前版本的Jenkins所无法想象的。同时无论身处何种角色,你都能快速从这些新特性中受益。