Сервер сборки: лучшие практики по управлению сторонними компонентами? - PullRequest
10 голосов
/ 19 июня 2009

Я поддерживаю довольно большое устаревшее приложение. Исходное дерево - настоящий беспорядок. Я пытаюсь настроить сервер сборки.

В дереве исходников есть сторонний компонент с источниками (также в пути к проекту). Эти компоненты также установлены в среде IDE.

Мой вопрос: Как управлять этими компонентами?

Я думал, что справлюсь так:

  • Установка IDE на сервер сборки
  • Установить все сторонние компоненты
  • Удалите источники компонентов из дерева источников проекта (и сохраните их в корневом каталоге проекта в отдельной папке каждый раз в архиве)
  • Каждый раз, когда нам нужно настроить (или отладить) сторонний компонент, мы пересобираем пакет и переустанавливаем его в IDE сервера сборки (и на каждой рабочей станции разработчика)

В чем разница между установкой компонентов в IDE и наличием источников в пути включения? Как линкер справляется с этим делом?

Ответы [ 4 ]

22 голосов
/ 19 июня 2009

Мы настроили наши ежедневные сборки с использованием простых командных файлов.

  1. Каждый проект (.dpr) имеет связанный файл Build.cmd.
  2. Все файлы Build.cmd вызываются из нашего основного файла BuildServerRun.cmd.

Файл BuildServerRun.cmd позаботится о

  1. Удаление всего дерева исходных текстов на сервере сборки.
  2. Получение последней версии из нашего репозитория управления версиями.
  3. Вызовите каждый Build.cmd и передайте вывод в файл.
  4. Пошлите результаты всем разработчикам.

Все пути к внешним компонентам настраиваются в файле dcc32.cfg

..    
-u"c:\Program files\Developer Express Inc\ExpressInplaceEditors\Delphi 5\Lib"
-u"c:\Program files\Developer Express Inc\ExpressQuantumGrid\Delphi 5\Lib"
..
-r"c:\Program Files\Borland\Delphi5\Lib"
-r"C:\Program Files\jvcl\jvcl\resources"
..
-i"C:\Program Files\jvcl\jvcl\run"
-i"C:\Program Files\jvcl\jcl\source"

Пример Build.cmd.

Примечание: у нас есть политика для компиляции в bin \ dcu, exe в bin, отсюда и директивы -N, -E.

@echo on
dcc32speed -B -Q -W -H -Nbin\dcu -Ebin BpABA.dpr
@echo off

Пример фрагментированного BuildServerRun.cmd

SET %Drive%=E:

:BuildServer
REM *************************************************
REM     Clear files
REM *************************************************
ECHO. > "%Temp%\BuildLieven.txt"
ECHO. > "%Temp%\TestRunLieven.txt"

REM *************************************************
REM     Set start time
REM *************************************************
echo | TIME | FIND "Huidige tijd" > "%Temp%\ResultLieven.txt"

REM *************************************************
REM     Get latest versions
REM *************************************************
IF %LatestVersion%==1 CALL %Drive%\buildserver\latestversion.cmd
ECHO "Latest versions opgehaald" >> "%Temp%\ResultLieven.txt"

REM *************************************************
REM     Build projects
REM *************************************************
CD %Drive%\Projects\

ECHO ***************************************************************** >> "%Temp%\BuildLieven.txt"
ECHO BpABA >> "%Temp%\BuildLieven.txt"
ECHO ***************************************************************** >> "%Temp%\BuildLieven.txt"
CD %Drive%\Projects\BPABA\production
ECHO Building BPABA\production
CALL Build.cmd >> "%Temp%\BuildLieven.txt"
CD %Drive%\Projects\BPABA\test
ECHO Building BPABA\test
CALL Build.cmd >> "%Temp%\BuildLieven.txt"
CD %Drive%\Projects\BPABA\test\dunit
ECHO Building BPABA\test\dunit
CALL Build.cmd >> "%Temp%\BuildLieven.txt"
ECHO BPABATests >> "%Temp%\TestRunLieven.txt"
ECHO Running BPABATests
CALL bin\BPABATests >> "%Temp%\TestRunLieven.txt"
CD %Drive%\Projects
ECHO. >> "%Temp%\BuildLieven.txt"
ECHO. >> "%Temp%\BuildLieven.txt"
ECHO. >> "%Temp%\BuildLieven.txt"

REM *****************************************************************
REM     Gather (Fatal)Errors/Hints/Warnings & Failures
REM *****************************************************************
ECHO ***************************************************************** >> "%Temp%\ResultLieven.txt"
ECHO (Fatal)Errors/Hints/Warnings en Failures >> "%Temp%\ResultLieven.txt"
ECHO ***************************************************************** >> "%Temp%\ResultLieven.txt"
ECHO Fatal errors during build >> "%Temp%\ResultLieven.txt"
TYPE "%Temp%\BuildLieven.txt" | FIND /c "Fatal:" >> "%Temp%\ResultLieven.txt"


ECHO Errors during build >> "%Temp%\ResultLieven.txt"
TYPE "%Temp%\BuildLieven.txt" | FIND /c "Error:" >> "%Temp%\ResultLieven.txt"

ECHO Warnings during build >> "%Temp%\ResultLieven.txt"
TYPE "%Temp%\BuildLieven.txt" | FIND /c "Warning:" >> "%Temp%\ResultLieven.txt"

ECHO Hints during build >> "%Temp%\ResultLieven.txt"
TYPE "%Temp%\BuildLieven.txt" | FIND /c "Hint:" >> "%Temp%\ResultLieven.txt"

ECHO Failures during test >> "%Temp%\ResultLieven.txt"
TYPE "%Temp%\TestRunLieven.txt" | FIND /c "Failures:" >> "%Temp%\ResultLieven.txt"
ECHO. >> "%Temp%\ResultLieven.txt"

ECHO ***************************************************************** >> "%Temp%\ResultLieven.txt"
ECHO Controle #Projecten = #Compiles >> "%Temp%\ResultLieven.txt"
ECHO ***************************************************************** >> "%Temp%\ResultLieven.txt"
ECHO #Projecten >> "%Temp%\ResultLieven.txt"
TYPE "%Drive%\buildserver\buildserverrun.cmd" | FIND /i "cmd >> " | FIND /i "Lieven" | FIND /i /v /c "FIND /i /v /c" >> "%Temp%\ResultLieven.txt"
ECHO #Compiles >> "%Temp%\ResultLieven.txt"
TYPE "%Temp%\buildLieven.txt" | FIND /i /c "dcc32" >> "%Temp%\ResultLieven.txt"
ECHO #Tests expected to run >> "%Temp%\ResultLieven.txt"
TYPE "%Drive%\buildserver\buildserverrun.cmd" | FIND /i "TestRunLieven" | FIND /i "CALL" | FIND /i /v /c "FIND /i /v /c" >> "%Temp%\ResultLieven.txt"
ECHO #Tests actually run >> "%Temp%\ResultLieven.txt"
TYPE "%Temp%\TestRunLieven.txt" | FIND /i /c "DUnit / Testing" >> "%Temp%\ResultLieven.txt"
ECHO. >> "%Temp%\ResultLieven.txt"
ECHO. >> "%Temp%\ResultLieven.txt"

ECHO ***************************************************************** >> "%Temp%\ResultLieven.txt"
ECHO Detail (Fatal)Errors/Hints/Warnings en Failures >> "%Temp%\ResultLieven.txt"
ECHO ***************************************************************** >> "%Temp%\ResultLieven.txt"
TYPE "%Temp%\BuildLieven.txt" | FIND "Fatal:" >> "%Temp%\ResultLieven.txt"
TYPE "%Temp%\BuildLieven.txt" | FIND "Error:" >> "%Temp%\ResultLieven.txt"
TYPE "%Temp%\BuildLieven.txt" | FIND "Warning:" >> "%Temp%\ResultLieven.txt"
TYPE "%Temp%\BuildLieven.txt" | FIND "Hint:" >> "%Temp%\ResultLieven.txt"
TYPE "%Temp%\TestRunLieven.txt" | FIND "Failures:" >> "%Temp%\ResultLieven.txt"

REM *************************************************
REM     Set stop time
REM *************************************************
ECHO | TIME | FIND "Huidige tijd" >> "%Temp%\ResultLieven.txt"

REM *************************************************
REM     Send results
REM *************************************************
CALL %drive%\buildserver\Blat.cmd
3 голосов
/ 19 июня 2009

Мой ответ более общий, чем ответ Ливена, специфичный для Delphi. Я написал это вскоре после вопроса, но перед отправкой отправился к сотруднику;)

Я отказываюсь устанавливать любую IDE на наш основной агент сборки Windows. Звучит как кошмар для меня. Движок MSBuild хорошо справляется со всеми сценариями сборки, и, кроме .NET, вам просто нужно установить Windows SDK. Или вы можете использовать NAnt и даже CMake, что угодно. Просто не устанавливайте IDE. На сборочных серверах не весело.

Теперь вы отметили это как Delphi. Я не знаю, насколько хорошо он там работает, но, как написал Ливен, Delphi поставляется с компилятором командной строки. У меня просто нет опыта работы со сторонними компонентами, но я думаю, что Delphi поддерживает MSBuild в последней версии.

Я также не уверен, является ли полезным включение сторонних компонентов в управление версиями из-за занимаемого им места - хотя вы также можете поместить их в другое место и включить их как внешние, что делает его намного меньше, но Кроме того, возникает проблема, заключающаяся в том, что при обновлении компонентов для одного приложения они будут обновляться для всех - поэтому вам лучше пройти хорошие интеграционные тесты. Но в этом и заключается смысл сервера сборки.

Кроме того, всегда полезно оформить заказ и иметь все компоненты, необходимые для создания приложения. Вам не нужно устанавливать компоненты в IDE, если они были сделаны хорошо. В зависимости от того, какие это компоненты, во многих случаях вам даже не нужно устанавливать их на машины разработчика. Например, многие компоненты .NET доступны в конструкторе, когда вы добавляете на них ссылку. И лицензирование обычно не более, чем «поместите файл лицензии в тот же каталог». Ну, так и должно быть, по крайней мере. Если это не так, как сегодня работает в Delphi, это, вероятно, одна из причин, по которой Delphi выходит. Кроме хлопот Borland / Inprise / DevCo / Codegear / Embarcadero.

1 голос
/ 19 июня 2009

Подобная ситуация здесь, к счастью, это не началось с большого беспорядка. Это правда, что настоящая проблема заключается в конфигурации IDE, которая должна указывать на правильные версии сторонних компонентов, если вы проверяете более старую версию. Единственное решение, о котором я слышал, - это использование разных веток реестра для разных конфигураций выпуска продукта.

Компоненты хранятся в отдельной структуре каталогов и по возможности используют номера версий в именах каталогов. Это облегчает извлечение старых версий и позволяет сценариям сборки указывать правильную версию.

Мы используем Apache Ant в качестве основного инструмента сборки уже много лет, и он действительно делает все, что нам нужно, включая вызов модульного теста и генерацию скрипта Innosetup.

Компиляция пакетов необходима только в том случае, если вы отправляете исполняемый файл с BPL, иначе это не нужно на сервере сборки.

Установка компонентов в IDE также не требуется на сервере сборки.

0 голосов
/ 17 мая 2013

Вы можете использовать Owly CI tool.

Позволяет легко создавать проекты, определяя файл манифеста. Он также позволяет обрабатывать зависимости - вы можете обернуть сторонние компоненты в пакеты owlyci и пометить их как зависимости от основного проекта.

Существует пример , как использовать его с системой Jenkins CI.

...