Intro to Jenkins 2 and the Power of Pipelines – 介绍Jenkins 2和管道的力量

最后修改: 2017年 12月 29日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this article, we’re going to showcase the usage of pipelines through an example of continuous delivery using Jenkins.

在本文中,我们将通过使用Jenkins的持续交付示例来展示管道的用法。

We’re going to build a simple, yet quite useful pipeline, for our sample project:

我们将为我们的样本项目建立一个简单但相当有用的管道。

  • Compilation
  • Simple static analysis (parallel with compilation)
  • Unit tests
  • Integration tests (parallel with unit tests)
  • Deployment

2. Setting up Jenkins

2.设置Jenkins

First of all, we need to download the latest stable version of Jenkins (2.73.3 at the point of writing this article).

首先,我们需要下载Jenkins的最新稳定版本(在撰写本文时为2.73.3)。

Let’s navigate to the folder where our file is and run it using the java -jar jenkins.war command. Keep in mind that we can’t use Jenkins without an initial users setup.

让我们导航到我们的文件所在的文件夹,并使用java -jar jenkins.war命令运行它。请记住,如果没有初始用户设置,我们就无法使用Jenkins。

After unlocking Jenkins by using the initial admin generated password, we must fill profile information of the first admin user and be sure to install all recommended plugins.

在使用初始管理员生成的密码解锁Jenkins后,我们必须填写第一个管理员用户的档案信息,并确保安装所有推荐的插件。

Now we have a fresh installation of Jenkins ready to be used.

现在我们有了一个新安装的Jenkins,可以使用了。

All available versions of Jenkins can be found here.

所有可用的Jenkins版本都可以在这里找到。

3. Pipelines

3.管线

Jenkins 2 comes with a great feature called Pipelines, which is very extensible when we need to define a continuous integration environment for a project.

Jenkins 2带有一个伟大的功能,叫做Pipelines,当我们需要为一个项目定义持续集成环境时,它是非常可扩展的。

A Pipeline is another way of defining some Jenkins steps using code, and automate the process of deploying software.

管道是使用代码定义一些Jenkins步骤的另一种方式,并使部署软件的过程自动化。

It’s using a Domain Specific Language(DSL) with two different syntaxes:

它使用的是具有两种不同语法的特定域名语言(DSL)

  • Declarative Pipeline
  • Scripted Pipeline

In our examples, we’re going to use the Scripted Pipeline which is following a more imperative programming model built with Groovy.

在我们的例子中,我们将使用Scripted Pipeline,它遵循的是用Groovy构建的更加命令式的编程模型。

Let’s go through some characteristics of the Pipeline plugin:

让我们来看看Pipeline插件的一些特点。

  • pipelines are written into a text file and treated as code; this means they can be added to version control and modified later on
  • they will remain after restarts of the Jenkins server
  • we can optionally pause pipelines
  • they support complex requirements such as performing work in parallel
  • the Pipeline plugin can also be extended or integrated with other plugins

In other words, setting up a Pipeline project means writing a script that will sequentially apply some steps of the process we want to accomplish.

换句话说,设置一个Pipeline项目意味着要写一个脚本,依次应用我们想要完成的过程中的一些步骤。

To start using pipelines we have to install the Pipeline plugin that allows composing simple and complex automation.

为了开始使用管道,我们必须安装管道插件,它允许组成简单和复杂的自动化。

We can optionally have the Pipeline Stage View one too so that when we run a build, we’ll see all the stages we’ve configured.

我们可以选择有管道阶段视图一个,这样当我们运行构建时,我们会看到我们所配置的所有阶段。

4. A Quick Example

4.一个快速的例子

For our example, we’ll use a small Spring Boot application. We’ll then create a pipeline which clones the project, builds it and runs several tests, then runs the application.

在我们的例子中,我们将使用一个小型的Spring Boot应用程序。然后,我们将创建一个管道,克隆该项目,构建它并运行几个测试,然后运行该应用程序。

Let’s install the Checkstyle, Static Analysis Collector and JUnit plugins, which are respectively useful to collect Checkstyle results, build a combined analysis graph of the test reports and illustrate successfully executed and failed tests.

让我们安装CheckstyleStatic Analysis CollectorJUnit插件,它们分别对收集Checkstyle结果、建立测试报告的综合分析图以及说明成功执行和失败的测试很有用。

First, let’s understand the reason of Checkstyle here: it’s a development tool that helps programmers write better Java code following accepted and well-known standards.

首先,让我们了解一下Checkstyle在这里的原因:它是一个开发工具,可以帮助程序员按照公认的知名标准编写更好的Java代码。

Static Analysis Collector is an add-on which collects different analysis outputs and prints the results in a combined trend graph. Additionally, the plug-in provides health reporting and build stability based on these grouped results.

静态分析收集器是一个插件,它收集不同的分析输出,并在一个组合趋势图中打印出结果。此外,该插件还提供健康报告和基于这些分组结果的构建稳定性。

Finally, the JUnit plugin provides a publisher that consumes XML test reports generated during the builds and outputs detailed and meaningful information relative to a project’s tests.

最后,JUnit插件提供了一个发布器,可以消费在构建过程中产生的XML测试报告,并输出与项目测试相关的详细和有意义的信息。

We’ll also configure Checkstyle in our application’s pom.xml:

我们还将在我们应用程序的pom.xml中配置Checkstyle

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-checkstyle-plugin</artifactId>
    <version>2.17</version>
</plugin>

5. Creating a Pipeline Script

5.创建一个管道脚本

First, we need to create a new Jenkins job. Let’s be sure to select Pipeline as the type before hitting the OK button as described in this screenshot:

首先,我们需要创建一个新的Jenkins作业。让我们确保在点击确定按钮之前选择Pipeline作为类型,如该截图中所述。

The next screen allows us to fill in more details of the different steps of our Jenkins job, such as the description, triggers, some advanced project options:

下一个屏幕允许我们填写Jenkins工作的不同步骤的更多细节,如描述触发器、一些高级项目选项:

Let’s dive into the main and most important part of this kind of job by clicking on the Pipeline tab.

让我们通过点击管道标签,深入了解这种工作的主要和最重要的部分。

Then, for the definition select Pipeline script and check Use Groovy Sandbox.

然后,在定义中选择管道脚本,并勾选使用Groovy沙箱

Here is the working script for a Unix environment:

下面是Unix环境下的工作脚本。

node {
    stage 'Clone the project'
    git 'https://github.com/eugenp/tutorials.git'
  
    dir('spring-jenkins-pipeline') {
        stage("Compilation and Analysis") {
            parallel 'Compilation': {
                sh "./mvnw clean install -DskipTests"
            }, 'Static Analysis': {
                stage("Checkstyle") {
                    sh "./mvnw checkstyle:checkstyle"
                    
                    step([$class: 'CheckStylePublisher',
                      canRunOnFailed: true,
                      defaultEncoding: '',
                      healthy: '100',
                      pattern: '**/target/checkstyle-result.xml',
                      unHealthy: '90',
                      useStableBuildAsReference: true
                    ])
                }
            }
        }
        
        stage("Tests and Deployment") {
            parallel 'Unit tests': {
                stage("Runing unit tests") {
                    try {
                        sh "./mvnw test -Punit"
                    } catch(err) {
                        step([$class: 'JUnitResultArchiver', testResults: 
                          '**/target/surefire-reports/TEST-*UnitTest.xml'])
                        throw err
                    }
                   step([$class: 'JUnitResultArchiver', testResults: 
                     '**/target/surefire-reports/TEST-*UnitTest.xml'])
                }
            }, 'Integration tests': {
                stage("Runing integration tests") {
                    try {
                        sh "./mvnw test -Pintegration"
                    } catch(err) {
                        step([$class: 'JUnitResultArchiver', testResults: 
                          '**/target/surefire-reports/TEST-' 
                            + '*IntegrationTest.xml'])
                        throw err
                    }
                    step([$class: 'JUnitResultArchiver', testResults: 
                      '**/target/surefire-reports/TEST-' 
                        + '*IntegrationTest.xml'])
                }
            }
            
            stage("Staging") {
                sh "pid=\$(lsof -i:8989 -t); kill -TERM \$pid " 
                  + "|| kill -KILL \$pid"
                withEnv(['JENKINS_NODE_COOKIE=dontkill']) {
                    sh 'nohup ./mvnw spring-boot:run -Dserver.port=8989 &'
                }   
            }
        }
    }
}

First, we’re cloning the repository from GitHub, then changing the directory to our project, which is called spring-jenkins-pipeline.

首先,我们从GitHub上克隆仓库,然后将目录改为我们的项目,称为spring-jenkins-pipeline.

Next, we compiled the project and apply Checkstyle analysis in a parallel way.

接下来,我们编译了该项目,并以平行方式应用Checkstyle分析。

The following step represents a parallel execution of unit tests and integration tests, then deployment of the app.

下面的步骤代表了单元测试和集成测试的平行执行,然后是应用的部署。

Parallelism is used to optimize the pipeline, and have the job runs faster. It’s a best practice in Jenkins to simultaneously run some independent actions that can take a lot of time.

并行主义用于优化管道,并使作业运行得更快。在Jenkins中,同时运行一些可能需要大量时间的独立动作是一种最佳做法。

For example, in a real-world project, we usually have a lot of unit and integration tests that can take longer.

例如,在现实世界的项目中,我们通常有大量的单元和集成测试,这些测试可能需要更长的时间。

Note that if any test failed the BUILD will be marked as FAILED too and the deployment will not occur.

请注意,如果任何测试失败,BUILD也将被标记为失败,部署将不会发生。

Also, we’re using JENKINS_NODE_COOKIE to prevent immediate shut down of our application when the pipeline reaches the end.

另外,我们使用 JENKINS_NODE_COOKIE来防止管道到达终点时立即关闭我们的应用程序。

To see a more general script working on other different systems, check out the GitHub repository.

要查看在其他不同系统上工作的更通用的脚本,请查看GitHub资源库

6. Analysis Report

6.分析报告

After creating the job, we’ll save our script and hit Build Now on the project home of our Jenkins dashboard.

创建作业后,我们将保存我们的脚本,并在Jenkins仪表板的项目主页上点击Build Now

Here’s an overview of the builds:

这里有一个构建的概述。

A little further down we’ll find the stage view of the pipeline, with the result of each stage:

再往下一点,我们会发现管道的阶段性视图,其中有每个阶段的结果。

Each output is accessible when hovering over a stage cell and clicking the Logs button to see the log messages printed in that step.

当把鼠标悬停在一个阶段的单元格上,点击Logs按钮,可以看到该步骤中打印的日志信息,每个输出都可以访问。

We can also find more details of the code analysis. Let’s click on the desired build from the Build History on the right menu and hit Checkstyle Warnings.

我们还可以找到代码分析的更多细节。让我们从右侧菜单的Build History中点击所需的构建,并点击Checkstyle Warnings.

Here we see 60 high priority warnings browsable by clicking:

在这里,我们看到60个高优先级的警告,可以通过点击浏览。

The Details tab displays pieces of information that highlight warnings and enable the developer to understand the causes behind them.

Details标签显示突出警告的信息片段,使开发人员能够了解这些警告背后的原因。

In the same way, the full test report is accessible by clicking on Test Result link. Let’s see the results of the com.baeldung package:

以同样的方式,点击测试结果链接,就可以获得完整的测试报告。让我们看看com.baeldung包的结果。

Here we can see each test file with its duration and status.

这里我们可以看到每个测试文件的持续时间和状态。

7. Conclusion

7.结论

In this article, we set up a simple continuous delivery environment to run and show static code analysis and test report in Jenkins via a Pipeline job.

在这篇文章中,我们设置了一个简单的持续交付环境,通过Pipeline作业在Jenkins中运行并显示静态代码分析和测试报告。

As always, the source code for this article can be found over on GitHub.

一如既往,本文的源代码可以在GitHub上找到over。