Я управляю CI-сервером для нескольких проектов моей компании, работающих под управлением CruiseControl.NET 1.6.7981.1.Проекты логически образуют «продукт», но (хотя бы частично) независимы друг от друга.Для сравнения, MS Office - это «продукт», состоящий из независимых проектов «Word», «Excel» и т. Д.
Каждый проект имеет свой собственный ccnet-проект, который создается при каждом изменении в исходном коде.управление (через IntervalTrigger).Это прекрасно работает.
Сам продукт состоит из вывода различных «дочерних» проектов, а также дополнительных статических данных (растровые изображения, примеры данных, ...).Для этого у меня есть отдельный «опубликовать» ccnet-проект, который выполняет эти шаги, а затем копирует данные в новую папку вывода в сети.Эта «публикация» тоже отлично работает.Каждый раз, когда он запускается, создается новая папка;в настоящее время каждая папка ок.1 ГБ в размере.
У меня есть два дополнительных требования:
- Поскольку «публикация» генерирует такие огромные объемы данных, я хочу запускать их каждую ночь (если кто-то не запускает их вручную).На самом деле у нас есть две версии продукта и все дочерние проекты, работающие на CI-сервере (dev и last-release).Последний релиз получает только патчи, поэтому может быть несколько дней, когда ничего не было сделано в дочерних проектах.Поэтому «публикация» должна выполняться, только если дочерний проект был изменен.
- Кто-то может нарушить сборку одного из дочерних проектов.До тех пор, пока он не будет исправлен, родительский проект «Публикация» не должен запускаться.
Однако способ, которым я пытался его решить, работает неправильно.Мой текущий 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>
Проблемы:
- Если в дочерних проектах ничего не делается в течение нескольких дней, «публикация» не выполняется.После этого, как только что-то меняется в дочерних проектах, запускается «публикация».Я предполагаю, что ScheduleTrigger остается запущенным.Я попытался обернуть ScheduleTrigger в FilterTrigger, но иногда сборка вообще не выполнялась.
- Если сборка дочернего проекта завершается неудачно, проект публикации останавливается.Однако повторный запуск проекта после успешного завершения сборки часто не работает.
Короче говоря, я полагаю, что решением будет набор триггеров для "публикации dev", который вызывает:
- Каждую ночь в 23:30 (например).
- Когда какой-либо дочерний проект был успешно построен с момента предыдущего "publish dev".
- И ни один дочерний проект нев состоянии сбоя сборки (т. е. все дочерние проекты находятся в состоянии успешной сборки).
Если # 2 или # 3 неверны, следующая проверка должна быть только следующей ночью.
РЕДАКТИРОВАТЬ:
Что-то определенно не так с условием lastStatus.У меня есть следующие выходные данные:
Ошибка сборки:
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 ...