解决jenkins启动结束时保留衍生进程

在jenkins中配置自动更新部署项目时,如果采取用execute shell启动/关闭tomcat,会发现可以进行关闭tomcat,但是无法启动tomcat,虽然构建会显示执行成功,但是查看进程,tomcat是没有启动的。这是因为Jenkins默认会在Build结束后Kill掉所有的衍生进程。需要进行以下配置,才能避免此类情况发生:

1、重设环境变量build_id

在execute shell输入框中加入BUILD_ID=DONTKILLME,即可防止jenkins杀死启动的tomcat进程

未分类

2、在启动jenkins 的时候禁止jenkins杀死衍生进程

修改/etc/sysconfig/jenkins配置,在JENKINS_JAVA_OPTIONS中加入-Dhudson.util.ProcessTree.disable=true。需要重启jenkins生效

此方法配置一次后,所有的job都无需设置BUILD_ID,就能够防止jenkins杀死启动的tomcat进程。

Jenkins节点重启连接失败的解决方法

当我们的Jenkins配置了其他的节点服务器,刚开始需要配置一些东西保证连接,但是当我们重启了服务器之后,就会发现从节点无法连接到服务器上,一直显示:

未分类

即使重新断开并重连也无法正常连接:

未分类

这时需要登录到Windows节点服务器上,按照上面给的提示,进行命令行的编辑:

上方提示为:

java -jar slave.jar
-jnlpUrl http://xx.xx.xx.xx:8080/computer/7999/slave-agent.jnlp -secret
fd09965cb330bab240344c4fdf93d1f4d4dd44019d42a4b51f67c323d58061c7

方法一:我们需要吧slave.jar的路径补充完整,才可以直接执行

如,我的slave.jar在E:jenkins20文件夹下,则我的命令应为:

java -jar
E:jenkins20slave.jar -jnlpUrl http://xx.xx.xx.xx:8080/computer/7999/slave-agent.jnlp
-secret fd09965cb330bab240344c4fdf93d1f4d4dd44019d42a4b51f67c323d58061c7

未分类

方法二:如果进入到slave.jar目录文件中也是可以的。

如:

未分类

再直接执行上面的命令即可:

java -jar slave.jar
-jnlpUrl http://xx.xx.xx.xx:8080/computer/7999/slave-agent.jnlp -secret
fd09965cb330bab240344c4fdf93d1f4d4dd44019d42a4b51f67c323d58061c7

请根据页面显示进行修改

执行命令正确如下:

未分类

上方的提示信息也可以到Jenkins安装节点的jenkins-slave.xml中找,

未分类

根据实际情况修改为上述执行脚本进行执行即可:

晚上脚本执行步骤,则可以正常连接,但是该命令行窗口无法关闭,关闭即丢失连接。

未分类

Jenkins使用Email Extension插件配置邮件通知

Jenkins 内置了 Mailer 插件用于发送邮件通知,但是 Mailer 插件的功能比较简单,无法按照用户的需求进行邮件的定制。Email Extension 是 Jenkins 默认推荐安装的一款功能强大的邮件插件,使用它几乎可以定制邮件的任何部分。本文将结合笔者的使用经验介绍 Email Extension 插件的使用方法。

全局配置

和其它的插件一样,Email Extension 插件的全局配置也是在 Jenkins -> Manage Jenkins -> Configure System 中。具体的配置项非常多,下面介绍几个比较基本且重要的配置项。

SMTP server

设置 smtp server 的名称或 IP 地址。

邮件类型

可以选择 HTML 格式的邮件或者是纯文本格式的邮件:

未分类

默认标题

默认的标题为:

$PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS!

显示项目名称,Build 号和 Build 结果。如果没有其它的要求,这个标题也算是简单明了啊!

默认的邮件内容

默认的邮件内容为:

$PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS:

Check console output at $BUILD_URL to view the results.

一般我们会通过邮件模板等功能实现一个完整的邮件内容,所以可以忽略这个默认的内容。

默认的触发条件

作为一种通知方式,在什么条件下触发邮件通知是极为重要的。Email Extension 插件支持的触发器类型是很丰富的:

未分类

个人觉得这里的默认设置没那么重要,因为每个项目的情况都是不一样的,所以最终都需要在项目上进行设置。而项目上的设置会覆盖这里的默认设置。

为项目添加邮件通知

在项目的配置项中添加 Post-build Actions,选择 “Editable Email Notification”:

未分类

然后就可以进行详细的设置了:

未分类

下面介绍一下比较重要的配置项。

关闭邮件通知

未分类

这个选项在维护项目时非常有用,可以临时关闭邮件通知,避免把不必要的邮件发送给用户。

收件人列表

收件人邮件地址,多于一个时需要使用逗号分隔。

邮件类型

和全局设置中的邮件类型一样,没有特殊要求的话保留默认类型即可。此时会应用全局设置中的类型。

默认标题

标题的默认内容为:$DEFAULT_SUBJECT,也就是在全局配置中设置的内容。如果觉着不爽可以进行深度定制,也就是使用系统提供的变量进行拼凑。至于能拿到什么变量,可以参考 Conten Token Reference 的内容:

未分类

点击问号图标就会列出所有可用的变量,实在是太多了,就不贴出来占篇幅了!

默认内容

默认内容为:$DEFAULT_CONTENT,也是在全局配置中设置的内容。和默认标题一样,你也可以自行定义。但多数情况下都会使用后面介绍的邮件模板,这里就不啰嗦了。

附件

有时把一些 Build 产物作为通知邮件的附件是很有用的。这里我们也可以轻松实现:

未分类

我们可以指定文件的名称,也可以使用通配符。
除了 Build 的产物,Build 的日志也是极其重要的信息。它可以帮助我们快速的调查 Build 过程中的各种问题,所以也应该把 Build 日志添加为邮件的附件:

未分类

测试一下,收到的邮件带了两个附件:

未分类

邮件模板

邮件的内容可以包含大量的信息,如果每个项目中都自己组织这些信息会费时费力。使用邮件的模板功能可以极大的提高生产力!

Email Extension 插件支持两种类型的邮件模板,分别是 Jelly 模板和 Groovy 模板。当前的现状是 Groovy 模板正在逐步的取代 Jelly 模板。但是两种模板的设置
和使用方式基本一样,我们以 Groovy 模板为例进行介绍。

在 Email Extension 插件的官方文档中可以找到模板的下载地址。笔者以下载的 groovy-html.template 文件为例进行说明。首先是安装邮件模板,其实就是把模板文件复制到 Jenkins 安装目录下的 email-templates 目录中,如果该目录不存在就先创建它。

接着我们可以测试一下安装的模板是否能正常工作。打开一个添加了 “Editable Email Notification” 的项目,你会发现在左边的菜单中多了一项 “Email Template Testing”:

未分类

选择这个菜单项并且输入刚才安装的模板名称:

未分类

点击 “Go” 按钮,一个预览的邮件内容就会出现在下面的空白处。
最后我们需要在邮件通知的配置中应用这个模板。其实就是设置 Default Content 为:

${SCRIPT, template="groovy-html.template"}

好了,邮件的模板设置已经完成,赶快触发个 Build 看看结果吧!

Pipeline 支持

Email Extension 插件支持 pipeline, 下面的代码可以很好的工作:

stage('test') {
    steps {
        echo 'hello'
        // error 'build failed'
    }
    post {
        success {
            emailext (
              subject: "SUCCESSFUL: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'",
              to: "[email protected]",
              body: """<p>SUCCESSFUL: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]':</p>
    <p>Check console output at &QUOT;<a href='${env.BUILD_URL}'>${env.JOB_NAME} [${env.BUILD_NUMBER}]</a>&QUOT;</p>""",
              recipientProviders: [[$class: 'DevelopersRecipientProvider']]
            )
        }
        failure {
            emailext (
              subject: "FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'",
              to: "[email protected]",
              body: """<p>FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]':</p>
                <p>Check console output at &QUOT;<a href='${env.BUILD_URL}'>${env.JOB_NAME} [${env.BUILD_NUMBER}]</a>&QUOT;</p>""",
              recipientProviders: [[$class: 'DevelopersRecipientProvider']]
            )
        }
    }
}

上面的代码在 stage 执行成功或者失败的情况下发送邮件。但邮件的内容只是简单的纯文本或这是 HTML 格式的文本。笔者尝试在 pipeline 代码中使用邮件模板的功能,但不管是 Jelly 模板还是 Groovy 模板都不能正常工作,所以这里还有待完善的功能。

总结

Email Extension 是一款可定制性强、功能全面的 Jenkins 邮件通知插件。随着 pipeline 日渐成为主流的持续集成方式,希望能 Email Extension 也能紧跟趋势提供对 pipeline 更好的支持。

Jenkins的部署

最基本的连续交付流程将至少具有三个阶段,这些阶段应在以下内容中定义Jenkinsfile:构建,测试和部署。

对于本节,我们将主要关注部署阶段,但应该注意的是,稳定的构建和测试阶段是任何部署活动的重要前身。

Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                echo 'Building'
            }
        }
        stage('Test') {
            steps {
                echo 'Testing'
            }
        }
        stage('Deploy') {
            steps {
                echo 'Deploying'
            }
        }
    }
}

Toggle Scripted Pipeline (Advanced)

Jenkinsfile (Scripted Pipeline)
node {
    stage('Build') {
        echo 'Building'
    }
    stage('Test') {
        echo 'Testing'
    }
    stage('Deploy') {
        echo 'Deploying'
    }
}

阶段作为部署环境

一个常见的模式是扩展级别以捕获额外的部署环境,如“分段”或“生产”,如下面的代码段所示。

stage('Deploy - Staging') {
    steps {
        sh './deploy staging'
        sh './run-smoke-tests'
    }
}
stage('Deploy - Production') {
    steps {
        sh './deploy production'
    }
}

在这个例子中,我们假设我们的./run-smoke-tests脚本运行的任何“烟雾测试” 都足以将释放资格或验证到生产环境。自动将代码自动部署到生产的这种Pipeline可以被认为是“持续部署”的实现。虽然这是一个崇高的理想,但对许多人来说,连续部署可能不实际的原因很好,但仍然可以享受持续交付的好处。 Jenkins Pipeline很容易支撑两者。

要求人力投入进行

通常在阶段之间,特别是环境阶段之间,您可能需要人为的输入才能继续。例如,判断应用程序是否处于“促进”到生产环境的状态。这可以通过input步骤完成。在下面的示例中,“真实检查”阶段实际上阻止输入,如果没有人确认进度,则不会继续进行。

Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    stages {
        /* "Build" and "Test" stages omitted */

        stage('Deploy - Staging') {
            steps {
                sh './deploy staging'
                sh './run-smoke-tests'
            }
        }

        stage('Sanity check') {
            steps {
                input "Does the staging environment look ok?"
            }
        }

        stage('Deploy - Production') {
            steps {
                sh './deploy production'
            }
        }
    }
}

Toggle Scripted Pipeline (Advanced)

Jenkinsfile (Scripted Pipeline)
node {
    /* "Build" and "Test" stages omitted */

    stage('Deploy - Staging') {
        sh './deploy staging'
        sh './run-smoke-tests'
    }

    stage('Sanity check') {
        input "Does the staging environment look ok?"
    }

    stage('Deploy - Production') {
        sh './deploy production'
    }
}

结论

这个导读旨在向您介绍使用Jenkins和Jenkins Pipeline的基础知识。因为它是非常可扩展的,Jenkins可以进行修改和配置,以处理几乎任何方面的自动化。

Jenkins Pipeline结束时的清理和通知

由于post Pipeline的部分保证在Pipeline执行结束时运行,因此我们可以添加一些通知或其他步骤来执行定稿,通知或其他Pipeline末端任务。

Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    stages {
        stage('No-op') {
            steps {
                sh 'ls'
            }
        }
    }
    post {
        always {
            echo 'One way or another, I have finished'
            deleteDir() /* clean up our workspace */
        }
        success {
            echo 'I succeeeded!'
        }
        unstable {
            echo 'I am unstable :/'
        }
        failure {
            echo 'I failed :('
        }
        changed {
            echo 'Things were different before...'
        }
    }
}

Toggle Scripted Pipeline (Advanced)

Jenkinsfile (Scripted Pipeline)
node {
    try {
        stage('No-op') {
            sh 'ls'
        }
    }
}
catch (exc) {
    echo 'I failed'
}
finally {
    if (currentBuild.result == 'UNSTABLE') {
        echo 'I am unstable :/'
    } else {
        echo 'One way or another, I have finished'
    }
}

有很多方法可以发送通知,下面是一些演示如何将有关Pipeline的通知发送到电子邮件,Hipchat房间或Slack频道的片段。

Email

post {
    failure {
        mail to: '[email protected]',
             subject: "Failed Pipeline: ${currentBuild.fullDisplayName}",
             body: "Something is wrong with ${env.BUILD_URL}"
    }
}

Hipchat

post {
    failure {
        hipchatSend message: "Attention @here ${env.JOB_NAME} #${env.BUILD_NUMBER} has failed.",
                    color: 'RED'
    }
}

Slack

post {
    success {
        slackSend channel: '#ops-room',
                  color: 'good',
                  message: "The pipeline ${currentBuild.fullDisplayName} completed successfully."
    }
}

现在,当事情出现故障,不稳定或甚至成功时,我们可以通过令人兴奋的部分完成我们的持续交付流程:shipping!

Jenkins记录测试结果和工件

虽然测试是良好的连续交付流程的关键部分,但大多数人不想筛选数千行控制台输出,以查找有关测试失败的信息。为了使这更容易,Jenkins可以记录和汇总测试结果,只要您的测试运行器可以输出测试结果文件。Jenkins通常捆绑在一起junit,但是如果您的测试运行器无法输出JUnit风格的XML报告,则还会有其他插件,可以处理任何广泛使用的测试报告格式。

要收集我们的测试结果和工件,我们将使用该post部分。

Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    stages {
        stage('Test') {
            steps {
                sh './gradlew check'
            }
        }
    }
    post {
        always {
            junit 'build/reports/**/*.xml'
        }
    }
}

Toggle Scripted Pipeline (Advanced)

Jenkinsfile (Scripted Pipeline)
node {
    try{
        stage('Test') {
            sh './gradlew check'
        }
    finally {
        junit 'build/reports/**/*.xml'
    }
}

这将永远抓住测试结果,让Jenkins跟踪他们,计算趋势并对其进行报告。测试失败的Pipeline将被标记为“不稳定”,在Web UI中用黄色表示。这与“FAILED”状态不同,用红色表示。

当有测试失败时,从Jenkins抓住建造的文物进行本地分析和调查往往是有用的。Jenkins内置的支持存储“工件”,在Pipeline执行过程中生成的文件,实际上是这样。

这很容易通过archive步骤和文件集合表达式完成,如下面的示例所示:

Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                sh './gradlew build'
            }
        }
        stage('Test') {
            steps {
                sh './gradlew check'
            }
        }
    }

    post {
        always {
            archive 'build/libs/**/*.jar'
            junit 'build/reports/**/*.xml'
        }
    }
}

Toggle Scripted Pipeline (Advanced)

Jenkinsfile (Scripted Pipeline)
node {
    try{
        stage('Test') {
            sh './gradlew check'
        }
    finally {
        archiveArtifacts artifacts: 'build/libs/**/*.jar', fingerprint: true
        junit 'build/reports/**/*.xml'
    }
}

记录Jenkins中的测试和工件对于快速轻松地向团队的各个成员发布信息非常有用。在下一节中,我们将讨论如何告诉团队成员什么在我们的Pipeline已经发生的事情。

Jenkins使用环境变量的方法

Jenkins 环境变量可以全局设置,如下面的示例或每个阶段。您可能会期望,每个阶段设置环境变量意味着它们将仅适用于定义它们的阶段。

Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any

    environment {
        DISABLE_AUTH = 'true'
        DB_ENGINE    = 'sqlite'
    }

    stages {
        stage('Build') {
            steps {
                sh 'printenv'
            }
        }
    }
}

Toggle Scripted Pipeline (Advanced)

Jenkinsfile (Scripted Pipeline)
node {
    withEnv(['DISABLE_AUTH=true',
             'DB_ENGINE=sqlite']) {
        stage('Build') {
            sh 'printenv'
        }
    }
}

这种从内部定义环境变量的方法Jenkinsfile 对于指示脚本(例如a)可以非常有用Makefile,以不同的方式配置构建或测试,以在Jenkins内部运行它们。

环境变量的另一个常见用途是在构建或测试脚本中设置或覆盖“虚拟”凭据。因为(显而易见)将凭据直接放入一个不好的主意Jenkinsfile,Jenkins Pipeline允许用户快速而安全地访问预定义的凭据,而Jenkinsfile无需知道其价值。

环境证书

如果您的Jenkins环境配置了凭据,例如构建秘密或API令​​牌,那么可以将它们轻松插入环境变量中,以便在Pipeline中使用。下面的代码片段用于“秘密文本”类型的凭据。

environment {
    AWS_ACCESS_KEY_ID     = credentials('AWS_ACCESS_KEY_ID')
    AWS_SECRET_ACCESS_KEY = credentials('AWS_SECRET_ACCESS_KEY')
}

正如第一个例子,这些变量将在全局或每个阶段可用,具体取决于environment指令 在哪里Jenkinsfile。

第二种最常见的凭证类型是“用户名和密码”,仍然可以在environment指令中使用,但会导致稍微不同的变量被设置。

environment {
   SAUCE_ACCESS = credentials('sauce-lab-dev')
}

这将实际设置3个环境变量:

SAUCE_ACCESS 含 <username>:<password>
SAUCE_ACCESS_USR 包含用户名
SAUCE_ACCESS_PSW 包含密码
credentials仅适用于声明性Pipeline。对于使用脚本Pipeline的用户,请参阅该withCredentials步骤的文档。

到目前为止,我们关心的是创建一个配置并执行我们期望的方式的Pipeline。在接下来的两个部分中,我们将介绍连续交付的另一个重要方面:表面反馈和信息。

Jenkins如何定义执行环境

在上一节中, 您可能已经注意到agent每个示例中的指令。该 agent指令告诉Jenkins在哪里以及如何执行Pipeline或其子集。如您所料,agent所有Pipeline都是必需的。

在引擎盖下,有几件事情agent会发生:

  • 该块中包含的所有步骤均排队等待Jenkins执行。一旦执行者可用,步骤就会开始执行。
  • 将分配一个工作区,其中将包含从源代码管理检出的文件以及Pipeline的任何其他工作文件。

有几种方法可以定义代理在Pipeline中使用,对于本次巡视,我们将仅关注使用短暂的Docker container。

Pipeline设计用于容易地使用Docker图像和容器在里面运行。这允许Pipeline定义所需的环境和工具,而无需手动配置各种系统工具和对代理的依赖。这种方法允许您几乎可以使用可以打包在Docker容器中的任何工具 。

Jenkinsfile (Declarative Pipeline)
pipeline {
    agent {
        docker { image 'node:7-alpine' }
    }
    stages {
        stage('Test') {
            steps {
                sh 'node --version'
            }
        }
    }
}

Toggle Scripted Pipeline (Advanced)

Jenkinsfile (Scripted Pipeline)
node {
    /* Requires the Docker Pipeline plugin to be installed */
    docker.image('node:7-alpine').inside {
        stage('Test') {
            sh 'node --version'
        }
    }
}

当Pipeline执行时,Jenkins将自动启动指定的容器并执行其中定义的步骤:

[Pipeline] stage
[Pipeline] { (Test)
[Pipeline] sh
[guided-tour] Running shell script
+ node --version
v7.4.0
[Pipeline] }
[Pipeline] // stage
[Pipeline] }

混合和匹配不同容器或其他代理时,在执行Pipeline时可以有很大的灵活性,有关更多配置选项,请继续使用“使用环境变量” (https://www.w3cschool.cn/jenkins/jenkins-w9ga28n8.html)。

Jenkins运行多个步骤的配置

Pipeline由多个步骤组成,允许您构建,测试和部署应用程序。Jenkins Pipeline允许您以简单的方式组合多个步骤,可以帮助您建模任何类型的自动化过程。

想像一个“一步一步”,就像执行单一动作的单一命令一样。当一个步骤成功时,它移动到下一步。当步骤无法正确执行时,Pipeline将失败。

当Pipeline中的所有步骤成功完成后,Pipeline被认为已成功执行。

Linux,BSD和Mac OS

在Linux,BSD和Mac OS(类Unix)系统上,该sh步骤用于在Pipeline中执行shell命令。

Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                sh 'echo "Hello World"'
                sh '''
                    echo "Multiline shell steps works too"
                    ls -lah
                '''
            }
        }
    }
}

Toggle Scripted Pipeline (Advanced)

Jenkinsfile (Scripted Pipeline)
node {
    stage('Build') {
        sh 'echo "Hello World"'
        sh '''
            echo "Multiline shell steps works too"
            ls -lah
        '''
    }
}

Windows

基于Windows的系统应该使用bat执行批处理命令的步骤。

Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    stages {
        stage('Deploy') {
            steps {
                retry(3) {
                    sh './flakey-deploy.sh'
                }

                timeout(time: 3, unit: 'MINUTES') {
                    sh './health-check.sh'
                }
            }
        }
    }
}

Toggle Scripted Pipeline (Advanced)

Jenkinsfile (Scripted Pipeline)
node {
    stage('Build') {
        bat 'set'
    }
}

超时,重试等等

有一些强大的步骤,“包装”其他步骤,可以轻松地解决问题,如重试(retry)步骤,直到成功或退出,如果步骤太长(timeout)。

Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    stages {
        stage('Deploy') {
            steps {
                retry(3) {
                    sh './flakey-deploy.sh'
                }

                timeout(time: 3, unit: 'MINUTES') {
                    sh './health-check.sh'
                }
            }
        }
    }
}

Toggle Scripted Pipeline (Advanced)

Jenkinsfile (Scripted Pipeline)
node {
    stage('Deploy') {
        retry(3) {
            sh './flakey-deploy.sh'
        }

        timeout(time: 3, unit: 'MINUTES') {
            sh './health-check.sh'
        }
    }
}

“部署”阶段重试flakey-deploy.sh脚本3次,然后等待health-check.sh脚本执行最多3分钟。如果健康检查脚本在3分钟内未完成,则Pipeline将在“部署”阶段被标记为失败。

“包装”的步骤,例如timeout和retry可以包含其它步骤,包括timeout或retry。

我们可以组合这些步骤。例如,如果我们想重新部署我们的部署5次,但是在失败的阶段之前,总是不想花3分钟以上:

Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    stages {
        stage('Deploy') {
            steps {
                timeout(time: 3, unit: 'MINUTES') {
                    retry(5) {
                        sh './flakey-deploy.sh'
                    }
                }
            }
        }
    }
}

Toggle Scripted Pipeline (Advanced)

Jenkinsfile (Scripted Pipeline)
node {
    stage('Deploy') {
        timeout(time: 3, unit: 'MINUTES') {
            retry(5) {
                sh './flakey-deploy.sh'
            }
        }
    }
}

完成

当Pipeline完成执行后,您可能需要运行清理步骤或根据Pipeline的结果执行某些操作。可以在本post节中执行这些操作。

Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    stages {
        stage('Test') {
            steps {
                sh 'echo "Fail!"; exit 1'
            }
        }
    }
    post {
        always {
            echo 'This will always run'
        }
        success {
            echo 'This will run only if successful'
        }
        failure {
            echo 'This will run only if failed'
        }
        unstable {
            echo 'This will run only if the run was marked as unstable'
        }
        changed {
            echo 'This will run only if the state of the Pipeline has changed'
            echo 'For example, if the Pipeline was previously failing but is now successful'
        }
    }
}

Toggle Scripted Pipeline (Advanced)

Jenkinsfile (Scripted Pipeline)
node {
    try {
        stage('Test') {
            sh 'echo "Fail!"; exit 1'
        }
        echo 'This will run only if successful'
    } catch (e) {
        echo 'This will run only if failed'

        // Since we're catching the exception in order to report on it,
        // we need to re-throw it, to ensure that the build is marked as failed
        throw e
    } finally {
        def currentResult = currentBuild.result ?: 'SUCCESS'
        if (currentResult == 'UNSTABLE') {
            echo 'This will run only if the run was marked as unstable'
        }

        def previousResult = currentBuild.previousBuild?.result
        if (previousResult != null && previousResult != currentResult) {
            echo 'This will run only if the state of the Pipeline has changed'
            echo 'For example, if the Pipeline was previously failing but is now successful'
        }

        echo 'This will always run'
    }
}

Jenkins 如何创建Pipeline

开始创建您的第一个Pipeline

快速入门Pipeline:

  • 将其中一个示例复制到您的存储库并将其命名Jenkinsfile

  • 单击Jenkins中的New Item菜单

未分类

  • 为您的新项目提供名称(例如我的Pipeline),然后选择多分支Pipeline

  • 单击添加源按钮,选择要使用的存储库的类型并填写详细信息。

  • 点击保存按钮并观看您的第一条Pipeline运行!

您可能需要修改一个示例Jenkinsfile以使其与您的项目一起运行。尝试修改sh命令以运行您在本地计算机上运行的相同命令。

设置你的Pipeline后,Jenkins将自动检测在存储库中创建的任何新分支或拉请求,并为其启动运行Pipeline。

继续“运行多个步骤” (https://www.w3cschool.cn/jenkins/jenkins-c7qs28n5.html)

快速启动示例

以下是一些简单的复制和粘贴的一个简单的流水线与各种语言的例子。

Java

enkinsfile (Declarative Pipeline)
pipeline {
    agent { docker 'maven:3.3.3' }
    stages {
        stage('build') {
            steps {
                sh 'mvn --version'
            }
        }
    }
}

Toggle Scripted Pipeline (Advanced)

Jenkinsfile (Scripted Pipeline)
/* Requires the Docker Pipeline plugin */
node('docker') {
    checkout scm
    stage('Build') {
        docker.image('maven:3.3.3').inside {
            sh 'mvn --version'
        }
    }
}

Node.js / JavaScript

Jenkinsfile (Declarative Pipeline)
pipeline {
    agent { docker 'node:6.3' }
    stages {
        stage('build') {
            steps {
                sh 'npm --version'
            }
        }
    }
}

Toggle Scripted Pipeline (Advanced)

Jenkinsfile (Scripted Pipeline)
/* Requires the Docker Pipeline plugin */
node('docker') {
    checkout scm
    stage('Build') {
        docker.image('node:6.3').inside {
            sh 'npm --version'
        }
    }
}

Ruby

Jenkinsfile (Declarative Pipeline)

pipeline {
    agent { docker 'ruby' }
    stages {
        stage('build') {
            steps {
                sh 'ruby --version'
            }
        }
    }
}

Toggle Scripted Pipeline (Advanced)

Jenkinsfile (Scripted Pipeline)
/* Requires the Docker Pipeline plugin */
node('docker') {
    checkout scm
    stage('Build') {
        docker.image('ruby').inside {
            sh 'ruby --version'
        }
    }
}

Python

Jenkinsfile (Declarative Pipeline)

pipeline {
    agent { docker 'python:3.5.1' }
    stages {
        stage('build') {
            steps {
                sh 'python --version'
            }
        }
    }
}

Toggle Scripted Pipeline (Advanced)

Jenkinsfile (Scripted Pipeline)
/* Requires the Docker Pipeline plugin */
node('docker') {
    checkout scm
    stage('Build') {
        docker.image('python:3.5.1').inside {
            sh 'python --version'
        }
    }
}

PHP

Jenkinsfile (Declarative Pipeline)

pipeline {
    agent { docker 'php' }
    stages {
        stage('build') {
            steps {
                sh 'php --version'
            }
        }
    }
}

Toggle Scripted Pipeline (Advanced)

Jenkinsfile (Scripted Pipeline)
/* Requires the Docker Pipeline plugin */
node('docker') {
    checkout scm
    stage('Build') {
        docker.image('php').inside {
            sh 'php --version'
        }
    }
}