在CruiseControl.NET中每晚“发布版本”

时间:2011-03-28 12:21:51

标签: continuous-integration cruisecontrol.net

我为我公司的一系列项目管理CI服务器,在CruiseControl.NET 1.6.7981.1下运行。这些项目在逻辑上形成“产品”,但是(至少部分地)彼此独立。相比之下,MS Office是一个“产品”,由独立项目“Word”,“Excel”等组成。

每个项目都有自己的ccnet项目,只要将更改提交给源代码控制(通过IntervalTrigger),就可以构建。这很好。

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

我还有两个要求:

  1. 由于“发布”会生成如此大量的数据,我想每晚运行它(除非有人手动触发它)。实际上,我们有两个版本的产品和所有在CI服务器上运行的子项目(dev和last-release)。最后一个版本只获取补丁,因此可能有几天没有在子项目中完成任何操作。因此,只有在修改了子项目时才能运行“发布”。
  2. 有人可能会破坏其中一个子项目的构建。在修复之前,不应运行父“发布”项目。
  3. 然而,我试图解决它的方式无法正常工作。我目前的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. 如果子项目的构建失败,则停止发布项目。但是,在构建成功后再次启动项目通常不起作用。
    3. 所以简而言之,我想解决方案会为“发布开发”触发一组触发器:

      1. 每晚23:30(例如)。
      2. 自上次“发布开发”以来成功构建任何子项目时。
      3. 并且没有子项目处于构建失败状态(即所有子项目都处于成功构建状态)。
      4. 如果#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的错误...

2 个答案:

答案 0 :(得分:1)

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

符合您要求的几个想法是:

  • 添加&lt; triggerStatus&gt; Success&lt; / triggerStatus&gt;项目触发器(防止例外)
  • 将项目触发器的innerTrigger设置为计划触发器而不是默认间隔触发器。设置为在23:30开火的计划触发器应解决您的问题

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

我个人设法用Enterprise Continuous Integration来处理这些产品问题,我们使用它差不多一年了,这是非常宽慰。

答案 1 :(得分:1)

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

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