Jenkins на службе 1С

19.07.23

Разработка - Групповая разработка (Git, хранилище)

Основная специализация Jenkins – это, прежде всего, CI/CD. Но его можно использовать и для других важных задач: разбора хранилищ, настройки копий баз данных, раздачи прав пользователям, рестарта кластера и проверки кода проектов.

Меня зовут Юрий Гончарук, я работаю DevOps-инженером в компании «Финтех Решения». Одна из моих задач – это настройка Jenkins.

Основная специализация Jenkins – это, прежде всего, CI/CD. Но мы его у себя пристроили и для кучи других очень интересных задач, которые непосредственно к CI/CD не относятся. Это:

  • разбор хранилищ;

  • настройка развернутых копий баз – когда мы поднимаем копию базы, смотрим;

  • перезагрузка кластера – мы его тоже делаем через Jenkins;

  • и управление доступом к базам для дежурных разработчиков.

 

Разбор 40 хранилищ

 

Начнем с разбора хранилищ.

Мы стараемся весь код хранить в Git, но разработка у нас по-прежнему ведется в хранилищах. Соответственно, у нас около сорока различных хранилищ – от УПП до ERP. Все их нужно разбирать в Git, потому что основной формат хранения, с которым мы работаем в дальнейшем – это Git. Хранилища – это среда внесения изменений непосредственно для разработчиков.

Для мелких «исправительных» расширений у нас есть отдельные проекты, в которые мы разбираем эти расширения через precommit1c – здесь участие CI/CD не требуется.

Мы сейчас пытаемся уходить от хранилищ – хотя бы для расширений, но пока это никуда от нас не денется и очень долгое время будет жить с нами.

При попытке контролировать разработку в сорока с лишним хранилищах, появляются вопросы:

  • Как сделать так, чтобы все эти хранилища разбирались?

  • Как подключить в систему разборки новое хранилище?

  • Как отключить хранилище от разборки при необходимости?

Для этого у нас в Jenkins есть шаблонное задание, которое мы при необходимости просто подключаем к хранилищу.

Мы создаем новое задание – его jenkinsfile показан на слайде. Задание совершенно несложное, буквально из четырех шагов. И настраиваем его на периодический разбор – чуть дальше покажу.

Все настройки для этого задания хранятся в конфигурационных файлах.

Т.е. задание используется шаблонное, а к нему – такие маленькие конфигурации, где задано:

  • какие плагины подключать;

  • дополнительные настройки плагинов;

  • куда подключаться;

  • куда синхронизировать.

Все это задается в файле конфигурации.

Как добраться до этого файла конфигурации? Мы решили, что так как каждое задание уникальное и имеет собственное имя в Jenkins, то и файл конфигурации будет иметь точно такое же название и будет располагаться в подключаемой библиотеке.

На слайде показано, каким образом мы его загружаем. Загруженный таким образом файл конфигурации сразу объявляет все указанные в нем переменные переменными среды – нам ничего дополнительно делать не нужно.

 

Теперь – то, что касается Gitsync.

Для разбора разных хранилищ нам нужен разный набор плагинов Gitsync. Каким образом это сделать?

Мы объявляем переменную GITSYNC_PLUGINS_PATH, и в ней инициализируем плагины. У нас есть список предопределенных плагинов:

  • sync-remote

  • limit

  • check-comments

  • check-authors

  • increment и прочее.

Все эти плагины у нас подключены для всех хранилищ. И дополнительно через переменную env.Plugins мы можем передать какие-то еще.

Сборочная линия проверяет, что каталог плагинов существует, и, если его нет, инициализирует необходимые плагины по списку.

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

Шаг синхронизации достаточно простой.

Задаем переменные окружения.

Отдельно через Credentials передаем учетные данные. Это очень важный момент, потому что их можно задать в командной строке явно, но самым безопасным и рекомендуемым способом является передача через Credentials – Gitsync эту функцию поддерживает.

 

Следующий вопрос, который перед нами встал – как часто разбирать.

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

Тут хочется сказать: у нас что, каждый час будет разбираться по одному коммиту? Мы это решили другим способом: когда очередная версия помещается в репозиторий, репозиторий через вебхук перевызывает это задание. Таким образом задание запускается по новой и будет так работать до тех пор, пока не разберет все версии из хранилища.

 

Разворачиваем копии

Следующая функциональность – копии баз. Практически всегда, когда вы разворачиваете копию, это еще не значит, что в эту копию можно сразу всех пускать. Нет, для этого с копией нужно поработать предварительно – этой подготовкой тоже занимается Jenkins.

Что мы делаем в копии?

  • Обязательно обновляем нумерацию объектов, это прямо must have.

  • И затем последовательно выполняем БСП-шные функции – запрещаем выполнение регламентных заданий.

  • Удаляем настройки подключений ко всем внешним сервисам, чтобы разработчик случайно не запустил синхронизацию в копии. Мы сразу удаляем все настройки подключений и убираем эту проблему.

  • Если нам все-таки нужно использовать какие-то внешние сервисы, мы переключаем на mock-заглушки либо на тестовые версии внешних сервисов.

  • Поскольку у нас используется механизм копий баз данных, мы отключаем копии баз данных для копии базы данных. Звучит как рекурсия, но это разные механизмы.

  • Следующий момент – у нас разработчики не имеют доступ на продуктовую базу, но мы им разрешаем заходить на копию. Поэтому мы настраиваем в поднятой копии доступ тем пользователям, которым нельзя в рабочую базу, но можно в копию.

  • И еще у каждой базы есть своя специфика.

Мы это реализовали достаточно просто.

  • Сделали отдельный репозиторий в GitLab, где хранятся исходники внешних обработок, которые выполняют эту настройку. Они там хранятся в прямо в XML-ках и при запуске заданий собираются. Всего набралось пять таких специфичных обработок: отдельно для УПП, Бухгалтерии, ERP и так далее. В каждом типе баз свои особенности.

  • Для запуска задания, которое выполняет настройку базы, используется возможность Jenkins запускать задание через вебхук.

  • Когда админ разворачивает копию базы на SQL, он дергает этот вебхук, и все.

  • При окончании работы задания Jenkins публикует в канале Teams уведомление, и разработчики уже могут заходить.

 

Вот так вот выглядит pipeline, он достаточно простой.

Мы передаем имя базы через параметр – Jenkins поддерживает такую функцию.

И внизу показано, как мы оповещаем о запуске обработки в Teams. Вот таким нехитрым образом мы можем опубликовать любое сообщение. Не только текст, но и, например, красивую табличку с данными. Туда можно передать что угодно, это очень удобно.

Справа показано, как у нас выглядит обработка для настройки копии базы ERP.

 

«Who is on duty today?» – Кто сегодня дежурный?

Разработчики у нас не имеют доступа в рабочую базу, но есть исключение – это дежурство. Дежурства бывает ночные, на выходные, но самые интересные – это дневные дежурства, которые идут в рабочее время.

  • Дежурным по очереди является каждый разработчик команды, причем дневное дежурство назначается на неделю. Мы утром включаем, а вечером выключаем разработчику доступ к рабочей базе.

  • Для ночных дежурных доступ в базу открывается с 18:00 до 09:00 следующего дня.

  • И в выходные разработчики заступают на дежурство с вечера пятницы до утра понедельника.

Расписание дежурств задается полностью в Teams, а в Jenkins настроена задача, которая по расписанию запускается, получает информацию из расписания Teams и разрешает или запрещает вход конкретных пользователей в базу.

Для этого у нас есть две небольшие библиотечки – для работы с Teams и для работы с Jira. Мы там реализовали далеко не всю функциональность API, только то, что нужно:

  • авторизация;

  • получение данных из расписания Teams;

  • и получение данных для выдачи дежурным разрешения работать в Jira – дежурные помимо доступа к рабочей базе должны разбирать и классифицировать новые задачи в Jira.

Сложного в принципе тут ничего нет. Все делаем по документации к API.

 

Рестарт кластера одной кнопкой

Следующее – это перезапуск кластера.

Jenkins умеет работать не только с cmd, чтобы запускать скрипты на OneScript, у него есть отдельная функциональность для работы через PowerShell – эту функциональность мы используем для перезапуска кластера.

Кластер у нас большой, в основном рабочем кластере содержится 5 рабочих серверов – их нужно погасить в правильной последовательности, а потом поднять в правильной последовательности.

Руками это сделать можно, но сложно, потому что это нужно делать безошибочно и каждый раз. А такая ситуация обычно возникает из серии: «У нас все упало, давайте перезагрузим».

Чтобы трясущимися руками не ошибиться, у нас есть такое задание, которое это делает автоматически:

  • перезапускает кластер;

  • также завершает все рабочие процессы, которые штатно не завершились;

  • очищает временные каталоги и каталоги сеансовых данных у кластера;

  • убирает файлы журнала регистрации из каталога кластера – это связано с тем, что у нас журнал регистрации перегоняется в GreyLog практически онлайн, поэтому хранить его постоянно на рабочем сервере смысла не имеет;

  • и потом запускает в определенной последовательности.

Вот так выглядит пайплайн, который запускает скрипт PowerShell.

Опять же через Credentials мы передаем имя пользователя и пароль. И запускаем скрипт PowerShell.

На слайде показан фрагмент скрипта PowerShell – мы подключаемся к удаленному компьютеру, используя объявленные в пайплайне переменные окружения.

А это – фрагмент команды для остановки сервиса на конкретной машине.

Из интересного – обратите внимание на то, что здесь используется модификатор области видимости «$Using». Он позволяет прокинуть локальную переменную в сессию. Если забыть его указать, можно долго мучиться – удивляться, почему ничего не работает.

 

Сборка и тестирование

Ну и «родная» функциональность Jenkins – build, test and deploy.

Сборку проектов, разрабатываемых в хранилище, мы, конечно, не производим, потому что там конфигурацию легко получить стандартными средствами – в любой момент можно вытащить из хранилища готовый CF версии.

А для сборки проектов, которые разрабатываются в Git, мы в Jenkins используем vanessa-runner, обернутый в скрипт на OneScript – фрагмент текста этого скрипта показан на слайде. Дополнительная обертка нужна, потому что в этом скрипте помимо вызова vanessa-runner обрабатывается дополнительная логика.

Справа показан шаг сборки расширения.

При построении проекта мы меняем номер версии – добавляем в номер текущей сборки. Это очень серьезный подводный камень.

В самом CF-файле в поле версии указано четыре числа через точку, и последняя циферка всегда ноль. Но когда мы собираем конкретный файл, мы эту циферку меняем на текущий build number.

Благодаря этому бинарные файлы всегда будут иметь уникальную версию – разработчику не нужно думать, поменял он версию или нет. Она всегда будет уникальна.

 

Здесь показан фрагмент кода – как мы на OneScript добавляем номер сборки. Этот код, может быть, несколько костыльный, но он работает.

Важно – после того, как мы поменяли номер сборки в MDO-файле конфигурации и собрали проект, нужно не забыть отменить изменения командой:

git restore <ИмяФайлаКонфигурации>

 

Чтобы сохранить бинарные файлы для дальнейшего использования, есть команда «Сохранение артефактов». Потом их можно использовать в других сборках.

Собрав версию один раз, мы можем использовать этот номер в любой другой задаче. Повторно артефакт собирать не нужно – мы его уже собрали, и он там лежит. Мы его просто используем для работы.

С построением разобрались, теперь тесты.

На слайде приведен пример команды, которая подключает расширение с тестами.

Напомню, что тесты у нас разрабатываются в расширениях – об этом есть отдельный доклад.

Мы подключаем расширение и запускаем базу, а потом второй командой «Запуск тестов» запускаем тесты с помощью XUnit.

 

Деплоим на прод

 

Следующий пункт – деплой, обновление рабочей базы.

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

Параметры этого сценария мы точно так же получаем по имени джобы.

На слайде показаны те шаги, которые у нас делаются:

  • мы закрываем активные сеансы;

  • устанавливаем блокировку сеансов;

  • обновляем;

  • запускаем в режиме предприятия;

  • и снимаем блокировку.

Здесь мы немного применили оптимизацию шагов – видите, у нас два шага выполняются параллельно:

  • мы ждем завершения сеансов;

  • и параллельно у нас обновляется база из хранилища.

Следующий шаг стартует только после их завершения.

А дальше все просто – обновляем конфигурацию, запускаем в режиме предприятия и снимаем блокировку.

 

Со снятием блокировки интересная штука – поскольку при первоначальном запуске мы накладываем блокировку на вход в базу, мы ее обязательно должны снять.

Что бы ни случилось в нашей джобе, мы должны снять блокировку.

Поэтому все шаги внутри пайпа у нас обернуты в catchError. Если мы ловим ошибку, то помещаем конкретный шаг как ошибочный, а buildResult у всей сборки выставляем как “NOT_BUILD”.

И последний шаг всегда снимает блокировку сеансов. Видите, тут даже в опциях указано retry(3) – то есть три раза пробуй, если что-то не получилось, еще два раза сделай.

Вот такая штука у нас используется.

 

Непрерывная проверка SonarQube

Следующий момент – проверка кода. Мы активно используем SonarQube, он подключается у нас практически ко всем репозиториям с кодом.

У нас есть несколько сценариев работы с SonarQube:

  • есть типовой маленький pipeline, который просто проверяет проект;

  • реализованы шаги, которые проверяют код – как для ветки, как для проекта, так и для мерж реквеста;

  • ну и отдельный пункт у нас – прохождение порога качества.

Для простого анализа у нас есть совсем простой pipeline, в котором буквально два шага – проверить и дождаться прохождения порога качества.

В этот пайплайн мы передаем параметры проверки проекта:

  • сколько памяти,

  • сколько ждать тайм-аута проверки

  • где хранятся настройки проверки SonarQube

Сам анализ включает в себя три параллельных шага:

  • первый шаг – это проверка всего проекта целиком;

  • потом – проверка конкретной ветки проекта;

  • и следующий момент – проверка мерж реквеста.

На слайде показана разница между этими шагами – они отличаются тем, какие параметры будут переданы в SonarQube при проверке.

Очень важно, что бесплатная версия SonarQube Community Edition поддерживает только один режим работы – это проверка целиком проекта.

Анализ веток проекта и мерж-реквестов доступен только у старших редакций SonarQube.

Но сообщество SonarQube реализовало Community Branch Plugin, который позволяет использовать эту функциональность и для младшей версии.

Без Community Branch Plugin эти два последних шага были бы нерабочими, был бы только вариант №1. Спасибо сообществу SonarQube, они помогают и 1С-никам.

Следующий момент – порог качества SonarQube.

Для большинства проектов порог качества – это скорее сообщение о том, как мы работаем.

А для некоторых проектов мы используем порог качества как такой терминатор – успешная сборка или нет. Если не прошли порог качества, все, сборка падает, и она помечается не рабочей.

Вот примеры настройки порога для таких проектов. Для ветки.

 

И для мерж-реквеста.

Вот как мы проверяем порог качества.

Если порог качества не пройден, мы помечаем сборку как нестабильную, и показываем, что это именно из-за падения порога качества.

К примеру, у нас есть небольшой проект, в котором процент покрытия 76 процентов (сейчас уже больше 80). Для новых версий этого проекта непрохождение порога качества по покрытию является терминальным. Не прошли – все, мерж-реквест не будет принят.

Пока у нас таких проектов буквально два, сейчас появится третий, в котором это будет использоваться. Но мы так уже работаем.

 

Вопросы

 

Декорирование мерж-реквестов у вас работает без проблем?

Да, работает. Без проблем. Какое-то время не работало из-за того, что использовалась некорректная связка ПО, но после того, как мы обновили и GitLab, и SonarQube на последнюю версию – все отлично работает, и все показывается.

Вы сказали, что используете хранилище, при этом делаете еще артефакты и прочее. Зачем хранилище?

У нас есть проекты и на Git, и на хранилище. Артефакты мы делаем для тех проектов, в которых разработка ведется в исходных кодах.

Вы сказали, что при деплое базы, если что-то пошло не так, вы в любом случае снимаете блокировку. А вы уверены, что блокировку точно можно снимать и работать в исходном режиме? Может быть, там что-то такое случилось, что мы немного порушили то, что было?

У нас пока примеров, когда все ломалось, не было. Поскольку у нас обновление базы подразумевает, что работают роботы, а не человек, то логика такая – мы запустили обновление базы и смотрим за результатом. Если обновление упадет по той или иной причине, туда уже зайдет человек и будет смотреть, в чем дело. И дальнейшее решение принимает человек, принимает не система. Мы разрешаем вход, но если что-то упадет, всегда есть человек, который за этим смотрит.

Почему именно Jenkins? Есть же много разных инструментов, например, GitLab CI. Если у вас Enterprise версия GitLab, почему бы сразу его не использовать? По коду видно, что в большей части используются скрипты на OneScript и Powershell. Почти всю эту функциональность можно перенести и на GitLab CI.

Да, мы именно так и хотели, чтобы сама логика была реализована именно в скриптах.

Почему именно Jenkins? Наверное, потому что так исторически сложилось: Jenkins использует комьюнити Инфостарта, о нем очень много было полезных докладов и статей.

В принципе, это все можно сделать и на GitLab CI. Здесь нет никакой проблемы.

Можно сделать и на других CI платформах, здесь нет ничего уникального. Здесь интересно только то, что можно делать и так, и так, и так.

Если ничего нет, то даже Jenkins уже хорошо.

Есть ли у вас опыт использования библиотеки от Никиты Грызлова?

Мы сознательно делаем так, чтобы не реализовывать на стороне Jenkins вообще никакую логику. У нас groovy – это максимум обертка. Те шаги, которые я показывал, просто перегоняют параметры в командную строку. Никакой бизнес-логики внутри нет.

Вся логика у нас написана либо в OneScript, либо в PowerShell. На groovy у нас логики нет. Groovy и pipeline отвечают только за логику прохождения шагов, но не за логику выполнения шагов.

А почему так? Для уменьшения порога входа, чтобы 1С-ники могли это делать?

В лучших практиках Jenkins прямо написано: «Не пишите логику на groovy». Там это чуть ли не в первом же абзаце написано. Раз не нужно писать логику на groovy, тогда на чем? Ответ очевиден, на 1С (т.е. на OneScript).

 

*************

Статья написана по итогам доклада (видео), прочитанного на конференции Infostart Event.

 

30 мая - 1 июня 2024 года состоится конференция Анализ & Управление в ИТ-проектах, на которой прозвучит 130+ докладов.

Темы конференции:

  • Программная инженерия.
  • Инструментарий аналитика.
  • Решения 1С: архитектура, учет и кейсы автоматизации на 1С.
  • Управление проектом.
  • Управление продуктом.
  • Soft skills, управление командой проекта.

Конференция для аналитиков и руководителей проектов, а также других специалистов из мира 1С, которые занимаются системным и бизнес-анализом, работают с требованиями, управляют проектами и продуктами!

Подробнее о конференции.

 


См. также

Системы контроля версий для 1С-разработчиков.

1С-программирование DevOps и автоматизация разработки Групповая разработка (Git, хранилище) DevOps для 1С Платформа 1С v8.3 Платные (руб)

Основы командной разработки на 1С. Использование систем контроля версий при разработке на платформе 1С:Предприятие 8

4900 руб.

29.06.2022    7952    71    4    

99

Захват в хранилище по составу подсистем

Групповая разработка (Git, хранилище) Управляемые формы 8.3.8 Конфигурации 1cv8 Абонемент ($m)

Обработка для захвата объектов в хранилище согласно составу подсистем.

1 стартмани

21.11.2023    853    3    ImHunter    0    

14

Работа с GitLab API

Групповая разработка (Git, хранилище) WEB-интеграция Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Работа с API GitLab на примере запуска pipeline с переменными, отслеживания его статуса и загрузкой полученных артефактов.

1 стартмани

06.10.2023    623    1    itsys    0    

5

Наш путь в Git – история одного внедрения CI/CD

Групповая разработка (Git, хранилище) DevOps и автоматизация разработки Бесплатно (free)

Чтобы перейти от разработки в хранилище до полноценного релизного цикла CI/CD, с автотестированием кода, сборкой конфигураций из исходников и ветками разработки для каждой задачи, нужно пройти большой путь. Расскажем о том, как организовать полностью автоматическую доставку проверенного и рабочего кода в 2000 конфигураций.

02.10.2023    2932    MrWonder    4    

11

Приемы быстрой работы в EDT/Git

Групповая разработка (Git, хранилище) Платформа 1С v8.3 Конфигурации 1cv8 Россия Бесплатно (free)

Статья даёт ответы на некоторые вопросы, возникающие у разработчиков, которые погружаются в океан технологий EDT и Git, омывающий царство DevOps... Сколько и какие ветки нужны? Какой репозиторий выбрать? Кто должен сливать доработки в мастер ветку или ветку версии? Как не тратить время в EDT на ресурсоёмких операциях? Зачем нам сборочный конвейер и как его построить? Зачем нам нужно тестирование и как его реализовать? Как вести разработку, если есть разработчики, не умеющие вести разработку в EDT или не имеющие технической возможности, но нам нужны их skills в 1С? Что такое фантомы и нужно ли с ними бороться? Как слить 20 доработок с конфликтами и уложиться в 4 часа? Опыт использования модных технологий в реальных проектах.

30.03.2023    7608    check2    10    

86

Получаем статистику по git-репозиторию в разрезе разработчиков

DevOps и автоматизация разработки Групповая разработка (Git, хранилище) OneScript Бесплатно (free)

Итак! Представим, что наступил момент, когда разработка через исходный код реализована на предприятии в полном объеме. Мы разрабатываем в EDT или конфигураторе (но выгружаем конфигурацию в исходный код), версионируем внешние отчеты и обработки и расширения, собираем релизы, проверяем код статическим анализом, в разработке царит гармония и мир. Красота! Но менеджерам этого мало, всегда хочется чего-то еще, и вот мне прилетает задача - дай статистику по вкладу в код каждого разработчика.

13.03.2023    2527    ardn    3    

27

Кровь, пот и GIT

Групповая разработка (Git, хранилище) Бесплатно (free)

Ведущий разработчик 1С Андрей Карпов на конференции Infostart Event 2021 Post-Apocalypse поделился ошибками, которые совершают новички в работе с GIT. В докладе четыре кейса с пошаговыми инструкциями, которые позволят не допускать конфликтов в разработке.

17.01.2023    8654    karpik666    45    

67

Прокси хранилища 1С (IIS, OneScript)

Групповая разработка (Git, хранилище) OneScript DevOps и автоматизация разработки Платформа 1С v8.3 Россия Бесплатно (free)

Избавляемся от версионной зависимости, проверяем комментарии, вызываем веб-хуки, делаем красивые пути. И все это на привычном IIS и понятном OneScript.

08.12.2022    7133    kamisov    56    

95
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. kirillkr 29 21.07.23 22:28 Сейчас в теме
Жаль нет кода библиотеки acme_lib.
2. yukon 136 24.07.23 09:20 Сейчас в теме
(1) Большая часть будет доступна в
Vanessa-runner плагине для Jenkins.

Готовим доклад по этому плагину на IE2023.
vikad; kirillkr; +2 Ответить
3. mikeA 1 03.08.23 12:50 Сейчас в теме
А ещё с помощью него можно выполнять клиентские методы форм через ... xUnitFor1C. И не спрашивайте меня зачем.
4. yukon 136 03.08.23 12:53 Сейчас в теме
(3) Да можно вызывать и клиентские и серверные методы, и я могу даже сказать зачем. см. доклад "Тесты в расширениях" - там как раз подробно про это.
Оставьте свое сообщение