По мотивам статьи было реализовано ~10 линий сборки. Ну работали себе. Время от времени ломались из-за новых авторов в хранилище, чинились, работали дальше.
Но вот понадобилось добавить еще ~15 линий (отсюда "Опять 25":) и немного переделать текущие.
Начал заниматься всем этим. Но на 8-й линии уже психанул - ведь работа несложная, но кропотливая и однотипная (!). Поэтому озадачился и решил написать единую линию сборки, где все проекты были бы описаны в отдельном файле и хранились в репозитории - чтобы вообще в Jenkins не лазить. За пару вечеров допилил.
Предназначение
Пайплайн выгружает несколько хранилищ в git-репозитории и (опционально) запускает анализ кода sonar scanner'ом.
Ключевые возможности
- Чтение общих и проектных настроек из JSON-файлов.
- Фильтрация запускаемых проектов через параметр
PROJECT_FILTER. - Параллельная и последовательная обработка проектов.
- Опциональный таймаут для каждого проекта.
- Безопасная работа с секретами (токен SonarQube, учетные данные Git).
- Обработка ошибок: сбой одного проекта не останавливает весь пайплайн.
- Использование библиотеки
gitsyncдля переноса коммитов хранилища в Git-репозиторий. - Возможность задавать произвольные параметры для
gitsyncиsonar scannerчерез переменные окружения.
Большую роль играет то, что и gitsync, и sonar scanner могут параметризоваться переменными окружения. И поэтому любые такие настройки можно задать при описании общих и/или проектных настроек - эти настройки "транслируются" в переменные окружения.
{
# Метка Jenkins-агента, где будет происходить сборка
"agentLabel": "sonar",
# Кодовая страница для логов gitsync и sonar scanner
"codepage": "65001",
# ID секрета, хранящего раздельно пользователя и пароль для подключения к git-репозиторию
"gitCredentialsID": "git_token",
# ID секрета, хранящего токен для подключения к SonarQube
"sonarqubeTokenID": "sonarqube_token",
# Настройки проектов "по умолчанию".
# Все ключи из default могут быть переопределены непосредственно в объекте проекта (на верхнем уровне).
"default": {
# Проект активен
"active": true,
# Каталог репозитория, где хранятся сами исходники
"srcDir": "src",
# Запускать анализ SQ
"useSonar": true,
# Ветка репозитория исходников. Бывает и main, и master. Указываем, как нам нужно.
"branch": "main",
# Запускать параллельно с другими проектами
"parallel": true,
# Дополнительные параметры командной строки для gitsync
"otherGitsyncParams": "",
# Дополнительные параметры командной строки для sonar scanner
"otherSonarScannerParams": "",
# Очищать рабочий каталог перед запуском gitsync.
"clearDir": true,
# Можем ограничить таймаутом время сборки проекта
"timeoutMinutes": 0
},
# Переменные окружения "по умолчанию"
# Здесь и переменные gitsync, и sonar scanner.
"env": {
"V8VERSION": "8.3.22.2283",
"GITSYNC_STORAGE_USER": "user_gitsync",
"GITSYNC_DOMAIN_EMAIL": "domain.ru",
"GITSYNC_EMAIL": "domain.ru",
"GITSYNC_REMOTE_PUSH_N_COMMITS": "2",
"GITSYNC_LIMIT": "0",
"GITSYNC_REMOTE_PUSH_TAGS": "true",
"GITSYNC_REMOTE_PUSH": "true",
"GITSYNC_SKIP_EXISTS_TAGS": "true",
"GITSYNC_TASK_PREFIX": "#",
"SONAR_HOST_URL": "https://sonarqube:9443",
"SONAR_SOURCE_ENCODING": "UTF-8",
"SONAR_INCLUSIONS": "**\\*.bsl",
"SONAR_SCANNER_JAVA_OPTS": "-Xmx2G"
}
}
* JSON не предусматривает комментарии - удалить.
[
{
# Задаем другую основную ветку
"branch": "master",
"env": {
# Это расширение
"GITSYNC_EXTENSION": "РасширениеВнешниеКонтрагентыДоговоры",
# Путь к хранилищу
"GITSYNC_STORAGE_PATH": "//STORAGES-1C/Расширения/РасширениеВнешниеКонтрагентыДоговоры/",
# URL git-репозитория
"GITSYNC_REPO_URL": "https://STORAGES-GIT/docflow/ebd-external_data.git",
# Ключ проекта SonarQube
"SONAR_PROJECT_KEY": "ebd.external_data"
}
},
{
# Отключаем параллельность
"parallel": false,
"env": {
"GITSYNC_STORAGE_PATH": "//STORAGES-1C/TechProjects/194_БП/",
"GITSYNC_REPO_URL": "https://STORAGES-GIT/1c/prom/main_disconnects.git",
"SONAR_PROJECT_KEY": "Prom_bp_disconnect",
# Имя проекта SonarQube
"SONAR_PROJECT_NAME": "Пром (БП Отключения)",
# Дополнительные java-опции для sonar scanner
"SONAR_SCANNER_JAVA_OPTS": "-Xmx8G -Xms2G -Dfile.encoding=UTF-8"
}
}
]
* JSON не предусматривает комментарии - удалить.
Примечания
- Проектные настройки дополняют и "перекрывают" значения по умолчанию.
- Конечный запуск cli-утилит выполняется с помощью powershell, т.к. bat как-то неустойчиво ведет себя, именно при использовании в скриптовом pipeline, - может на ровном месте зависнуть. А в freestyle-проектах такой проблемы не наблюдается.
- Ключ проекта передается не через переменную окружения, дописан через "--define". У меня почему-то из переменной окружения sonar scanner не брал ключ. И через "-Dsonar.projectKey=" тоже не брал. А через "--define" взял.
- Сначала выполняется параллельная сборка, затем выполняются последовательные сборки.
- Ключ sonar-проекта (env.SONAR_PROJECT_KEY) нужно задавать, даже если анализ кода отключен. Используется для заголовка шага сборки.
- Не проработана тема с credentials для доступа к хранилищу для gitsync. Может позже доделаю.
- Немного озадачился безопасностью для параметров, которые могут быть дописаны в командную строку (см.метод sanitizeParams), чтобы избежать injections. Но тут тема более серьезная. Может и вообще нужно убрать эти доп.параметры командной строки.
Дополнительные возможности
Фильтр проектов
При запуске задания в Jenkins можно задать, какие проекты обрабатывать. Для этого нужно линию сборки сделать параметризованной, ввести параметр PROJECT_FILTER с значением по умолчанию "*".
Варианты фильтра:
- * - все проекты, с учетом их активности
- cf - обработка основных конфигураций, с учетом активности
- cfe - обработка расширений
- Ключи необходимых проектов, через пробел. Настройка активности не учитывается.
Таймауты
Можно задать таймаут в минутах для обработки проекта. Для отключения таймаута - указать 0 (ноль).
Плагины
Требуются плагины Jenkins:
- Pipeline Utility Steps (для `readJSON`, `readFile` и др.)
- Git Plugin (для клонирования репозиториев)
Итоги
Получилась достаточно универсальная линия сборки. При этом, состав и настройки проектов определяются "снаружи", конфигурационными файлами, без захода в Jenkins.
Вступайте в нашу телеграмм-группу Инфостарт