Jenkins管道中的Maven生命周期-如何最好地分离职责?

Pow*_*tat 7 maven-3 maven jenkins maven-lifecycle jenkins-pipeline

在使用jenkins 2(声明性)管道和Maven时,我始终对如何组织管道中的事物以使其可重用和灵活存在问题。

一方面,我想将管道分成逻辑阶段,例如:

pipeline
 {
  stages
   {
    stage('Clean') {}
    stage('Build') {}
    stage('Test') {}
    stage('Sanity check') {}
    stage('Documentation') {}
    stage('Deploy - Test') {}
    stage('Selenium tests') {}
    stage('Deploy - Production') {}
    stage('Deliver') {}
   }
 }
Run Code Online (Sandbox Code Playgroud)

另一方面,我有与

mvn clean deploy site
Run Code Online (Sandbox Code Playgroud)

我可以简单地将Maven拆分为

mvn clean
mvn deploy
mvn site
Run Code Online (Sandbox Code Playgroud)

但是,“部署”包括以下所有生命周期阶段

  • 验证
  • 编译
  • 测试
  • 校验
  • 安装
  • 部署

所以我看了很多例子,例如

sh 'mvn clean compile'
Run Code Online (Sandbox Code Playgroud)

sh 'mvn test'
Run Code Online (Sandbox Code Playgroud)

这导致第二次重复验证和编译步骤,并以此方式浪费“时间/资源”。这可以通过做一个解决

sh 'mvn surefire:test'
Run Code Online (Sandbox Code Playgroud)

而不是再次运行整个生命周期。

所以我的问题是-在詹金斯油耗阶段和Maven生命周期之间取得最佳平衡的最佳方法是什么?对我来说,我看到两种方式:

  1. 将Maven生命周期划分为尽可能多的流水线阶段-这将产生更好的詹金斯用户反馈(请参阅哪个阶段失败等)。
  2. 让maven做所有事情,只使用jenkins管道处理maven的结果(即分析单元测试结果等)。

还是我误解了CI / CD实践中的某些内容?

Pow*_*tat 6

两个月后,我想我有一个平衡良好的 Jenkins 管道脚本,它不完整,但在 windows 和 linux 上运行稳定。它避免了我见过的其他例子的陷阱。

詹金斯档案

pipeline
 {
  agent any

  tools
   {
    maven 'Maven3'
    jdk 'JDK8'
   }

  options
   {
    buildDiscarder(logRotator(numToKeepStr: '4'))
    skipStagesAfterUnstable()
    disableConcurrentBuilds()
   }


  triggers
   {
    // MINUTE HOUR DOM MONTH DOW
    pollSCM('H 6-18/4 * * 1-5')
   }


  stages
   {
    stage('Clean')
     {
      steps
       {
        script
         {
          if (isUnix()) 
           {
            sh 'mvn --batch-mode clean'
           }
          else
           {
            bat 'mvn --batch-mode clean'
           }
         }
       }
     }

    stage('Build')
     {
      steps
       {
        script
         {
          if (isUnix()) 
           {
            sh 'mvn --batch-mode compile'
           }
          else
           {
            bat 'mvn --batch-mode compile'
           }
         }
       }
     }

    stage('UnitTests')
     {
      steps
       {
        script
         {
          if (isUnix()) 
           {
            sh 'mvn --batch-mode resources:testResources compiler:testCompile surefire:test'
           }
          else
           {
            bat 'mvn --batch-mode resources:testResources compiler:testCompile surefire:test'
           }
         }
       }
      post
       {
        always
         {
          junit testResults: 'target/surefire-reports/*.xml'
         }
       }
     }

    stage('Sanity check')
     {
      steps
       {
        script
         {
          if (isUnix()) 
           {
            sh 'mvn --batch-mode checkstyle:checkstyle pmd:pmd pmd:cpd com.github.spotbugs:spotbugs-maven-plugin:spotbugs'
           }
          else
           {
            bat 'mvn --batch-mode checkstyle:checkstyle pmd:pmd pmd:cpd com.github.spotbugs:spotbugs-maven-plugin:spotbugs'
           }
         }
       }
     }

    stage('Packaging')
     {
      steps
       {
        script
         {
          if (isUnix()) 
           {
            sh 'mvn --batch-mode jar:jar'
           }
          else
           {
            bat 'mvn --batch-mode jar:jar'
           }
         }
       }
     }

    stage('install local')
     {
      steps
       {
        script
         {
          if (isUnix()) 
           {
            sh 'mvn --batch-mode jar:jar source:jar install:install'
           }
          else
           {
            bat 'mvn --batch-mode jar:jar source:jar install:install' // maven-jar-plugin falseCreation default is false, so no doubled jar construction here, but required for maven-install-plugin internal data
           }
         }
       }
     }

    stage('Documentation')
     {
      steps
       {
        script
         {
          if (isUnix()) 
           {
            sh 'mvn --batch-mode site'
           }
          else
           {
            bat 'mvn --batch-mode site'
           }
         }
       }
      post
       {
        always
         {
          publishHTML(target: [reportName: 'Site', reportDir: 'target/site', reportFiles: 'index.html', keepAll: false])
         }
       }
     }

    stage('Deploy test')
     {
      steps
       {      
        script
         {
          if (isUnix()) 
           {
            // todo
           }
          else
           {
            bat returnStatus: true, script: 'sc stop Tomcat8'
            sleep(time:30, unit:"SECONDS")
            bat returnStatus: true, script: 'C:\\scripts\\clean.bat'
            bat returnStatus: true, script: 'robocopy "target" "C:\\Program Files\\Apache Software Foundation\\Tomcat 9.0\\webapps" Test.war'
            bat 'sc start Tomcat8'
            sleep(time:30, unit:"SECONDS")
           }
         }
       }
     }

    stage('Integration tests')
     {
      steps
       {
        script
         {
          if (isUnix()) 
           {
            sh 'mvn --batch-mode failsafe:integration-test failsafe:verify'
           }
          else
           {
            bat 'mvn --batch-mode failsafe:integration-test failsafe:verify'
           }
         }
       }
     }

   }

 }
Run Code Online (Sandbox Code Playgroud)

希望这对外面的其他开发人员很有趣。

随着时间的推移,当我对其进行显着改进时,我将在此处更新。

对于那些还希望看到 Jenkinsfile 和 Maven pom 的人,请查看我在 github 上的小示例项目:TemplateEngine