Jenkins Multi Branch使用Gerrit Trigger

时间:2017-07-10 14:21:27

标签: jenkins jenkins-pipeline gerrit-trigger multibranch-pipeline

一点背景......

我们一直使用Gerrit + Jenkins超过一年,取得了巨大的成功。添加代码审查和构建验证使我们的开发人员对他们提交到源代码的内容更加负责。我们的项目开始时,我为我的团队设置了两者之间的集成。

现在,我希望能够为利用Gerrit进行代码审查的库进行多分支构建。一旦CR通过验证的构建并且更改使其成为源,我希望发生分发构建(Gerrit触发器可以监听此事件)。

简单示例

我写了一个详细而具体的例子,说明了我在下一节中要做的事情

为了便于沟通我尝试做的事情,我将参考项目A和图书馆B.两者都在Gerrit中进行CR和构建验证。这为我们正在分发的每个分支提供了2个Gerrit触发的构建和夜间构建。

图书馆B由项目A(通过凉亭)消耗。当用户向库项目提交更改时,Gerrit触发器会选择此更改并且Jenkins构建更改。一旦检查并提交了更改,就会手动启动dist构建。然后,此构建更新包中的dist。这将在项目A的下一个版本中(或当用户手动更新bower时)获取。

更详细的例子

我们创建了一个库,这是一组可用的常用样式和JavaScript,可以在我们组织的不同Web应用程序项目中使用。我们试图最好地创建库,就像许多人熟悉的bower.io包一样(我们的模仿Bootstrap)。库的git分支布局旨在模仿gitflow; develop 分支始终是下一个版本等。

该库有一个src/文件夹,其中包含所有基本代码等。bower.json文件指向dist/文件夹,其中包含已编译,缩小等文件。通过这种设置,我们在Web应用程序中使用了包。

使用Gerrit,我们会审核来自此项目的团队提交的所有内容。这很容易。带有Gerrit-Trigger的Jenkins会收到有关新更改的通知并构建补丁集。我们告诉开发人员不要在dist/文件夹中提交更改,因为它会导致合并噩梦,但是文件存在,因此库的每个使用者都不必进行编译输出。

在这一点上,希望对我们正在做的事情有一个很好的高层次观点。现在解释这个问题可能更容易。

当我们为主要网络应用程序的QA团队进行日常构建时,我们会bower install。在我们的bower.json文件中,我们指向#develop引用。这意味着Web应用程序将使用库dist/文件夹中的最新内容。如果在为Web应用程序进行每日QA构建之前尚未完成对更新dist/文件夹的库的提交,那么该库将无法在该构建中进行更新。

这让QA感到悲伤。他们向开发人员发送一封电子邮件,其中关闭的票据实际上已准备好进行测试。这让我感到不安,因为我反过来收到开发人员发来的一封电子邮件,询问WTF。

我想要发生什么

  1. 为每个项目定义一个多分支管道构建,以便每个分支不需要自己的每日/每晚构建作业。
  2. 对于库作业,除了用于夜间构建的管道之外,每当将补丁集提交给源代码时,它也会启动。
  3. 特别是关于第2点和上面的详细示例:我希望在没有开发人员互动的情况下以及当潜在客户提交已批准的补丁集来源时,以受控方式自动更新dist/文件夹。< / em>的

    对于第1点,关于这个问题,我并不是在为项目A构建管道构建方面寻求帮助。

    问题

    我为库项目创建了一个多分支管道。在其中我想拉动源:

    try {
      stage('Checkout') {
        // Grab the source to build
        checkout scm
      }
    }
    catch (err) {
      currentBuild.result = "FAILURE"
    
      emailext body: "The Library build has failed. The source for the build was unable to be pulled from Gerrit. Please view the build information here: ${env.BUILD_URL}",
      from: 'Jenkins CI Server <jenkins-no-reply@example.com>',
      subject: 'Git Pull Issue With foundation-controls',
      to: 'Mike@example.com'
    
      throw err;
    }
    

    这个有效!但是,它只是为分支机构提供最新信息。它没有定义构建何时发生。我开启了SCM民意调查。

    构建完成后,我有一个步骤:

    stage('Publish') {
      if (env.BRANCH_NAME == "master" || env.BRANCH_NAME == "develop" || env.BRANCH_NAME.startsWith("release/") || env.BRANCH_NAME.startsWith('hotfix/')) {
    
        sh 'git add dist'
        def gitDiffStatusCode = sh script: 'git diff --cached --exit-code', returnStatus: true
    
        if (gitDiffStatusCode != 0)  {
          sh 'git commit -m "chore(release): Internal release"'
          sshagent(['xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx']) {
            sh "git push --force-with-lease origin HEAD:${env.BRANCH_NAME}"
          }
        } else {
          echo 'Nothing to commit';
          sendEmail = false
        }
      }
      else if (env.BRANCH_NAME.startsWith('feature/')) {
        echo "On A feature branch. Not publishing!"
        sendEmail = false
      }
      else {
        echo "Skipping publish - This build is not ocurring on a publish-able branch!"
        sendEmail = false
      }
    }
    

    这里的问题是push会导致轮询触发并进入无限循环。

    我想要做的是使用Gerrit-Trigger的功能在合并更改/补丁时发起构建(提交已发生)。而不是自由形式的作业,我希望它是一个管道构建,以便它使用Jenkins文件。

    如何让这个工作,以便Gerrit触发器告诉你何时进行构建?

    其他解决方法尝试

    我确实提出了一种跳过构建的方法。它涉及在构建运行时查看最后一次提交消息。然后我可以跳过管道中的所有其他步骤。这只意味着总会有两个构建,一个包含所有管道步骤,然后一个只包含&#34; Checkout&#34;阶段。不理想。

1 个答案:

答案 0 :(得分:0)

我认为你正在创建一个经典的无限事件循环。 但问题如下。

我可能错了,但您使用git作为源代码控制和工件存储库,即您正在添加可能已构建的Python包并将其推送到同一存储库。

这意味着你至少必须推送到你忽略的特殊分支。

我认为流程应该是: 1.在测试特定构建之后,您应该使用标记来标记提交。 2.单独的工作将对添加的正则表达式匹配标签做出反应并构建一个包。如果您需要了解互联网是如何充满他们的话,另一个步骤就是将软件包推入Kosher pypi索引

因此,问题就在于我对您使用Gerrit + CI的方式的拙见,

我最初担心你真的需要做那些git push操作,但你不是。

所以你最后的行动项目是:

决定是否要

  • 补丁临时解决方案(单独分支)

  • 真正的解决方案:将您的软件包放入pypi兼容服务器

在任何一种情况下,你都有几个groovy文件。