підтримка зростаючої, різноманітної бази даних з постійною інтеграцією


10

Мені потрібна допомога у філософії та розробці безперервної інтеграції.

У нашій теперішній програмі CI використовується buildbot. Коли я почав його проектувати, я успадкував (ну, не суворо, оскільки я брав участь у його розробці роком раніше) замовника будівельника CI, який був розроблений, щоб одразу впродовж ночі запустити всю збірку. Через деякий час ми вирішили, що це недостатньо, і почали досліджувати різні рамки CI, врешті вибравши buildbot. Однією з моїх цілей переходу на buildbot (окрім того, щоб насолодитися всіма вигодами вибуху) було подолати деякі недоліки нашого нічного будівельника.

Намотуйте мене на мить, і дозвольте мені пояснити, що я отримав у спадок. База даних коду для моєї компанії - це майже 150 унікальних програм для Windows + c ++, кожен з яких має залежність від однієї чи декількох десятків внутрішніх бібліотек (і багатьох - від сторонніх бібліотек). Деякі з цих бібліотек взаємозалежні і мають залежні програми, які (хоча вони не мають нічого спільного) повинні бути побудовані з такою ж збіркою цієї бібліотеки. Половина цих додатків і бібліотек вважаються "застарілими" і нерепортажними, і вони повинні бути побудовані з декількома різними конфігураціями компілятора IBM (для яких я написав унікальні підкласи Compile), а інша половина створена за допомогою візуальної студії.ShellCommands, оскільки немає підтримки для VSS).

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

Я спочатку це робив - створити записи для кожної програми, яку ми хотіли створити (усі 150 в них), потім створити запущені планувальники, які могли б створювати різні програми як групи, а потім підписати ці групи під загальний планувальник нічних збірок. Вони могли працювати на спеціальних рабах (більше немає віртуальних машинних шикарних виробів), і якщо я хотів, я міг просто додати нових рабів. Тепер, якщо ми хочемо зробити повний збір за графіком, це одним клацанням миші, але ми також можемо створити лише одну програму, якщо так хочемо.

Однак у цього підходу є чотири слабкі сторони. Одне - це комплексне джерело залежностей нашого дерева. Щоб спростити підтримку конфігурації, усі будівельники створюються з великого словника. Залежності витягуються та будуються не надто міцно (а саме, відмикання певних речей у моєму словнику збірки-цілі). Друга полягає в тому, що кожна збірка має від 15 до 21 етапів збирання, які важко переглядати та дивитись у веб-інтерфейсі, а оскільки налічується близько 150 стовпців, для завантаження потрібно вічно (подумайте від 30 секунд до декількох хвилин). По-третє, у нас більше немає автоматичного розкриття цілей побудови (хоча, наскільки хтось із моїх колег з цього приводу сприймає, я в першу чергу не бачу, що це спричинило нас). Нарешті,

Тепер, переходячи до нової розробки, ми починаємо використовувати g ++ та підривну діяльність (не переносячи старе сховище, пам’ятайте - лише для нового матеріалу). Крім того, ми починаємо проводити більше тестування одиниць ("більше" може дати неправильну картину ... це більше як будь-яке ) та інтеграційне тестування (використовуючи python). Мені важко зрозуміти, як їх вписати в існуючу конфігурацію.

Отже, де я тут помилився по-філософськи? Як я можу найкраще рухатись вперед (за допомогою buildbot - це єдиний фрагмент головоломки, на який я маю ліцензію на роботу), щоб моя конфігурація була фактично підтриманою? Як вирішити деякі недоліки дизайну? Що реально працює з точки зору стратегій CI для великих (можливо, завищених) складних баз кодів?

Редагувати:

Я думав, що пояснив свою проблему, але очевидно, що я був недостатньо зрозумілий. Я не шукаю пропозицій щодо зміни платформ CI. Це не відбудеться, і відповіді, що підказують, що не будуть прийняті. Що я хочу знати - це те, як інші люди керують складними базами кодів за допомогою CI. У мене є десяток різних продуктів, і у мене залежність, розсіяна на вітрі, і всі вони різні. ЦЕ Я хочу знати, як боротися.


Я теж хотів би знати відповідь на це. Наше середовище не таке складне, як ваше, але у нас залежність залежностей (у випадку проекту інсталяції він має глибину в чотири шари). Я не знаю, чи повинен кожен проект бути проектом CI, чи потрібно просто використовувати файл Visual Studio .sln, щоб подбати про нього, щоб мені не довелося заново створювати дерево залежності для кожного проекту (та майбутній проект).
moswald

Неможливість побудови на локальній машині робить вашу місію сервера CI важливою для вашого бізнесу. Ви можете переосмислити це.
Thorbjørn Ravn Andersen

Відповіді:


3

Хоча я не стикався з ситуацією такої поганої, як ви описуєте, я підтримував конфігурацію CI з десятками компонентів, між якими є деякі "прості" залежності. Я сподіваюся, що мій підхід може дати вам підказки, з якими слід діяти. Проблема, безумовно, не пов'язана лише з вибором сервера CI, а й із загальним процесом збирання та структурою проекту.

Я розбив цю проблему на 2 частини: Будівництво та ІС.

Будівництво

Під "будівництвом" я маю на увазі процес, змінюючи вихідний код під рукою до остаточного артефакту. Наша компанія в основному використовує Java в розробці, а інструмент побудови, який ми використовували, - Maven. Ви, ймовірно, не зможете використати це через характер свого проекту, але в Мевена є якась цінна концепція, яку варто зазначити:

1) У світі Мейвен кожен артефакт (ліб, реальна програма тощо) повинен бути чітко відокремлений і відокремлений. Залежності між артефактом повинні бути чіткими. Я мушу підкреслити, брудна залежність, особливо кругова залежність між вашими артефактами збирання, зробить процес збирання безладним.

Наприклад, я бачив деякі проекти java раніше, хоча після всього процесу збирання побудовано кілька JAR (ви можете вважати, що це lib / dll в Java), вони насправді взаємозалежні. Мовляв, A.jar використовує речі у B.jar, і навпаки. Така «модуляризація» абсолютно безглузда. A.jar і B.jar завжди потрібно розгорнути і використовувати разом. Підсумком є ​​те, що пізніше, якщо ви хочете зробити їх розділеними на різні проекти (наприклад, для повторного використання в інших проектах), ви не зможете цього зробити, тому що ви не можете визначити, який проект, А чи Б, спочатку побудувати.

Так, це потрібно враховувати в дизайні вашого програмного забезпечення, але я завжди вважаю, що замість того, щоб витрачати час на те, щоб зробити складний будівельний інструмент / модель працює в безладному проекті, я б краще витратити час на реорганізацію дизайну, щоб використовувати проста модель будівлі.

2) Залежності повинні бути декларативними. Я бачив багато процесів складання, які я бачив раніше, і вони включають усі необхідні локально в проекті. Це зробить процес збирання вкрай клопітким, якщо деякі з них - це інші артефакти, які вам потрібно створити.

3) "Централізоване" сховище артефактів для отримання залежностей або розгортання артефактів після його складання. Його не потрібно "централізувати" для всього офісу (це буде чудово, якщо він є), просто локальний каталог вже буде добре.

Детальніше про 2 і 3. Просто для прикладу я натрапив на проект, який передбачав 3 незалежні проекти. Кожен проект будується на базі джерела, а також libs під lib / каталогом у вихідному каталозі. Проект A створить декілька ліб, які, в свою чергу, використовуються проектами B і C. Є досить недоліки: процедура складання складна і складніше автоматизувати; контроль джерела стає роздутим непотрібними дублірованими JAR, які повторно використовуються в різних проектах

У світі Мейвена, що це робиться, проект B і C насправді не містить A.jar (та інші залежності, як і інші сторонні ліб) у джерелі проекту. Це декларативний характер. Наприклад, у конфігурації збірки проекту B він просто оголошує, що йому потрібно: A.lib v1.0, xyz.lib v2.1 тощо, і сценарій збірки буде шукати вкладку з /A/1.0/A. баночка та /xyz/2.1/xyz.lib

Для світу, що не належить до Maven, цей артефакт реєстру повинен бути лише один або два каталогу із узгодженою структурою каталогу. Ви можете розмістити всі сторонні лісти до місця спільного доступу та дозволити розробникам синхронізувати чи скопіювати їх на локальних машинах. У своїх проектах на C ++, які я робив багато років тому, я роблю це встановити lib та header на $ {artifact_dir} / lib_name / ver, а артефакт_id оголошено змінною середовища.

Коли проект A побудований, він буде мати копію його результату в цьому artifact_dir, так що коли ми будуємо проект B, B може отримати результат A автоматично, без копіювання вручну.

4) Незмінний випуск. Щойно ви випустите A.lib 1.0, це все, ви не очікуєте, що зміст вмісту A.lib 1.0 через 1 місяць буде лише тому, що є деякі виправлення помилок. У такому випадку це має бути A.lib 1.1. Артефактом мінливої ​​бази коду слід вважати спеціальну "версію", для якої в Мейвіні ми називаємо її знімком.

Невимінюваний випуск - це більше проблема етики. Але що це вирішило, зрозуміло: коли у вас багато проектів, використовуючи один і той самий lib, ви знаєте, яку версію цього lib ви використовуєте, і ви будете впевнені, що та сама версія lib, яка використовується в різних проектах, справді однакова . Я думаю, що багато хто з нас перейшли через проблему: Чому проекти X і Y обидва використовують lib A, але результат збірки відрізняється? (і виявляється, що lib A за допомогою X і Y насправді відрізняється після копання у вміст або розмір файлу lib).


Все це гарантує, що ваші проекти можуть будуватись самостійно, без особливих ручних хитрощів, як, наприклад, побудувати проект А. Спершу скопіюйте A.lib у проект B, а потім складіть проект B ...

Провівши подібну вправу, наприклад, коли ви будуєте проект A, він спробує отримати залежності від централізованого сховища артефактів. Якщо деяких залежностей (які є іншими проектами вашої компанії, наприклад, проект B) не знайдено, що вам потрібно зробити, це отримати джерело проекту B, побудувати його (який буде успішно розгорнуто до централізованого сховища) та потім знову будуйте проект A.


CI

З легкою системою побудови, з чіткими залежностями, CI буде набагато простіше. Я очікую, що ваш сервер CI виконує наступні вимоги:

1) Контролюйте джерело управління, лише замовлення + збірка, коли є зміни в джерелі

2) Здатний встановлювати залежності між проектами

Маючи чітку залежність від проектів, вам просто потрібно налаштувати проекти в CI відповідно до ваших реальних проектів, встановити залежність проектів CI відповідно до залежностей ваших проектів. Ваш сервер CI повинен бути налаштований на створення залежних проектів перед тим, як будувати будь-який проект (і, звичайно, побудова відбувається лише в тому випадку, якщо джерело проекту дійсно зміниться).

Якщо все піде правильно, у вас повинна бути величезна, складна, але все ж керована CI (і ще важливіше - керована структура проекту)


Мені подобається, куди йде ця відповідь, але ви могли б детальніше розібратися в розділі "будівництво"? Тобто наведіть кілька прикладів, поясніть деякі поняття більш повно, детально.
Нейт

хм ... як і яка частина? Я намагаюся редагувати публікацію, щоб детальніше розповісти про кожну частину. Буде краще, якщо ти зможеш сказати мені, яку саме частину ти вважаєш потрібною детальніше. До речі, якщо ви також використовуєте Java, подивіться на maven.apache.org. Мейвен може бути не найпростішою річчю для прийняття, але це змушує вас зробити свої речі чистими та організованими.
Адріан Шум

1

Що працювало в подібних ситуаціях для мене:

  • Абстракція на рівні додатків шляхом шунтування деяких частин збірки у спеціальні додатки збірки (у нашому випадку це сценарії PHP, викликані з основної збірки). Це може скоротити кілька десятків рядків етапів складання в один крок збирання.
  • Абстрагування рівня складання шляхом створення скриптів для підстроювання, які запускаються з основного сценарію збірки. Поняття не має, чи це стосується buildbot (немає досвіду роботи з цим продуктом).

Я б запропонував ви ставитесь до цієї збірки як до проекту розробки програмного забезпечення. Це означає, що вам потрібно модулювати базу коду збірки та написати деякі автоматизовані тести для неї (наприклад, побудувати відомий номер редакції та перевірити, чи він дає правильні результати).


0

Я б вважав Дженкінса сервером CI, ви можете ознайомитись з особливостями тут:

https://wiki.jenkins-ci.org/display/JENKINS/Meet+Jenkins

Чому? Він простий в установці, він має чудовий інтерфейс, його легко налаштувати і розширити, і є багато готових плагінів майже для всього:

https://wiki.jenkins-ci.org/display/JENKINS/Plugins

Спробувати :)


2
Я відчуваю, що ви читали заголовок мого запитання, але не читали тіла ... Я не шукаю пропозиції щодо продукту. Я вибрав продукт. Я шукаю, як організувати складну установку CI.
Нейт

Нейт, я прочитав увесь твій пост і, думаю, ти вибрав неправильний продукт, тому я запропонував Дженкінсу. Я використовую Дженкінса на роботі для різного роду тестування продуктів C ++ (навіть тестів, написаних на декількох мовах) з кластеризацією на декількох машинах, і це працює дуже добре. Адмініструвати та налаштувати це дуже просто. Дійсно, спробуйте :)
Patrizio Rullo

Подивіться на цьому блозі теж: vperic.blogspot.com/2011/05 / ...
Патріціо Rullo

0

Тепер ми використовуємо Go by ThoughtWorks до цього, ми використовували CruiseControl.Net . Це було корисно, враховуючи, що у нас дві команди на півсвіту одна від одної, і між нами велика різниця в часовому поясі.

Ми керуємо кількома проектами, і більшість завдань передбачає перекриття між двома розробниками в обох сторонах земної кулі, тому ми маємо пам’ятати, що всі файли не повинні порушувати чужу конструкцію.

Крім того, управління є легшим за допомогою Go і, будучи спритним процесом Agile Process, дає нам менші головні болі після того, як ми встановили його. Тестування також інтегровано з Go.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.