2011-03-28 47 views
2

我管理一个CI-服务器一堆我公司的项目,在CruiseControl.NET 1.6.7981.1运行。这些项目在逻辑上构成了“产品”,但彼此之间(至少部分)是相互独立的。作为比较,MS Office是一个由独立项目“Word”,“Excel”等组成的“产品”。每晚“发布构建”在CruiseControl.NET

每个项目都有自己的ccnet-project,每当更改提交给源代码控制通过IntervalTrigger)。这工作正常。

产品本身由不同的“子”工程的输出以及附加的静态数据(位图,样本数据,...)的。为此,我有一个单独的“发布”ccnet项目,它执行这些步骤,然后将数据复制到网络上的新输出文件夹。这个“发布”也很好。每次运行时,都会创建一个新文件夹;目前每个文件夹是大约。 1GB大小。

我有两个附加要求:

  1. 由于“发布”产生如此巨大的数据量,我想在夜间运行它(除非有人手动触发它)。我们实际上有两个版本的产品和所有在CI服务器上运行的子项目(dev和last-release)。最后一个版本只能获得补丁,所以可能会有几天的时间在子项目中没有做任何事情。所以“发布”应该只在一个子项目被修改的情况下运行。
  2. 有人可能会破坏其中一个子项目的构建。在修复之前,不应运行父项“发布”项目。

我试图解决它不能正常工作,但是,该方式。我目前的ccnet.config看起来差不多。如下(相关部分只):

<project name="Child 1 dev" queue="dev" queuePriority="1"> 
    <!-- Build the project --> 
    <publishers> 
     <!-- Logger, statistics, ... --> 
     <conditional> 
      <conditions> 
       <statusCondition value="Success" /> 
       <lastStatusCondition value="Failure" /> 
      </conditions> 
      <tasks> 
       <cruiseServerControl> 
        <actions> 
         <controlAction type="StartProject" project="Publish dev" /> 
        </actions> 
       </cruiseServerControl> 
      </tasks> 
     </conditional> 
     <conditional> 
      <conditions> 
       <statusCondition value="Failure" /> 
      </conditions> 
      <tasks> 
       <cruiseServerControl> 
        <actions> 
         <controlAction type="StopProject" project="Publish dev" /> 
        </actions> 
       </cruiseServerControl> 
      </tasks> 
     </conditional> 
    </publishers> 
</project> 

<!-- Additional "child" projects as above --> 

<project name="Publish dev" queue="dev" queuePriority="10"> 
    <triggers> 
     <multiTrigger operator="And"> 
      <triggers> 
       <multiTrigger operator="Or"> 
        <triggers> 
         <projectTrigger project="Child 1" /> 
         <projectTrigger project="Child 2" /> 
         <projectTrigger project="Child 3" /> 
        </triggers> 
       </multiTrigger> 
       <scheduleTrigger buildCondition="ForceBuild" time="23:30" /> 
      </triggers> 
     </multiTrigger> 
    </triggers> 
    <!-- Do the publishing, a bunch of exec tasks. --> 
</project> 

的问题:

  1. 如果没有在子项目做了好几天了,那么没有“发布”运行。之后,只要儿童项目发生变化,“发布”就会运行。我猜测ScheduleTrigger保持触发。我尝试在FilterTrigger中包装ScheduleTrigger,但有时候根本没有构建。
  2. 如果子项目的构建失败,则发布项目将停止。但是,构建成功后再次启动项目通常不起作用。

因此,在短期,我猜的解决方案将用于“发布dev的”触发一组触发器:

  1. 每天晚上23:30(例如)。
  2. 自上次“发布开发”以来,任何子项目已成功构建。
  3. 而且没有孩子的项目是在构建失败的状态(即所有的子项目都是一个成功的建造状态)。

如果#2或#3错了,下一张支票应该只是第二天晚上。

编辑:

东西肯定不对的lastStatusCondition。我有以下的输出:

构建失败:

2011-04-01 10:14:06,105 [Child 1 dev] [DEBUG] - Checking conditions 
2011-04-01 10:14:06,105 [Child 1 dev] [DEBUG] - Checking status - matching to Success 
2011-04-01 10:14:06,105 [Child 1 dev] [INFO] - Conditions did not pass - running else tasks 
2011-04-01 10:14:06,105 [Child 1 dev] [INFO] - Tasks completed: 0 successful, 0 failed 
2011-04-01 10:14:06,105 [Child 1 dev] [DEBUG] - Checking conditions 
2011-04-01 10:14:06,105 [Child 1 dev] [DEBUG] - Checking status - matching to Failure 
2011-04-01 10:14:06,121 [Child 1 dev] [INFO] - Conditions passed - running tasks 

所以一切工作正常。然后我马上又盖了,与构建固定:

2011-04-01 10:18:36,078 [Child 1 dev] [DEBUG] - Checking conditions 
2011-04-01 10:18:36,078 [Child 1 dev] [DEBUG] - Checking status - matching to Success 
2011-04-01 10:18:36,078 [Child 1 dev] [DEBUG] - Checking last build status - matching to Failure 
2011-04-01 10:18:36,078 [Child 1 dev] [INFO] - Conditions did not pass - running else tasks 
2011-04-01 10:18:36,093 [Child 1 dev] [INFO] - Tasks completed: 0 successful, 0 failed 
2011-04-01 10:18:36,093 [Child 1 dev] [DEBUG] - Checking conditions 
2011-04-01 10:18:36,093 [Child 1 dev] [DEBUG] - Checking status - matching to Failure 
2011-04-01 10:18:36,093 [Child 1 dev] [INFO] - Conditions did not pass - running else tasks 
2011-04-01 10:18:36,093 [Child 1 dev] [INFO] - Tasks completed: 0 successful, 0 failed 

因此,尽管已经失败以前的版本(你可以从匹配的第一个日志看到失败),当前的以前的版本状态属性(成功)建立显然不是失败!我想我必须提交一个针对ccnet的bug ...

回答

1

看看我的博客,我在那里提供了一个解决方案。评论赞赏:

http://rubenwillems.blogspot.com/2011/04/tuning-ccnet-to-your-whishes-new.html

+0

非常感谢!我必须测试它是否按计划运作。小修改:在'SubProjectsAreChanged()'中,如果在此期间建立了子项目,则立即返回true。但是,尚未检查的子项目可能处于失败状态。在本地我改变它将它保存到一个临时变量并在最后返回它。 – 2011-04-05 09:37:02

1

对于你的第一个问题,我的想法和你的一样:我认为计划触发器会一直触发并等待多个“OR触发器”被触发。请注意,在反转角色时需要此行为:当您成功构建子项目时,您希望等到第二个触发器触发(23:30)。

一对夫妇的想法,以满足您的需求将是:

  • 添加< triggerStatus>成功</triggerStatus>项目信息触发器(防止例外)
  • 设置项目触发器的innerTrigger到一个时间表触发器而不是默认的间隔触发器。时间表触发设置开火23:30应该解决您的问题

至于你的第二个问题,我不知道为什么这个项目会不会重启,sowwy。

我personnaly设法处理这些产品问题与Enterprise Continuous Integration,我们用了近一年,这是很大的安心。

+0

对于第二个问题,我的猜测是,也许lastStatusCondition不能正常每个项目的工作,而是“全球”。因此,如果另一个项目在此期间成功运行,则最后一个状态将设置为成功,即使项目的最后一个状态应该继续为“失败”。 – 2011-03-29 16:55:15

+0

使用项目触发器时有一个问题:第一次触发内部触发器时,它没有以前的状态作为比较。所以它不知道该怎么做。这对于默认间隔触发器没有问题(因为它每5秒触发一次)。但这意味着对于计划触发器,在服务器重启后,我们要么等待另外一天,要么总是触发(即使它不是必需的)。 – 2011-04-01 07:00:55