Через терни до складання

Привіт, дорогі читачі. Я – розробник в компанії «RTL Service», в якій мої обов'язки по розробці продукту перетинаються з обов'язками DevOps. Конкретніше – я створюю і підтримую інфраструктуру складання і первинного тестування наших продуктів ще до їх попадання в відділ тестування.

У даній статті буде розказано про те, який шлях проходить код від пуша у сховище системи контролю версій до формування інсталяційного deb пакети і розміщення в наш репозиторій пакетів.
В якості сервера CI (безперервної інтеграції) у нас використовується Hudson, можете кидати в мене тапками, але ми керуємося принципом «Працює — не чіпай».
Надалі є плани спробувати TeamCity або Jenkins.

Загальна інформація про завдання і групах на нашому сервері CI.
Всі завдання по зборках у нас розбиті на 5 великих груп:
● Firmware (збірка прошивок пристроїв, вони виходять за рамки цієї статті, але перший і другий крок складання у них відбувається так само як у решти об'єктів складання)
● Server (складання основного сервера)
● Appserver (складання сервера додатків)
● Webclient (складання веб інтерфейсу)
● Tests (запуск повного функціонального тестування тощо)

Крок 1: Комміт в систему контролю версій.
Тут все досить тривіально. За допомогою хуків з боку сервера контролю версій надсилається GET запит на CI сервер, результатом якого буде запуск параметризованной збірки (що це і для чого – буде розказано нижче).
Приклад post-commit хука:

while read orev nrev ref
do
case "$ref" in
refs/heads/i*)
issue_branch="${ref##refs/heads/}"
curl -X GET "http://адрес_ci_сервера/..../buildWithParameters?ISSUE_BRANCH=$issue_branch"
;;
esac
done


Крок 2: Запуск параметризованной складання.
Як зрозуміло з назви, — це збірка, яка може мати різні параметри. У нашому випадку зазвичай вистачає пари-трійки, наприклад, ім'я гілки і назва продукту. Такий підхід дозволяє не плодити завдання, які розрізняються між собою не критичними моментами.
На цьому етапі відбувається первинна складання, наприклад, для java проекту це буде робота з gradle в самому примітивному варіанті, що виглядає як «gradle clean build».
Це дозволить виявити випадкові недоліки в коді многомодульного проекту і прогнати юніт тести.

Крок 3: Запуск smoke тестування.
Цей крок виконується в рамках параметризованной складання. Smoke тести проходять в рамках slave машини, на якій запущено завдання по збірці. Цей підхід дозволяє виконувати збирання і початкове тестування різного (наприклад, сервера додатків і веб-клієнта) паралельно, що зменшує час очікування нової версії відділом тестування. У той же час розробники раніше отримують інформацію про виниклі проблеми.
Цілком очевидно, що в рамках цих тестів перевіряється, що після складання коду (нового або виправленого) встановлюється додаток стартує і виконує основні функції. У нашій компанії, В залежності від проекту, вони написані на різних фреймворках (наприклад, огірок).
Тут нам і знадобляться параметри збірки, які ми передали, т. к. для різних продуктів, як і у випадку з приймальним тестуванням, сценарії smoke тестування можуть дуже сильно відрізнятися.

Крок 4: Запуск приймального тестування.
На цьому етапі виконується приймальне тестування продукту з різними сценаріями. Розписувати це не бачу сенсу, оскільки на цю тему є статті на хабре і відповідних ресурсах.

Крок 5: Збірка deb пакета.
Оскільки наша система розрахована на дистрибутив Debian, то найбільш очевидним і зручним засобом буде рідній для нього формат розповсюдження бінарних пакетів deb.
Про структуру пакету на хабре є статті, з якими можна ознайомитися. Я ж розповім про деякі хитрощі, які застосовуються у нас.
Насамперед потрібно отримати ревізію проекту для версійності і можливості оновлювати пакет прямо з репозиторію через apt-get update і apt-get install.
Для цього ми використовуємо стандартну функцію гіта «git describe», при бажанні можна отримати номер збірки відповідно тегу, додавши параметр --tags. Зазвичай під нову мінорну версію ми заводимо свій тег.
Распарсив це по регулярному виразу, отримуємо щось на зразок «1075-g7fb7c67», що і буде номером нашої ревізії. Укупі з назвою і версією продукту ми отримуємо повна назва нашого пакету, в нашому випадку виходить щось на кшталт «rtls-webclient-mines-1.0-dev_1.0-dev.1075-g7fb7c67_all.deb».

Власне, для самої збірки у нас використовується bash скрипт.
Суть в тому, що він створює складальну директорію і кладе туди шаблони для створення пакета. Далі, в залежності від найменування продукту, кладе необхідні модулі та обробляє шаблон файлу config в папці DEBIAN, через команду sed прописує свіжу інформацію про пакет, маючи відомості отримані вище (на прикладі ревізією це виглядає так: «sed -e ' s/%REVISION%/$REV/» -i $PACKAGE/DEBIAN/control»).
Після підготовки складальної директорії за допомогою fakeroot створюється сам deb-пакет командою «dpkg-deb --build $TMP_DIR ${NAME}_${VERS}.${REV}_all.deb», де TMP_DIR — складальна директорія, NAME — ім'я продукту. VERS – версія, а REV – витягнений ревізія.
Далі за допомогою wput отриманий пакет кладеться в репозиторій, а пакет для відправлення – у відділ тестування.

Крок 6: Робота з баг трекером.
Як баг трекера у нас використовується redmine, і для нього написаний відповідний скрипт, який визначає наявність номери тікета в коммите, і при наявності такого, тікет коментується службовим користувачем у назві пакету, в якому застосовано виправлення знайденої помилки. Це дозволяє відділу тестування практично відразу перевіряти виправлення.

Крок 7 (опціональний):
Кожну ніч у нас запускаються завдання повнофункціонального тестування системи і за допомогою відповідного чекбокса у налаштуваннях тригерів збірки, які дають нам розуміння про загальний статус проекту.

Приклад збірки
image
Приклад завалившейся складання з-за не пройшов тесту. Команда розробників була повідомлена і останній коммитивший виправив проблему
image
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.