Руководство прикладного разработчика#
Описание#
Программный компонент Build tools (код CIJE), входящий в состав программного продукта Platform V DevOps Tools (код DOT), представляет собой библиотеку Jenkins и предназначен для сборки дистрибутивов командами разработки.
Оглавление#
Руководство прикладного разработчика
Разработка первого приложения с использованием программного компонента
Термины и сокращения#
Термин, сокращение |
Определение, расшифровка |
|---|---|
Nexus |
Хранилище дистрибутивов |
BitBucket |
Веб сервис для хостинга проектов и их совместной разработки |
OpenShift |
Платформа для разработки и эксплуатации контейнеризированных приложений |
Docker |
Инструмент для автоматизации развертывания и управления приложениями в средах с поддержкой контейнеризации |
Jenkins |
Программная система для обеспечения процесса непрерывной интеграции |
Credentials |
Параметры учетной записи (логин, пароль) |
Jenkinsfile |
Простой текстовый файл с кодом на языке |
ТУЗ |
Техническая учетная запись |
Jira |
Инструмент управления рабочим процессом |
Confluence |
Инструмент создания внутренней базы знаний |
SonarQube |
Инструмент для непрерывной проверки кода и статистического анализа |
SYFT |
Утилита анализа образов docker |
pipeline |
Репозиторий, предназначенный для хранения релизов скриптов развертывания на уровне стенда |
ПСИ |
Приемо-сдаточные испытания |
bh |
Файлы с backend двоичными данными (business hub) |
pl |
Файлы с frontend (presentation layer) |
pl_mobile |
Файлы с frontend (presentation layer) для мобильных приложений |
db |
Файлы с liquibase-скриптами настройки базы данных (БД) |
conf |
Файлы конфигурации (различные yaml, conf, json-файлы) |
QGM |
Quality Gates Manager — пользовательское веб-приложение, предназначенное для администрирования и работы с данными инструмента Quality Gates |
ReleaseNotes |
JSON-файл, содержащий список новых коммитов (собирается автоматически) |
МУС |
Модуль управления структурой |
Системные требования#
Основные требования к используемым системам при работе с программным компонентом представлены в Руководстве по установке → глава Системные требования.
Перед началом работы с программным компонентом необходимо:
Создать git-репозиторий для хранения кода Jenkins библиотеки.
Создать пространство в maven репозитории (на запись).
Получить доступ к зеркалу central (maven) (с правом на чтение) и инструментарию JDK, maven.
Завести Jenkins Credential с доступом к репозиторию из пункта
1с предоставленными правами на запись.Создать исполняемые Jenkins jobs.
Получить доступ к области
docker-registryс правом на запись.
Подключение и конфигурирование#
Конфигурирование pipeline (pipeline.yml)#
Сборка дистрибутива в библиотеке ufs-pipeline управляется с помощью конфигурации, описанной в файле pipeline.yml, и содержащей:
Настройки инструментов сборки (maven, npm)
Реквизиты дистрибутива (maven-координаты) ( fp )
Адреса и параметры учетной записи доступа для загрузки (distribution)
Реквизиты дистрибутива для установки флагов (qgm)
Реквизиты сборки Docker-образов (docker)
Описание зависимостей дистрибутива (с разбивкой по профилям) (profiles)
Описание подключения и сборки компонентов дистрибутива (bh, pl, db, jenkinsfiles)
Описание загрузки дополнительных артефактов (downloads)
Подключение и настройки расширений (extensions)
Файл pipeline.yml может также быть параметризирован переменными окружения.
Настройка инструментов сборки#
В файле конфигурации сборки доступна настройка нескольких инструментов сборки: maven, npm и sonar, причем:
настройка
mavenобязательна и требуется в любом случаенастройку
npmнеобходимо выполнять только в том случае, если используется блокplнастройку
sonarрекомендуется выполнить, но при ее отсутствии будет использована инсталляцияSonarQubeс токеном доступа по умолчанию
Примеры настройки:
### Настройки MAVEN ###
maven:
# Идентификатор файла в folder, который следует подключить через configFileProvider. Рекомендуемый вариант подключения
settings_id: 'maven-settings'
# Maven настроенный в Jenkins. Доступные версии можно посмотреть в Pipeline Syntax - snippet generator - tool - Maven
home: 'Maven 3.6.3'
# JDK настроенный в Jenkins. Доступные версии можно посмотреть в Pipeline Syntax - snippet generator - tool - JDK
jdk: 'jdk-11.0.10_linux'
# Опции, которые будут прокинуты во все maven-сборки
options: '-Xmx100m'
### Настройки NodeJS ###
npm:
# Идентификатор файла в folder, который следует подключить через configFileProvider. Рекомендуемый вариант подключения
config_id: "npm-settings"
# Версия NodeJS, настроенная в Jenkins. Доступные версии можно посмотреть в Pipeline Syntax - snippet generator - tool - NodeJS
version: "v7.5.0-linux-x64"
### Настройки SonarQube ###
sonar:
credentialsId: sonar-token-cred # Идентификатор credentials с типом Secret text
installationName: SonarQube # Название инсталляции SonarQube следует уточнить у владельцев Jenkins
sonar_timeout: 20 # Если параметр задан: изменить в минутах время ожидания ответа Quality Gate статуса от SonarQube сервиса
Список версий JDK, maven, nodejs и т.д. можно посмотреть, зайдя в конфигурацию любой Jenkins job, и нажав Pipeline Syntax в самом низу, далее Snippet Generator и выбрать в списке tool:

Конфигурирование блока fp#
Блок fp содержит maven-координаты дистрибутива, который включает следующие опции для заполнения:
groupId - Group ID дистрибутива.
artifactId - Artifact ID дистрибутива.
version - Версия дистрибутива. Данный параметр может иметь любое значение, к которому будет добавлен номер сборки. Разделитель номера сборки - знак "минус", который также можно переопределить с помощью переменной окружения BUILD_NUMBER_SEPARATOR. (Например, D-01.000.00-123, где 123 - номер сборки)
version_meta - Параметр, значение которого добавляется к указанной версии дистрибутива через разделитель
_.component_code - 4-х буквенный код компонента дистрибутива.
Если вы не знаете свой component_code, то можете указать artifactId в качестве его значения (ограничение на 4 символа в этом случае не действует)
Пример:
fp:
groupId: distribution.group.id
artifactId: distribution-artifact-id
# Maven version для артефакта инсталляционного пакета. К нему будет добавляться номер сборки. В результате для build с номером 123 в Nexus будет выгружен артефакт с версией D-01.000.00-123
version: "D-01.000.00"
# Добавляет постфикс к версии дистрибутива в формате version-BUILD_NUMBER_version_meta, например D-01.000.00-472_SECTOR_1
version_meta: "SECTOR_1"
component_code: cije # Код компонента вашего дистрибутива.
Настройка блока distribution#
Блок distribution включает в себя набор репозиториев, в которые необходимо загрузить собранный дистрибутив.
Для каждого репозитория нужно указать ссылку на него и serverId - запись в settings.xml, в которой хранятся данные
учетной записи с правами на запись в указанный репозиторий.
Пример заполнения:
distribution:
- url: https://your.company.maven.server/repo/your-repo
serverId: cdp # В settings.xml есть server с id=cdp
Заполнение раздела qgm#
Помимо загрузки дистрибутива в хранилище библиотека сборки также отправляет данные в QGM (Release Notes и флаги).
В разделе qgm указываются credentials, под которыми должна производиться отправка данных артефактов, а также параметр repository.
Пример заполнения:
qgm:
repository: my-repo
creds: my-qgm-creds
Заполнение раздела docker#
Раздел docker содержит следующие опции:
registry_address- адрес registry, в который должны быть загружены образы;builder_token- credentials с доступом в registry на запись вregistry_address;image_path- путь образов внутриregistry_address;args- добавляет дополнительные пользовательские параметры при исполнении команды docker build, по умолчанию выставлен флаг --no-cache=true;additional_registries- список дополнительных registry, вход в которые будет осущеcтвлен помимоregistry_address(это может потребоваться, если, например, базовый образ лежит в registry, отличном отregistry_address).
Опции для работы с разделом dockefiles, определяемые в подразделе cache:
registry- адрес registry, в который должен быть загружен кеш образа;path- путь до папки, в которой будет лежать кеш образов.credential_id- идентификатор Jenkins Credentials, который будет использован для авторизации в registry кеширования. Если параметр не задан, будет использоватьсяbuilder_tokenиз секцииdocker.
docker:
registry_address: "registry.<...>.ru"
builder_token: "b65d28a6-056a-444c-a25f-8d2b222b5d60"
additional_registries:
- registry_address1
- registry_address2
image_path: some/path/to/my/images
args: "--no-cache=true"
# Опции для работы с разделом `with_docker`
cache:
registry: "registry.<...>.ru"
path: "some/path/to/my/cache/folder"
Есть возможность отключить сборку докер-образа, добавив в Jenkins job сборки дистрибутива boolean параметр
SKIP_BUILD_DOCKER, либо добавив в pipeline.yml в раздел docker параметрskip_build_docker. Значение у параметров должно быть true.
Заполнение разделов bh, db#
Разделы bh и db сдержит список репозиториев, в которых надо выполнить сборку. Каждый элемент этого списка содержит следующие
параметры:
name - название элемента (рекомендуется использовать уникальные значения всех name во всех блоках);
repo - адрес репозитория, содержащего maven-проект;
branch - ветка репозитория;
cmd - maven-цели или плагины, которые надо вызвать (например,
package);args - дополнительные аргументы, которые необходимо добавить в каждую команду запуска (в том числе в команду запуска SonarQube);
outputs - список файлов, которые нужно скопировать в дистрибутив после сборки (выполнения всех команд из cmd);
create_tag - значение типа boolean, по умолчанию false (если значение параметра выставлено в true, то создается аннотированный тег с версией, декларированной разделом fp);
sonar_cmd (только для bh) - возможность переопределить команду запуска SonarQube-сканирования (рекомендуется использовать данный параметр, т.к. иначе работает довольно незаурядная логика, которая оставлена в угоду обратной совместимости);
sonarPomConfigured (только для bh) - если значение true, в команду запуска SonarQube-сканирования не будут внедрены дополнительные параметры;
sonarSkip - если true, пропустить SonarQube-сканирование;
sonar (только для bh) - составной параметр, содержит опции:
mainBranch - основная ветка в SonarQube;
longLivingBranchesPattern - шаблон долгоживущих веток (в терминах SonarQube).
parallel - опция использования параллельной сборки. Если для двух приложений будет указано одинаковое значение
parallel, то они будут запускаться в общем потоке. (может использоваться для сборки Dockerfiles, PL's, Jenkinsfiles, DB's и BH's.);
Отличия сборки bh и db:
Для
dbне выполняется запуск SonarQube;В результате сборки
dbдолжен появиться ZIP-архив со скриптами Liquibase.
Требования к репозиториям в разделе db и bh описаны в соответствующих разделах (db, bh).
Примеры:
bh:
- name: "bh-app-1"
repo: "project/bh-app-1.git"
branch: "release/pir1024"
args: "-f myproject/pom.xml"
cmd:
- "clean test"
- "install"
outputs:
- "myproject/bh-app-1-ear/target/*.ear"
sonarPomConfigured: true
sonar:
mainBranch: 'master'
db:
- name: "db-1"
repo: "dbufs/db-1.git"
branch: "release/pir1024"
cmd: "clean package -P!liquibase,packageOnly"
outputs:
- "./target/efsct-db*.zip"
Заполнение раздела pl#
Раздел pl содержит список nodejs-репозиториев, в которых надо выполнить сборку с помощью npm. Перед сборкой будет выполнена подгрузка зависимостей (npm ci).
Каждый элемент списка содержит следующие параметры:
name - название элемента (рекомендуется использовать уникальные значения всех name во всех блоках);
repo - адрес репозитория, содержащего maven-проект;
branch - ветка репозитория;
create_tag - значение типа boolean, по умолчанию false (если значение параметра выставлено в true, то создается аннотированный тег с версией, декларированной разделом fp);
cmd - команда сборки проекта (например,
npm build);install - альтернатива стандартной команде подгрузки зависимостей (если задана, будет выполнена вместо
npm ci);link_sshpk - если
true, перед сборкой будет выполнена командаnpm link sshpk;link_sass - если
true, перед сборкой будет выполнена командаnpm link node-sass;sonarSkip - если true, пропустить SonarQube-сканирование;
outputs - список файлов, которые нужно скопировать в дистрибутив после сборки (выполнения команды из
cmd) (файлы попадут в папкуpackage/plдистрибутива).parallel - опция использования параллельной сборки. Если для двух приложений будет указано одинаковое значение
parallel, то они будут запускаться в общем потоке. (может использоваться для сборки Dockerfiles, PL's, Jenkinsfiles, DB's и BH's.);
Пример заполнения:
pl:
- name: my-pl
repo: cije/test.app.frontend.git
branch: develop
cmd: 'npm pack'
outputs:
- '*.tgz'
Требования к самим репозиториям, перечисленным в pl, описаны в соответствующем разделе.
Заполнение раздела Jenkinsfiles#
Для подключения сборки Jenkinsfiles необходимо в файле pipeline.yml добавить блок jenkinsfiles, в котором нужно указать список репозиториев, содержащих исполняемые Jenkins файлы.
Каждый элемент из этого списка содержит следующие параметры:
name - название элемента. Рекомендуется использовать уникальные значения всех name во всех блоках;
repo - адрес репозитория, содержащего Jenkinsfile;
branch - ветка репозитория с Jenkinsfile;
sonarSkip - если true, пропустить SonarQube-сканирование;
create_tag - значение типа boolean, по умолчанию false (если значение параметра выставлено в true, то создается аннотированный тег с версией, декларированной разделом fp);
jenkinsfile_name - относительный путь к файлу с описанием сборки компонентов -
jenkinsfile(по умолчанию:Jenkinsfile);parallel - опция использования параллельной сборки. Если для двух приложений будет указано одинаковое значение
parallel, то они будут запускаться в общем потоке. (может использоваться для сборки Dockerfiles, PL's, Jenkinsfiles, DB's и BH's.);skip - если установить в
true, то сборка данного Jenkinsfile будет пропущена;Любой дополнительный набор параметров, которые нужно передать в Jenkinsfile.
Для ускорения сборки дистрибутива существует возможность параллельной сборки Jenkinsfile. Для этого необходимо использовать опцию parallel, в значении которой указывается строка.
Если для двух приложений будет указано одинаковое значение parallel, то они будут запускаться в общем потоке.
### Ссылки на сборочные Jenkins-файлы ###
jenkinsfiles:
- name: "test.app.backend" # любое
repo: "<...>/test.app.backend.git" # url без хоста
branch: "develop" # ветка сборки
- name: "test.app.frontend" # любое
repo: "<...>/test.app.frontend.git" # url без хоста
branch: "develop" # ветка сборки
parallel: front
# параметры, описанные ниже, могут быть использованы в jenkinsfile
param1: value1 # app.param1
param2: value2 # app.param2
complexParam:
attr1: value3 # app.complexParam.attr1
attr2: value4 # app.complexParam.attr2
Требования к содержимому Jenkinsfile описаны в соответствующем разделе.
Описание зависимостей дистрибутива#
Зависимости дистрибутива описываются в секции profiles. Такое название дано, поскольку все зависимости должны быть помещены под соответствующие профили, и в каждом профиле должен быть описан набор зависимостей.
Каждая зависимость описывается maven-координатами:
groupId
artifactId
version
type (необязательная координата, по умолчанию jar)
classifier (необязательная координата)
Пример:
profiles:
some-profile: # название профиля (some-profile)
- groupId: some.group.id
artifactId: some-artifact-id
version: some-version
type: zip # если зависимость - это дистрибутив - то ее type=zip
classifier: distrib # если это дистрибутив - то classifier=distrib
some-another-profile:
- groupId: some.another.group.id
artifactId: some-another-artifact-id
version: some-another-version
type: zip
classifier: distrib
Все эти зависимости будут добавлены в файл pom.xml дистрибутива.
Подключение и настройка расширений#
В конфигурации сборки есть секции, позволяющие подключать и отключать точки расширения.
Список существующих точек расширения следует смотреть в документации репозитория jenkinsfiles (репозиторий с точками расширения).
Для подключения расширения используется секция extensions. В этой секции списком указываются расширения, которые нужно подключить.
Каждый элемент списка может содержать следующие параметры:
name - название расширения. По сути, единственный обязательный параметр. Если элемент - это строка, то эта строка - значение поля name. Все остальные поля имеют дефолтные значения (указаны в скобках).
repo (<…>/jenkinsfiles.git) - репозиторий, из которого нужно взять расширение
branch (master) - ветка, из которой нужно взять расширение
jenkinsfile_name (
<name>.groovy) - название скрипта, реализующего расширениеstage (берется из
getDefaultConfigрасширения) - название этапа (stage), к которому привязывается расширение (список вариантов ниже)phase (берется из
getDefaultConfigрасширения) - фаза (до или после), в которую нужно вызвать расширениеТакже могут быть добавлены любые дополнительные параметры, которые в дальнейшем будут использованы в расширении.
Список stage:
prepare
build
downloads
docker
templating
pack
upload
Список phase:
before
after
Если в качестве элемента списка указано только название расширения, все остальные параметры рассчитываются по следующим правилам:
jenkinsfile_name = <имя расширения>.groovy
repo = <проект этого репозитория (ufs-pipeline)>/jenkinsfiles.git
branch = master Также существует возможность более гибкой настройки расширения.
extensions:
- generateJenkinsFile # будет взято расширение generateJenkinsFile.groovy из репозитория jenkinsfiles
- name: MoveDockerfile
branch: feature/superfeature # будет взято расширение MoveDockerfile.groovy из ветки feature/superfeature
- name: securityChecks
devsec_repo: 'repo' # репозиторий с библиотекой sast/oss
run_sast: true
run_oss: true
- name: MyCustomExtension
repo: myproject/myrepo.git
branch: master
jenkinsfile_name: superEx.groovy
stage: pack
phase: before
# ниже представлен набор параметров, которые может использовать расширение
param1: value1
param2: value2
param3: value3
complexParam:
someAttr1: value4
someAttr2: value5
check_rn: true
checked_flags:
- oss
- sast
При подключении точки расширения
securityChecksнеобходимо заполнить опцииdevsec_repo,rus_sast,run_ossдля корректной работы SAST/OSS сканирования
Ряд расширений включен по умолчанию:
updateVersionConf- добавляет в дистрибутив актуальный файл version.confAddDescription- добавляет в сборку описание со ссылками на загруженные артефактыanalyzeDependencies- добавляет этап анализа зависимостей собранных Docker-образовmakeReleaseNotes- добавляет сборку ReleaseNotes
Для их отключения используется секция disabled_extensions (при этом расширения, явно подключенные в разделе extensions, выключены не будут):
disabled_extensions:
- AddDescription
- analyzeDependencies
Также для поддержки обратной совместимости автоматически подключается расширение legacyMavenCoordinates в случае наличия устаревшего параметра artifact_type.
Для подключения точек расширения, не имеющих дополнительных параметров, достаточно в списке extensions указать только их название, например:
extensions:
- generateJenkinsFile
- MoveDockerfile
Рекомендации по разработке собственных точек расширения описаны в соответствующем разделе.
Конфигурирование блока downloads#
Блок downloads содержит список параметров загрузки различных файлов. Обязательные параметры:
type - тип файла. От него зависит в какую папку инсталляционного пакета он попадет. Возможные варианты описаны ниже.
source - источник файла. Набор параметров для конфигурации различается для разных источников.
dest - назначение файла. Параметр, указывающий путь назначения файла из параметра
source.
Типы файлов бывают следующими:
bh - файлы с backend двоичными данными (business hub)
pl - файлы с frontend (presentation layer)
db - файлы с liquibase-скриптами настройки БД
conf - файлы конфигурации (различные yaml, conf, json-файлы).
!!! alert "" ️ Если есть хотя бы один такой файл, то исходный репозиторий с конфигурацией в дистрибутив скопирован не будет. Чтобы сохранить в дистрибутив содержимое репозитория конфигурации, нужно добавить параметр
copyMainConfig: true.docs - файлы документации
sdk_mvn - файлы библиотек maven, распространяемых вместе с дистрибутивом. Допустимый source - только nexus, причем помимо файла будет также скачан pom-файл.
sdk_npm - файлы библиотек npm, распространяемых вместе с дистрибутивом. Допустимый source - только filesystem, причем параметры в этом случае используются иначе:
используется только параметр
subdirфайл копируется из пути
[workspace]/[subdir]требуется добавить настройку coordinates:
{name: '[name]', version: '[version]'}
Источники файлов могут быть следующими:
filesystem - текущая нода сборки. Позволяет скопировать любой файл из собранных репозиториев (
jenkinsfile/bh/plи т.д.). Связка с собранным элементом осуществляется с помощью параметраname- будет использован элемент с таким жеname. При этом настройки того, какие конкретно файлы копировать, аналогичны источнику git (кроме cmd).git - репозиторий. Для настройки используются следующие параметры:
repo - path репозитория
branch - ветка, из которой требуется скопировать файл(ы)
name - название элемента (может быть использовано для копирования элементов при
source: filesystem)subdir - будут скопированы файлы из заданной директории репозитория
files - маска, по которой будут скопированы файлы
cmd (необязательный) - при желании можно вызывать maven-команду перед копированием
nexus - maven-артефакт, который можно скачать с помощью settings.xml, указанного в разделе maven. Параметры:
groupId - groupId артефакта
artifactId - artifactId артефакта
version - версия артефакта. Если необходимо указать версию неявно (например, чтобы Jenkins job брал какую-то последнюю), следует указывать ее в формате Maven Dependency Version Ranges
classifier (необязательный) - classifier артефакта
packaging (необязательный, по умолчанию
jar) - packaging/type артефакта
confluence - скачать страничку из confluence. Для работы данного источника, нужно настроить раздел
confluence.
Пример файла конфигурации (с указанием назначения параметров в комментариях)#
### Настройки NodeJS ###
npm:
# Идентификатор файла в вашем folder, который следует подключить через configFileProvider. Рекомендуемый вариант подключения. Настройка npm-settings в Jenkins
config_id: "npm-settings"
# Версия NodeJS, настроенный в Jenkins. Доступные версии можно посмотреть в Pipeline Syntax - snippet generator - tool - NodeJS
version: "v7.5.0-linux-x64"
### Настройки MAVEN ###
maven:
# Идентификатор файла в вашем folder, который следует подключить через configFileProvider. Рекомендуемый вариант подключения.
settings_id: "maven-settings" # Настройка maven-settigns в Jenkins
# Maven настроенный в Jenkins. Один на все проекты, меняться не должен
home: "Maven 3.2.5"
# JDK настроенный в Jenkins. Один на все проекты, меняться не должен
jdk: "JDK_1.7_45_Linux"
distribution:
- url: "..."
serverId: "..."
- url: "..."
serverId: "..."
qgm:
repository: "..." # Имя репозитория Nexus
creds: "..."
profiles:
some_profile:
- groupId: "some.group.id"
artifactId: "some-artifact"
version: "D-ver"
type: zip
classifier: distrib
# Профиль binaries обязателен для дистрибутива конфигураций. При сборке binary загружаются и распакуются в папку дистрибутива
binaries:
- groupId: "some.group.id"
artifactId: "some-artifactId-bin"
version: "D-01.004.05-765"
type: zip
classifier: distrib
extensions:
- name: std5Configuration
### Настройки CONFLUENCE ###
confluence:
# ID данных авторизации в Confluence. Используем credentialsId, полученный на шаге Настройка Jenkins
creds: "ad50b262-dda8-4fae-a0d5-45b9e16041b8"
# Корневую ссылку Confluence можно задать в виде root_url. Один на все проекты - можно не менять
root_url: "https://confluence.ca.<host-name>"
### Настройки SW.META ###
meta:
# ID данных авторизации в SW.META. Используем credentialsId ТУЗ с правами загрузки модели
creds: "ad50b262-dda8-4fae-a0d5-45b9e16041b8"
# Корневая ссылка API SW.META
# Если не указана будет использована https://meta.<domain>/basic для ALPHA,
# для SIGMA: https://meta.<domain>
root_url: "https://meta.<domain>/basic"
# Код компонента из ARIS. Также можно посмотреть на портале META в карточке своей АС.
code: "ad50b262-dda8-4fae-a0d5-45b9e16041b8"
### Настройки сборки приложения ###
fp:
# Maven groupId для артефакта инсталляционного пакета.
groupId: "AS_EFS.AS_EFS_???.Distrib"
# Maven artifactId для артефакта инсталляционного пакета.
artifactId: "AS_EFS_???"
# Maven version для артефакта инсталляционного пакета. К нему будет добавляться номер сборки, в результате для собрки с номером 123 в Nexus будет выгружен артефакт с версией D-01.000.00-123
version: "D-01.000.00"
# Добавляет постфикс к версии дистрибутива в формате version-BUILD_NUMBER_version_meta, например D-01.000.00-472_SECTOR_1
version_meta: "SECTOR_1"
### Список приложений BH, которые нужно собрать из исходников ###
bh:
# ID приложения. Используется при сборке как название папки куда клонируется репозиторий
- name: "bh-app-1"
# путь к репозиторию в Bitbucket, где лежат исходники приложения
repo: "project/bh-app-1.git"
# ветка, которую нужно собирать
branch: "release/pir1024"
# аргументы Maven, например, можно указать относительный путь к pom.xml, который нужно собрать
args: "-f subfolder/pom.xml"
# команды Maven, которыми собираем проект
cmd:
- "clean test"
- "install"
# Список шаблонов файлов, которые нужно скопировать в инсталляционный пакет после сборки (задается относительно корня репозитория)
outputs:
- "./bh-app-1-ear/target/*.ear"
# Необязательный параметр. По умолчанию: false. true - в случае, если для запуска проверки SonarQube QG достаточно выполнить sonar:sonar
sonarPomConfigured: false,
# Необязательный параметр. По умолчанию false. true - в случае для модулей, не попадающих в ПРОМ и не требующих прохождения QG (например, envelope ear для развертывания jar на тестовые стенды)
sonarSkip: false,
skip_rn: true, # Используется для того, чтобы пропустить сбор Release Notes для данного репозитория
prod_branch: 'release/18.5', #если хотим указать для репозитория версию ПРОМ
issue_pattern: '[A-Za-z][A-Za-z0-9]+-[0-9]+' # Регулярное выражение, по которому определяется идентификатор запроса в JIRA из commit. Если хотим отличное от приведенного - указываем его.
sast_skip: true # По умолчанию: false. При значении true отключает сканирование репозитория sast/oss
parallel: parallel # Запустить параллельную сборку с именем потока parallel
### Список приложений PL, которые нужно собрать из исходников ###
pl:
# ID приложения. Используется при сборке как название папки куда клонируется репозиторий
- name: "pl-app-1"
# Путь к репозиторию в BitBucket, где лежат исходники приложения
repo: "project/pl-app-1.git"
# Ветка, которую нужно собирать
branch: "release/pir1024"
# Команда которой осуществляется сборка
# cmd: "npm run build"
cmd: "node ./scripts/profile.js"
# Создавать ли символическую ссылку (симлинк) на локальный node-sass, установленный в Jenkins
link_sass: false
# Создавать ли симлинк на локальный sshpk установленный в Jenkins
link_sshpk: false
# Пропустить сбор Release Notes для данного репозитория
skip_rn: true
# Список шаблонов файлов, которые нужно скопировать в инсталляционный пакет после сборки (задается относительно корня репозитория)
outputs:
- "./archive/dist*.zip"
sast_skip: true # По умолчанию false. При значении true отключает сканирование репозитория sast/oss
parallel: parallel # Запустить параллельную сборку с именем потока parallel
### Список скриптов БД, которые нужно собрать из исходников ###
db:
# Сборка осуществляется так же как и сборка BH, все параметры аналогичны
- name: "db-1"
repo: "dbufs/db-1.git"
branch: "release/pir1024"
# Команда для сборки только одного подпроекта в многомодульном проекте
cmd: "clean package -P!liquibase,packageOnly"
args: "-f project/pom.xml",
outputs:
- "./project/target/efsct-db*.zip"
parallel: parallel # Запустить параллельную сборку с именем потока parallel
### Список артефактов, которые нужно загрузить из Nexus ###
downloads:
- {source: "confluence", type: "docs", pages: ['98876674']}
- {source: "nexus", type: "db", repoId: "efs_release_db", groupId: "ru.<host-name>.database", artifactId: "project-db", version: "26.*", packaging: "zip"}
- {source: "git", type: "docs", repo: "smefs/startmanager-bh.git", branch: "develop", subdir: "authorization-parent/docs", files: "*.docx", sast_skip: true}
- {source: "git", dest: "$WORKSPACE/sources/", repo: "smefs/startmanager-bh.git", branch: "develop", subdir: "tmp/source", files: "*.txt", sast_skip: true}
- {source: "git", type: "docs", repo: "smefs/startmanager-bh.git", branch: "develop", subdir: "authorization-parent/docs", files: "\"Инструкция по сборке.docx\""}
# Следующая директива позволит взять каталог (вместе со своим содержимым) {WORKSPACE}/sources/sm-uko-root/sm-uko/target/conf и положить его в дистрибутив
- {source: "filesystem", type: "conf", subdir: "sm-uko/target/conf", files: "*", name: "sm-uko-root", copyMainConfig: true}
# Добавление sdk для архива компонента происходит через nexus, файлы помещаются в репозиторий в package/sdk/mvn/
- { source: "nexus", type: "sdk_mvn", repoId: "ufs-platform_thirdparty", groupId: "com.github.qwazer", artifactId: "markdown-confluence-gradle-plugin", version: "0.8.999", packaging: "jar" }
# Добавление sdk для архива бинарных артефактов происходит через filesystem, файлы помещаются в репозиторий в package/sdk/npm/
- { source: "filesystem", type: "sdk_npm", subdir: ".npm/commander/2.20.3/package.tgz", coordinates: { name: commander, version: 2.20.3 } }
docker:
# Токен для логина в registry
#builder_token: "ose_openshift_devopsefs_key"
builder_token: "token"
# Ссылка на registry
#registry_address: "docker-registry-default.apps.test-ose.ca.<host-name>"
registry_address: "registry.<host-name>"
# адрес Nexus3 registry
image_path: "registry_url"
# массив из дополнительных ссылок на registry, для чтения; используется единый Credential для доступа во все Nexus репозитории, указанный в builder_token
additional_registries:
- "registry_address1"
- "registry_address2"
### Настройки DevSecOps ###
### Общая информация о командах ###
team:
- {
# Код команды в МУСе.
# Если не сработает код команды в МУСе, то можно попробовать прописать логин ТУЗа, который используется для сканирования в Checkmarx
mus_code: "command_code",
# название команды в МУСе
mus_name: "command_name",
# Почтовый адрес Product Owner в МУСе для уведомлений с результатами сканирования
# !!! Почта должна быть валидной для текущего домена, чтобы корректно определить пользователя, которому впоследствии предоставятся права на доступ к АС в SALM !!!
# !!! Возможно указание нескольких почт через знаки ";" или "," внутри одной строки !!!
# Пример: "user1@sberbank.ru; user2@sberbank.ru, user3@sberbank.ru"
mus_po_mail: "user1@sberbank.ru; user2@sberbank.ru, user3@sberbank.ru",
}
# Возможно добавление нескольких команд
# !!! Вторую и последующие команды необходимо добавить по формату, аналогичному первой !!!
# - {
# mus_code: "00040018",
# mus_name: "Web SBOL Design",
# mus_po_mail: "sspetrov@sberbank.ru",
# }
### Общая информация о приложении ###
app:
# Конфигурационный элемент (КЭ) приложения / модуля ПО в Service Manager.
# !!! КЭ должен быть строкой, состоящей исключительно из цифр без лидирующих нулей !!!
sm_id: "number_id"
# название КЭ приложения / модуля ПО в Service Manager
sm_name: "app_name"
### Настройки SAST Checkmarx ###
sast_cx:
# Credentials ID в Jenkins для учетной записи Checkmarx одной команды, под которой будет проводиться сканирование
creds_id: "creds"
# проектная область в JIRA для заведения и синхронизации дефектов
jira_area: "area"
# Маски файлов и директорий для включения (**/*) в скан и исключения (!**/*) из скана.
# Пример: "!**/utils/**/*.xml" - исключение всех xml файлов в папке utils
masks: ""
# ID профиля сканирования, по умолчанию 36. 14 - для мобильного приложения. 100003 - Smoke
preset_id: "36"
# Максимальное время ожидания статуса QG в минутах
wait_qg: "2"
### Настройки OSS
oss:
# Маски файлов и директорий для исключения из сканирования
# Пример: "**/utils/**/*.xml" - исключение всех xml файлов во всех папках utils
# !!! Перечисление нескольких масок возможно через знаки "," или ";" внутри одной строки, например, "**/*test*/**; **/*.txt, .git/**" !!!
# !!! Пропуски в каждой маске справа и слева автоматически удалятся (trim) !!!
excludes: ""
Параметризация pipeline.yml#
В любой параметр в файле pipeline.yml есть возможность подставить значение переменной из environment.
Допустим, необходимо параметризовать секцию distribution в файле pipeline.yml.
Тогда конфигурация должна выглядеть следующим образом:
distribution:
- url: "${DISTRIBUTION_URL}"
serverId: "${DISTRIBUTION_SERVER_ID}"
В Jenkins job сборки дистрибутива необходимо добавить значения для одноименных параметров:
DISTRIBUTION_URL
DISTRIBUTION_SERVER_ID
По умолчанию параметризация конфигурации выключена. Для ее использования добавьте в Jenkins job сборки скрипта параметр "PARAMETERIZATION_YML" со значением true.
Важно
Перед тем, как использовать параметризацию необходимо:
Убедиться в отсутствии символов
$в том числе, в комментариях.Экранировать
\: вместо записиabc\, использовать записьabc\\.
Объявление переменных окружения через pipeline.yml#
Для объявления переменных окружения необходимо определить раздел env в pipeline.yml и произвести перечисление определений в формате key: value:
env:
ENV_KEY_0: env-value-0
ENV_KEY_1: env-value-1
...
Объявленные через pipeline.yml переменные окружения могут быть использованы как в разработке, так и для параметризации самого pipeline.yml
Список переменных окружения (к описанию), которые не должны быть объявлены через pipeline.yml:
IMAGE_CREATOR_BRANCH;
BASE_BRANCH;
EXTENSION_BRANCH;
JENKINS_NODE;
CONFIG_FILE;
CONFIG_BRANCH;
CONFIG_REPO;
CONFIG_DIR;
GIT_CREDS;
GIT_URL;
PLAYBOOKS.
Настройка Jenkins job#
В данном разделе описаны этапы настройки Jenkins job, которые могут быть использованы. Создание job (с нуля) описано в соответствующем разделе.
Параметр PLAYBOOKS#
Параметр PLAYBOOKS позволяет выбрать, какие именно операции при сборке дистрибутива следует выполнить.
Ниже указаны возможные варианты сценариев (playbooks). Сценарии, отличные от fp-deploy-<...>, run-sast, run-oss, предназначены для
целей отладки, т.к. позволяют выполнять сборку отдельных разделов файла pipeline.yml без публикации дистрибутива.
Если название или описание какого-либо из отладочных сценариев вам непонятно - не используйте его.
Playbook |
Описание |
|---|---|
fp-deploy-<…> |
Сборка проекта и выгрузка в Nexus. В случае выбора этого списка сценариев (playbook) для запуска будут выполнены все этапы сборки (кроме SAST/OSS) |
run-sast |
Запуск проверки SAST |
run-oss |
Запуск проверки OSS |
docker_build |
Сборка и доставка docker образов |
build-bh |
Сборка BH |
build-pl |
Сборка PL |
build-downloads |
Сборка блока downloads. При выборе будет выполнена логика загрузки ресурсов из секции pipeline.yml → downloads в процессе сборки дистрибутива |
doc-build |
Сборка документации |
build-db |
Отдельная сборка DB |
build-<Х> |
<Х> в данном случае - это |
Подробнее о build-
Для сборки всех Jenkins-файлов, перечисленных в конфигурационном файле pipeline.yml, необходимо в параметр PLAYBOOKS добавить значение
build-jenkinsfilesи выбрать его при запуске Jenkins job.Для сборки определенного Jenkins-файла необходимо в параметр PLAYBOOKS добавить и выбрать при запуске значение, равное
build-$jenkinsfiles.nameиз файла pipeline.yml.
Данное поведение доступно, только если выключен сценарий fp-deploy-<...>
Параметр type: String Parameter#
Настройки этого типа могут быть указаны как в параметрах Jenkins job, так и в настройках ее окружения (опция Prepare an environment for the run).
Имя |
Значение по умолчанию |
Описание |
|---|---|---|
EMAIL_LIST |
– |
Список email адресов, на которые будут отправляться отчеты с результатами запуска сборки. Если задан - будет активирована рассылка. |
CONFIG_REPO |
– |
Путь к репозиторию, в котором хранится конфигурация проекта. Если полная ссылка для git clone выглядит как |
CONFIG_BRANCH |
master |
Ветка в репозитории CONFIG_REPO. Этот параметр необязательный. Именно поэтому для него указано значение по умолчанию. |
CONFIG_FILE |
pipeline.yml |
Путь к файлу конфигурации pipeline из репозитория CONFIG_REPO. Этот параметр необязательный. Именно поэтому для него указано значение по умолчанию. |
CONFIG_DIR |
. |
Возможность работы с подпапками конфигураций. Если выбрать данный параметр, то можно указать отдельную папку из репозитория конфигураций. |
JENKINS_NODE |
clearAgent |
Используется для лейбла агента Jenkins на котором будет осуществляться сборка. Этот параметр необязательный. Именно поэтому для него указано значение по умолчанию. |
DB_REPO_PATH |
dbufs/settings.git |
Используется для выбора пути к репозиторию из файла settings.xml в целях сборки скриптов БД. |
DB_REPO_BRANCH |
develop |
Используется для выбора ветки или определенного commit в репозитории с файла settings.xml в целях сборки скриптов БД. |
PLATFORM_RELEASE |
– |
Если задан - в файле version.conf запишется значение в параметр platformRelease. |
AT_BRANCH |
– |
Если задан - в файле version.conf запишется значение в параметр atBranch. |
SONAR_JDK |
– |
Используется для переопределения используемой версии JDK для анализа в SonarQube (по умолчанию JDK_1.8_121_Linux). Параметр необязательный. |
PARAMETERIZATION_YML |
false |
Включает параметризацию файла pipeline.yml. |
GIT_HTTP_URL |
- |
Если задан - значение запишется в pom.xml в тег scm/url. |
Параметр type: Boolean Parameter#
Данные параметры НЕ могут быть настроены с помощью переменных окружения Jenkins job и должны быть строго ограничены параметрами типа Boolean.
Имя |
Значение по умолчанию |
Описание |
|---|---|---|
DEBUG_ENABLED |
False (unchecked) |
Вывод отладочной информации. |
TAG_CONFIG_REPO |
False (unchecked) |
Проставление тега (версия N собрана из данного commit) на репозиторий конфигураций проекта после успешной сборки дистрибутива и выгрузки. |
Заполнение конфигурации скриптов развертывания#
Чтобы pipeline мог установить приложения на стенд, также необходимо заполнить конфигурацию скриптов развертывания.
В репозитории конфигурации проекта (рядом с файлом pipeline.yml) необходимо добавить файлы:
config-was-app.yml;
distrib.yml;
locations.conf.j2.
Миграция на текущую версию#
Миграция на текущую версию (с версии 1.3) заключается в изменении pipeline.yml:
Актуализировать секцию fp.
Актуализировать секцию maven - параметр
use_for_deployболее не актуален и его следует удалить.Создать секцию distribution - настройки берутся из nexus_<…>.
Создать секцию qgm - настройки берутся из
nexus_<...>.Удалить секцию
nexus_<...>.Удалить секцию
nexus.Перенести component_code в секцию
fp.
Также, если собирается составной дистрибутив:
убрать из
pipeline.ymlпараметрыartifact_type,config_kind,binaries_versionвыполнить настройки в соответствии с разделом Сборка составного дистрибутива
Разработка первого приложения с использованием программного компонента#
Подключение и конфигурирование
Настройка конфигурационных файлов в Jenkins#
Создание конфигурационного файла производится с помощью функции Jenkins, которая называется Config Files:
В созданной области (папке) Jenkins перейти в Config Files → нажать на Add a new Config.
Выбрать Type конфигурационного файла.
В ID записать идентификатор, который затем будет указываться в файле *pipeline.yml. После чего нажать Submit.
Заполнить content для определнного типа конфигурационного файла.
Пример создания settings.xml#
Чтобы создать settings.xml, необходимо:
В качестве Type для создания нового конфигурационного файла выбрать
Maven settings.xml.Указать ID конфигурационного файла, например -
maven-settings.В поле **content необходимо добавить содержимое settings.xml (того, что используется для сборки артефактов), но без раздела
servers(об этом далее).Раздел
serversв settings.xml заполняется в Jenkins с использованием credentials. Для их добавления необходимо воспользоваться кнопкой Add - следует указать корректныеserverId, чтобы они совпадали сIDподключаемых репозиториев.
Для загрузки дистрибутива во внешний репозиторий, определенный разделом distribution в
pipeline.yml, необходимо заполнить соответствующиеserverIdвsettings.xml(см. п.4) с правами на запись
Пример заполнения settings.xml:
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0">
<mirrors>
<mirror>
<id>central</id>
<name>Mirror of public repositories</name>
<url>https://nexus.mycompany.com/nexus/content/repositories/mirror-central</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
<profiles>
<profile>
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<repositories>
<repository>
<id>cdp</id>
<name>distribution repo</name>
<url>https://nexus.mycompany.com/nexus/content/repositories/distribution</url>
</repository>
</repositories>
</profile>
</profiles>
</settings>
Пример создания .npmrc#
Чтобы создать .npmrc, необходимо:
В качестве Type для создания нового конфигурационного файла выбрать
Npm config file.Указать ID конфигурационного файла, например -
npmrc.В поле **content необходимо добавить содержимое .npmrc вашего проекта.
Пример заполнения .npmrc:
//registry.host/path/to/repo/npm/:_authToken=<authToken> ; BASE64_STRING это строка из профиля пользователя. Инструкция по получению ниже
registry=https://registry.host/path/to/repo/npm/
audit=false
always-auth=true
fetch-retries=5
cafile=/local path/ca_root.pem ; Необходимо для проверки отношений доверия ресурсам, если сертификата нет, можно отключить проверку. Инструкция по получению находится ниже
strict-ssl=false ; Отключение проверки сертификата при ошибках доверия
save-exact=true ; Опционально для сохранения в package.json версии скачанного пакета (до максимально доступной патч версии(без ^))
Создание Jenkins job#
Перед созданием Jenkins job должны быть выполнены шаги из раздела Системные требования, а также сформирован файл pipeline.yml.
Для создания Jenkins job сборки необходимо в используемом пространстве (папке) Jenkins выбрать → New Item → указать имя Jenkins job и указать тип Pipeline.
После чего откроется страница настроек.
Ниже описаны необходимые настройки:
Раздел Pipeline → Definition : Pipeline script from SCM.
Pipeline → SCM : Git.
Pipeline → SCM → Repositories → Repository URL :
ssh://git@<...>/ufs-pipeline.git(ssh-адрес репозитория ufs-pipeline).Pipeline → SCM → Repositories → Credentials : Используйте SSH credentials используемой ТУЗ.
Pipeline → SCM → Branches to build → Branch Specifier (blank for 'any') : master.
если требуется использование какой-либо конкретной версии библиотеки, можно использотовать соответствующий тег, например:
tags/1.4.1-*
Pipeline → Script Path → pipeline.groovy.
Lightweight checkout → true.

После сохранения Jenkins job появится возможность его запуска.
Первичная настройка Jenkins job#
В большинстве случаев какая-либо специальная настройка параметров Jenkins job не требуется. Все необходимые параметры будут добавлены в Jenkins job при первом запуске:
PLAYBOOKS - сценарии запуска. Более подробно описано ниже.
CONFIG_REPO - репозиторий с конфигурацией - тот, в котором хранится pipeline.yml, а также остальные конфигурационные файлы.
CONFIG_BRANCH - ветка репозитория с конфигурацией.
EMAIL_LIST - список рассылки, для уведомлений о сборках.
В инструкции приведен список настроек, которые могут быть использованы при настройке Jenkins job.
Подключение библиотеки без DPMPipelineUtils#
Существует также и другой вариант подключения библиотеки.
Для этого необходимо выбрать для Pipeline definition вариант Pipeline script.
После чего, в окне кода ввести следующие строки:
def creds = 'ssh-tuz' // Используйте ssh credentials вашего ТУЗа
def gitUrl = 'ssh://<...>/ufs-pipeline.git'
def branch = 'master'
def scm = [
$class: 'GitSCM',
branches: [[name: branch]],
userRemoteConfigs: [[
credentialsId: creds,
url: gitUrl
]]
]
library identifier: "ufs-pipeline@$branch", retriever: legacySCM(scm)
ansiColor('xterm') {
runPipeline(scm)
}
Детали настройки статического анализа кода#
Настройка SonarQube для проектов Development Pipeline#
Подготовка к работе#
Для подготовки SonarQube к работе необходимо выполнить следующие действия:
Получить доступ к SonarQube.
Создать проектную область с помощью Jenkins:
Область в SonarQube (PROJECT_KEY) для maven проектов рекомендуется создавать по GroupId:ArtifactId.
Организовать доступ участников к проектной области.
Осуществить настройку анализа.
Осуществить настройку в файлах settings.xml, pom.xml.
Настроить SonarQube для PR.
Для получения доступа необходимо выполнить вход в SonarQube. В таком случае используемая для входа учетная запись будет добавлена в SonarQube, после чего ее можно будет добавить в администраторы проекта при создании посредством Jenkins job
Настройка анализа при сборке дистрибутива#
При подготовке к сканированию следует также добавить в свой проект Jenkins credential c типом (Kind) - Secret text. Его идентификатор нужно указать в pipeline.yml в разделе SonarQube
Для анализа в SonarQube используемые параметры в файле pipeline.yml: sonarSkip, sonarPomConfigured.
sonarSkip – необязательный параметр, по-умолчанию:
false. Значениеtrueуказывается для модулей, не попадающих в пром и не требующих прохождения QG (например envelope ear для развертывания jar на тестовые стенды).sonarPomConfigured – необязательный параметр, по-умолчанию:
false. Значениеtrueуказывается для запуска проверки SonarQube QG, достаточно выполнитьsonar:sonar.
Внимание!
Если не указаны параметры sonarPomConfigured: true, либо sonar.projectKey в properties в файле pom.xml, то в качестве sonar.projectKey прописывается название репозитория. Таким образом подключение к SonarQube будет выполнено с названием репозитория. Если проект в сонаре был создан с GroupId:ArtifactId, то Jenkins job не увидит проект в SonarQube без параметров sonarPomConfigured: true, либо sonar.projectKey.
В файле pipeline.yml в разделе bh можно указать следующую настройку - sonar: {mainBranch: 'master'}. По умолчанию defaultbranch - develop. Эта настройка необходима, если defaultBranch отличается.
bh:
- name: "bh-app-1"
repo: "project/bh-app-1.git"
branch: "release/pir1024"
sonar: {mainBranch: 'master'}
cmd: "clean test"
outputs:
- "./bh-app-1-ear/target/*.ear"
В параметрах Jenkins job можно указать SONAR_DISABLED.
Если глобально необходимо пропустить SonarQube, то можно указать параметр SONAR_DISABLED, также данный параметр выключает ожидание ответа от сонара.
⚠ ️Внимание!В случае с параметром SONAR_DISABLED у сборки не появится флагci_ok, а следовательно, она не попадет на ПСИ.
Также существует возможность установить собственную настройку SonarQube с помощью параметра sonar_cmd в файле pipeline.yml в блоке bh.
Например: sonar_cmd: "sonar:sonar -Dsonar.login=token -Dsonar.branch.name=ufs-pipieline-test".
Данная строка полностью будет воспроизведена при запуске Pipeline, как есть. Другие параметры будут взяты из файла pom.xml/settings.xml.
В параметре Jenkins job можно указать версию JDK для анализа в сонаре через строковый параметр SONAR_JDK. По умолчанию используется версия JDK_1.8_121_Linux.
Настройки в settings.xml, pom.xml#
В файле settings.xml можно указать:
<settings>
<profile>
<id>sonar</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<sonar.host.url>${env.SONAR_HOST_URL}</sonar.host.url>
<sonar.login>${env.SONAR_AUTH_TOKEN}</sonar.login>
</profile>
</settings>
Для первоначального анализа проекта необходимо выполнить запуск на
masterветке. Для этих целей можно создать тестовый Jenkins job с типом Pipeline, либо запустить из командной строки с указанием своих данных. В случае если была проведена настройка в файлах pom.xml, settings.xml, то в Jenkins job достаточноmvn sonar:sonar:
mvn sonar:sonar -Dsonar.host.url=https://sonar.example/sonar -Dsonar.login=SONAR_TOKEN -Dsonar.projectName=ProjectName
В файле pom.xml указываются следующие данные:
sonar.projectKey
Мультимодульные проекты – это проекты, выделяемые в том случае, когда в головном файле pom.xml указывается несколько модулей в разделе modules, например:
<modules>
<module>name-exchange-bh</module>
<module>name-exchange-war</module>
<module>name-exchange-ear</module>
</modules>
Для мультимодульных проектов лучшее решение – использовать проект с ключом groupId:artifactId.
<properties>
<sonar.java.source>1.8</sonar.java.source>
<sonar.projectKey>${project.artifactId}</sonar.projectKey>
<sonar.host.url>${env.SONAR_HOST_URL}</sonar.host.url>
<sonar.login>${env.SONAR_AUTH_TOKEN}</sonar.login>
</properties>
В случае с многомодульными проектами Maven возможно возникновение рекурсии и переполнение стека с ошибкой StackOverflowError. Причиной ошибки может быть установленное в корневом POM свойство <sonar.projectKey>projectKey</sonar.projectKey>.
При WorkDirectoriesInitializer.cleanAllWorkingDirs рекурсии по проекту вычисляется ключ для каждого модуля, однако это происходит путем чтения свойства sonar.projectKey. Поскольку это одинаковое значение для каждого модуля, рекурсия никогда не завершается и стек переполняется.
Исправление заключается в добавлении <sonar.moduleKey>${project.artifactId}</sonar.moduleKey> к корневому POM, который оценивает разные значения для каждого подмодуля и, таким образом, позволяет завершить рекурсию.
В этом случае можно указать sonar.projectKey в виде ${project.groupId}:${project.artifactId}:
<properties>
<sonar.java.source>1.8</sonar.java.source>
<sonar.projectKey>${project.groupId}:${project.artifactId}</sonar.projectKey>
<sonar.moduleKey>${project.artifactId}</sonar.moduleKey>
<sonar.host.url>${env.SONAR_HOST_URL}</sonar.host.url>
<sonar.login>${env.SONAR_AUTH_TOKEN}</sonar.login>
</properties>
Для не мультимодульных проектов запись осуществляется в виде – <sonar.projectKey>${project.groupId}:${project.artifactId}</sonar.projectKey>, либо можно указать sonarPomConfigured: true в файле pipeline.yml для каждого репозитория bh.
<properties>
<sonar.java.source>1.8</sonar.java.source>
<sonar.projectKey>${project.artifactId}</sonar.projectKey>
<sonar.host.url>${env.SONAR_HOST_URL}</sonar.host.url>
<sonar.login>${env.SONAR_AUTH_TOKEN}</sonar.login>
</properties>
Область в сонаре (PROJECT_KEY) необходимо создавать по
GroupId:ArtifactId.
Если данные для проекта явно не указаны в файле settings.xml, то они берутся из корневого файла pom.xml. Ключ проекта будет сформирован как groupId:artefactId. В случае не указывания данных в pom.xml ключ по умолчанию будет формироваться с названием репозитория, т.е. область в SonarQube ищется по названию репозитория в bh.
Ключ проекта может быть указан непосредственно в файле settings.xml с помощью параметра sonar.projectKey (однако это не работает для многомодульных проектов, поскольку будет собран только первый POM).
Также Maven можно вызывать с параметрами, добавив при этом собственные данные в sonar-project.properties:
sonar.projectKey=
sonar.projectName=
sonar.projectVersion=${project.version}
sonar.sources=*/src
sonar.language=java
sonar.sourceEncoding=UTF-8
sonar.java.binaries=*/target/classes
sonar.locale=ru_RU
Настройка SonarQube для PR#
Maven может также быть вызван с параметрами при добавлении собственных данных в Properties:
sonar.projectKey=
maven.compiler.sources=
maven.compiler.target=
sonar.branch.name=${PULL_REQUEST_FROM_BRANCH}
sonar.branch.target=${PULL_REQUEST_TO_BRANCH}
sonar.login=$SONAR_TOKEN
sonar.host.url=https://<domain>-sonarqube.example.ru
Настройки, которые при этом необходимо указать в файле settings.xml:
<profile>
<id>sonar</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<sonar.host.url>${env.SONAR_HOST_URL}</sonar.host.url>
<sonar.login>${env.SONAR_AUTH_TOKEN}</sonar.login>
</properties>
</profile>
Настройка SonarQube в общем случае#
Пример настройки SonarQube. Подробнее о том, как задать значение tool name: Поиск инструментов сборки.
def onDistrib(app, distr) {
nodejs(configId: 'test.app.npmrc', nodeJSInstallationName: 'v7.5.0-linux-x64') {
sh 'npm ci'
sh 'npm run build'
withEnv(["PATH+SCANNER=${tool name: 'SonarQube_Scanner'}"]) {
sh "sonar-scanner -Dsonar.host.url=${env.SONAR_HOST_URL} -Dsonar.login=${env.SONAR_AUTH_TOKEN} -Dsonar.projectKey=my-app"
}
}
}
return wrapJenkinsfile(this)
Библиотеки используемые в ufs-pipeline#
Артефакт ufs-pipeline подключает и использует следующие библиотеки:
image-creator
По умолчанию ufs-pipeline подключает master ветку библиотек.
Переопределить ветку используемой библиотеки можно путем добавления соответствующего параметра:
Параметр type: String parameter
IMAGE_CREATOR_BRANCH
Сборка без использования pipeline.yml#
Предусмотрена возможность использования библиотеки без pipeline.yml (либо перезапись параметров оттуда). Например, вам требуется временно поменять ТУЗ для выгрузки в Nexus без лишних коммитов, или изменить настройки Maven. Для этого необходимо подключить библиотеку ufs-pipeline таким образом: выбираете вместо Pipeline script from SCM пункт Pipeline script.
Пример заполнения Pipeline script#
def creds = 'sshTechCreds' //используйте SSH Credentials вашего ТУЗа
def gitUrl = 'ssh://git@hostname:port/ufs_ci/ufs-pipeline.git' // наша библиотека
def branch = 'master'
// Объект системы контроля версий, оставляете как здесь
def scm = [
$class: 'GitSCM',
branches: [[name: branch]],
userRemoteConfigs: [[
credentialsId: creds,
url: gitUrl
]]
]
// Подключение библиотек
library identifier: "ufs-pipeline@$branch", retriever: legacySCM(scm)
@Library('DPMPipelineUtils@1.4') _
// Конфигурационный файл с вашими параметрами
def pipelineMaven = [maven:[settings_id: "test.app.settings", home: "Maven 3.5.2", jdk: "JDK_1.8_72_Linux"]]
// Запуск pipeline
runPipeline(scm, pipelineMaven)
Использование программного компонента#
Сборка составного дистрибутива#
Использование составных дистрибутивов рекомендуется с целью:
Ускорения сборки в случае изменения конфигураций;
Уменьшения расхода места в Хранилище дистрибутивов;
Возможности использовать для разных сегментов одну кодовую базу с разными конфигурациями.
Артефакты составного дистрибутива#
Бинарные файлы - собранные приложения для дистрибутива.
Конфигурации - конфигурация дистрибутива. В данном артефакте прописана зависимость на бинарные (исполняемые) файлы.
Архивация в ZIP конечного дистрибутива производится через указание маски включаемых папок/файлов в стиле Ant. По умолчанию, в дистрибутив попадает только содержимое папки
package
Сборка исполняемого файла#
Для того чтобы собрать исполняемый файл необходимо:
Создать отдельный файл pipeline.yml (отдельный файл или отдельный репозиторий с этим файлом);
В нем включить расширение std5Binaries:
extensions: - std5BinariesЗапустить Jenkins job сборки, указав с помощью параметров расположение файла конфигурации (
CONFIG_REPO/CONFIG_FILE/CONFIG_BRANCH/CONFIG_DIR);Отметить версию, с которой был выложен исполняемый файл, она потребуется для сборки конфигураций;
Сборка конфигураций#
Аналогично пункту 1 раздела «Сборка исполняемого файла».
В файле pipeline.yml добавить зависимость (дистрибутив, собранный согласно разделу «Сборка исполняемого файла») в профиле binaries:
profiles: binaries: - groupId: my.group.id # groupId из сборки binaries artifactId: my-artifact-bin # artifactId из сборки binaries version: D-01.004.03-453 # В данном случае использована версия дистрибутива, указанная в шаге 4 сборки binary type: zip classifier: distribВ файле pipeline.yml добавить расширение std5Configuration
extensions:
- std5Configuration
аналогично пункту 3 раздела «Сборка исполняемого файла».
В одном из начальных этапов сборки будет скачана зависимость из профиля
binaries.В pom.xml дистрибутива появятся все профили со всеми зависимостями, описанные в разделе
profiles
Ограничения#
При сборке исполняемых файлов из дистрибутива исключаются все конфигурации.
При сборке конфигураций из дистрибутива исключаются все исполняемые файлы (pl, bh и пр.).
Загрузка логических моделей данных (LDM) при сборке дистрибутива#
Для того, чтобы при сборке дистрибутива выполнялась отправка логических моделей данных в сервис META, необходимо:
Разработать логические модели данных, содержащие ПДн, БТ, ДПК в формате JSON в соответствии с требованиями Разработки логических моделей данных АС;
Разместить модели в директории dataModel репозитория конфигурации проекта;
Зарегистрировать ТУЗ с правами загрузки моделей в META;
Выяснить код компонента используемого приложения в ARIS;
Добавить настройки для работы с сервисом МЕТА в файл pipeline.yml.
При размещении моделей в директории dataModel необходимо соблюдать правила именования:
model-pd.json - имя файла для модели ПДн;
model-bs.json - имя файла для модели БТ;
model-pcidss.json - имя файла для модели ДПК.
При разработке логических моделей данных необходимо соблюдать уникальность имени и кода модели.
Рекомендации по заполнению полей code и name (замените CI00000000 на КЭ вашего приложения):
"name": "CI00000000 Логическая модель данных PD",
"code": "CI00000000_LDM_PD",
"name": "CI00000000 Логическая модель данных BS",
"code": "CI00000000_LDM_BS",
"name": "CI00000000 Логическая модель данных PCI_DSS",
"code": "CI00000000_LDM_PCI_DSS",
Настройка динамических параметров#
Для получения необходимых параметров сборки при установке в OpenShift предусмотрены placeholders вида ${build: <parameter>}, значения которых будут проставлены в процессе выполнения Pipeline:
jenkins_env.fp_artifact_version - версия текущей сборки. Пример шаблона:
${build: jenkins_env.fp_artifact_version }jenkins_env.
<image-name>.fp_image_hash - хэш сумма, получившегося при сборке образа приложения, где<image-name>- название deployment unit. Пример шаблона:image:https://nexus3.<...>.ru/efs/ci00428440_efs/ci01947988_integration_routing/ufs-routing@${build: jenkins_env.deployment_unit_folder.fp_image_hash }
При использовании данного функционала необходимо исключить символ -
.- в названии deployment unit директории (<image-name>)
Использование sha-суммы обусловлено требованиями безопасности и новым стандартом формирования дистрибутива ОСЕ.
Обратите внимание, что в отличие от версии, sha-сумма отделяется от имени образа не двоеточием
:, а символом@. Таким образом поле image имеет формат:https://registry_host/image_url@${build: jenkins_env.fp_image_hash }
Данный placeholder необходимо использовать только в поле image, которое соответствует ВАШЕМУ образу. В sidecar и остальных полях файла менять ничего не нужно!
Значения следующих placeholders вида ${build: <parameter>} проставляются из вашего pipeline.yml:
fp.groupId, fp.artifactId, fp.version - groupId, artifactId, version - координаты дистрибутива в Nexus. Пример шаблона:
${build: fp.version}profiles.binaries.groupId, profiles.binaries.artifactId, profiles.binaries.version - аналогично - координаты бинарного артефакта, если текущий является конфигурацией. Пример шаблона:
${build: profiles.binaries.groupId}
Для определения значений переменных окружения среды необходимо в шаблонах использовать placeholders вида ${build: lookup('env', '<env_key>') }. Пример шаблона: ${build: lookup('env', 'BINARIES_VERSION') }, ${build: lookup('env', 'VERSION', default='1.0.0') }
Обратите внимание, переопределены placeholders для блока -
${build block: <block>}
Обратите внимание, что замена placeholders производится во всех текстовых (не бинарных) файлах рекурсивно относительно директории
package/conf
Для работы функционала необходимо определить переменную окружения ANSIBLE_TEMPLATING_TOOL. Значением должна выступать метка инструмента ansible (поиск инструментов сборки).
Сборка скриптов БД#
Скрипты БД, лежащие в дистрибутиве, должны быть сконфигурированы таким образом, чтобы при сборке получался архив следующей структуры:
db_archive.zip/
├─ <jdbc-driver>.jar
├─ <liquibase>.jar
├─ 0001_changelog.xml
├─ <папки и файлы, на которые ссылается 0001_changelog.xml>
Файла такой структуры можно добиться, например, с помощью добавления в файл pom.xml зависимостей postgres вызова assembly plugin с соответствующим дескриптором:
<dependencies>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<version>4.6.2</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.4.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>make-db-archive</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<finalName>db_archive</finalName>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>db-assemlby.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Важно: помимо скриптов текущего релиза в архив должны попасть liquibase-скрипты БД всех предыдущих. В данном примере все скрипты накопительным итогом хранятся в resources, и resources целиком попадает в дистрибутив.
и содержимое дескриптора db-assembly.xml (все файлы, которые нужно добавить, расположены в src/main/resources):
<?xml version="1.0" encoding="UTF-8"?>
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.1.0">
<id>make-liquibase-archive</id>
<formats>
<format>zip</format>
</formats>
<dependencySets>
<dependencySet>
<includes>
<include>org.postgresql:postgresql</include>
<include>org.liquibase:liquibase-core</include>
</includes>
<useProjectArtifact>false</useProjectArtifact>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<directory>src/main/resources/</directory>
<outputDirectory>.</outputDirectory>
</fileSet>
</fileSets>
Сборка bh-артефактов#
Репозиторий bh - это обычный maven-проект. Для сборки используется maven, который
настроен в соответствующем разделе в файле pipeline.yml.
При этом к cmd добавляются следующие параметры (профили включаются, если не выключен сонар):
mvn <параметры из настройки args> -U -Dmaven.repo.local=<workspace>/.m2 -DFP_VERSION=<версия дистрибутива> -DDB_BRANCH_NAME=<ветка репозитория> -Pnexus-alpha,sonar,sonar-coverage
Далее, если не включен параметр sonarSkip, запускается SonarQube сканирование. Для запуска сканирования используется следующая команда:
если настроен параметр
sonar_cmd- просто выполняется то, что в нем указано (при этом в начало команды добавляются параметры изargs)иначе - выполняется команда
sonar:sonarс параметрами (параметры указываются с префиксом -D - как стандартные свойства Java):sonar.projectKey - указывается, если не включена опция
sonarPomConfiguredи если в pom.xml нет свойстваsonar.projectKey. Равен этот параметр свойствуnameрепозитория (в pipeline.yml).sonar.branch.name - текущая ветка репозитория. Если она равна опции
sonar.mainBranch- то параметр вообще не указывается.sonar.branch.longLivedBranches.regex - берется из опции
sonar.longLivingBranchesPattern, по умолчанию равен(<текущая ветка>|branch|release|develop).*sonar.login - в качестве значения используется переменная окружения
SONAR_TOKEN, а если она не задана - значение6dd7e6fbc1c282f9a6176352a39173b62f8afe4e
Описание параметров конфигурации в файле pipeline.yml представлено в соответствующем разделе
Сборка Frontend#
Репозиторий pl - это nodejs-проект. Для сборки используется npm, который настроен в соответствующем разделе pipeline.yml.
При этом перед запуском непосредственно команды, которая прописана в cmd, будет выполнена подгрузка зависимостей с помощью команды
npm set strict-ssl false && env && npm ci -timeout=9999999.
Важно!
В корне репозитория должен располагаться файл package-lock.json
package-lock.json предназначен для блокировки зависимостей от определенного номера версии. В package-lock.json файле перечислены зависимости вашего приложения и зависимости всех его составляющих.
Генерация package-lock.json производится в процессе исполнения команды
npm install [library]. При установке библиотек необходимо указывать версию (например,npm i express@4.18.2). Указание флагов --save-dev/–save-prod при установке зависимостей обязательно.
Рекомендуется сохранять именно подобное поведение, т.е. скачивание зависимостей с помощью команды npm ci, т.к. если использовать npm install,
можно получить ситуацию, когда сборка внезапно начинает падать без каких-либо изменений - из-за того, что вышла новая версия какой-либо из зависимостей.
Параметры конфигурации в pipeline.yml описаны в соответствующем разделе.
Собственная реализация сборки#
Предоставляемая Jenkins библиотека программного компонента позволяет реализовывать собственные решения по сборке приложений для дистрибутива. Данный способ необходим в случае отсутствия той или иной сборочной функциональности внутри библиотеки и является рекомендуемой практикой, так как позволяет разработчикам собирать дистрибутивы удобными способами без привязки к pipeline. Как это сделать:
В корне репозитория в собираемой ветке создается Jenkinsfile.
В данный файл копируется обертка:
groovy def onDistrib(app, distr) { } return wrapJenkinsfile(this)Далее, при, например, сборке через maven, может быть добавлен wrapper:
def onDistrib(app, distr) { withMaven(jdk: 'JDK_1.8_121_Linux', maven: 'Maven 3.6.1', mavenSettingsConfig: 'test.app.settings') { } } return wrapJenkinsfile(this)Параметр
mavenSettingsConfigбудет описан в соответствующем разделе разделе описания файла settings.xml.После этого осталось написать команду сборки вашего приложения (или любую другую).
Важное замечание!Внутри обертки onDistrib можно указывать что угодно:можно загружать файлы и копировать их в папки;
можно вызывать несколько команд maven и т.д. Для добавления артефактов в дистрибутив необходимо вызывать соответствующие методы объекта Distrib. Полный список методов описан ниже.
Добавить dockerfile или, например, entrypoint-скрипт можно с помощью функции
distr.addDockerItems('my-deployment-unit', 'Dockerfile')илиdistr.addDockerItems('my-deployment-unit', 'entrypoint.sh').После создания Jenkinsfile в репозитории, его нужно настроить в pipeline.yml в соответствии с инструкцией.
Пример сборки maven-проекта#
def onDistrib(app, distr) {
withMaven(jdk: 'JDK_1.8_121_Linux', maven: 'Maven 3.6.1', mavenSettingsConfig: 'test.app.settings') {
sh "mvn clean package -Ddistrib.version=${distr.getVersion()}"
sh 'mvn sonar:sonar'
}
distr.addBH ("target/*.war") // добавляем в дистрибутив артефакт типа bh
}
return wrapJenkinsfile(this)
Пример сборки gradle-проекта#
def onDistrib(app, distr) {
withEnv(["GRADLE_HOME=${tool name: 'gradle-6.5', type: 'gradle'}"]) {
withCredentials([usernamePassword(credentialsId: 'my-credentials',
usernameVariable: 'maven.user.name',
passwordVariable: 'maven.user.password')]) {
stage('Build with gradle') { // допустим, вызов SonarQube встроен в build
sh "$GRADLE_HOME/bin/gradle :my-app:build -Pversion=$distr.version"
}
}
}
distr.addBH("./my-app/build/libs/my-app-*.jar") // добавляем в дистрибутив артефакт типа bh
}
return wrapJenkinsfile(this)
Пример сборки npm-проекта#
def onDistrib(app, distr) {
nodejs(configId: 'test.app.npmrc', nodeJSInstallationName: 'v7.5.0-linux-x64') {
sh 'npm ci'
sh 'npm pack'
}
distr.addPL("*.tgz") // добавляем в дистрибутив артефакт типа pl
}
return wrapJenkinsfile(this)
На этапах построения приложения происходит скачивание open-source библиотек и компонент из внешних репозиториев. Данная процедура производится с использованием инструмента, который проверяет соответствие установленных библиотек и компонентов требованиям кибербезопасности.
API дистрибутива#
У объекта Distrib существуют методы для добавления артефактов в дистрибутив:
Аргумент filePath во всех приведенных ниже методах - это путь к файлу, который необходимо добавить в дистрибутив. Допускается использование маски в bash-стиле.
// Добавить в дистрибутив артефакт типа bh
// Если задан аргумент bhName, то артефакт будет добавлен в папку bh/$bhName
def addBH(filePath, bhName = "")
// Добавить в дистрибутив артефакт типа pl
def addPL(filePath)
// Добавить в дистрибутив артефакт типа pl_mobile
def addPLMobile(filePath)
// Добавить в дистрибутив артефакт типа db
def addDB(filePath)
// Добавить в дистрибутив артефакт типа data
def addData(filePath)
// Добавить файл(ы) документации в дистрибутив
def addDocs(filePath)
// Добавить файлы конфигурации в дистрибутив
def addConf(filePath)
// Добавить Dockerfile (Dockerfile, entrypoint.sh, etc) в дистрибутив
def addDockerItems(deploymentUnit, filePath)
Расшифровка для типов артефактов приведена в разделе Термины и сокращения.
Методы объекта Distrib для добавления своих библиотек в дистрибутив (для пользования другими командами):
// Добавляет в дистрибутив Node.js-библиотеку
// coordinates - координаты библиотеки в npm-формате (имя библиотеки и ее версия)
def addSdkNpm(filePath, coordinates) // пример - distr.addSdkNpm('some-path/output.tgz', [name: 'some-lib', version: '1.2.3'])
// Добавляет в дистрибутив JAR-библиотеку (Java)
// pomPath - путь к файлу pom.xml библиотеки
def addSdkMvn(filePath, pomPath)
Чтобы получить версию дистрибутива, следует использовать метод getVersion:
def getVersion()
Сборка Pull Request#
Для того чтобы собрать Pull Request в том же окружении, в котором он будет собираться
при подготовке дистрибутива (что дает некоторые гарантии того, что PR не сломает
сборку дистрибутива), рекомендуется использовать предоставляемую библиотеку. Кроме того,
данный подход позволяет версионировать логику сборки приложения вместе с кодом
самого приложения.
Для этого необходимо добавить Jenkinsfile в корень репозитория и настроить автоматический запуск сборки. Ниже описаны требования к содержанию Jenkinsfile
Требования к Jenkinsfile#
Jenkinsfile – это стандартный pipeline-скрипт Jenkins.
В данном файле должны быть реализованы методы:
onPR(prInfo)- для обработки событий PR. prInfo - словарь с ключами:id (Pull Request id),
url (ссылка на PR),
from (из какой ветки PR),
to (в какую ветку PR).
onCommit(commitInfo)- для обработки commit-хуков, например, после слияния ветки вdevelop,masterилиrelease/*.
commitInfo содержит ключ branch с наименованием ветки, в которую был выполнен commit (или merge).
В скрипт должна быть подключена библиотека ufs-pipeline, на уровне папки, либо через динамическую загрузку.
Скрипт должен заканчиваться строчкой
return wrapJenkinsfile(this, context), где context - это необязательный параметр-map, содержащий ключи:NODE - наименование slave или label (по умолчанию
Linux_Default), на котором следует выполнять сборку,COLOR_MAP - параметр для степа ansiColor (по умолчанию
xterm).
Использование node в скрипте Jenkinsfile не требуется и не рекомендуется.
Использование stage - рекомендуется в onPR и не рекомендуется в onDistrib.
Отправлять нотификации в Bitbucket не требуется и не рекомендуется.
Данный функционал присоединяется вызовом wrapJenkinsfile.
Автоматический запуск сборки#
Существуют следующие варианты настройки автоматического запуска сборки:
С помощью stash-плагина Pull Request Notifier :
Организовать первичный запуск Jenkins job.
Настроить выгрузку репозитория.
Добавить загрузку Jenkinsfile и вызов метода, соответствующего целям сборки (onPR или onCommit):
load('Jenkinsfile').onPR().Можно использовать пример ниже – Job с подгрузкой Jenkinsfile.
С помощью jenkins-плагина Multibranch Pipeline. В этом случае в настройках multibranch pipeline необходимо подключить библиотеку ufs-pipeline c load implicity.
Для корректной работы функциональности notifyBitbucket, которая автоматически вызывается при сборке, рекомендуется добавить в Jenkins job следующие переменные окружения:
USERPASS_CREDS - ID credentials в Jenkins, у которых есть доступ в Bitbucket;
STASH_BASE_URL - ссылка на Bitbucket.
Примечания#
Решение проблем первой сборки pipeline с использованием Pull Request Notifier#
У многих команд имеются сложности с тем, что pipeline-job сборки Pull Request не запускается через hook Bitbucket.
Для запуска, необходимо хотя бы одно успешное выполнение checkout этой Jenkins job.
Для этого рекомендуется выполнить следующие действия:
Создать в репозитории ветку
pull-requests/test.Запустить Jenkins job с отмеченной опцией Poll SCM и следующим кодом pipeline:
def creds = <credentials id>
def repo = <ссылка на репозиторий>
node('Linux_Default') {
checkout([$class: 'GitSCM', branches: [[name: 'pull-requests/**']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: creds, url: repo]]])
}
После этого hook репозиториев должен заработать, и Jenkins job можно наполнять полезным функционалом.
Ветку pull-requests/test можно удалить.
Примеры Jenkinsfile#
Пример Jenkinsfile со сборкой maven#
mySonarUrl = 'https://sonar.<...>/sonar/dashboard?id=some-project'
def makeMavenConfig() {
return [home: 'Maven 3.3.9', jdk: 'JDK 1.8_72_Linux', settings_id: 'settings']
}
def onPR(prInfo) {
stage('Build') {
withCredentials([usernamePassword(
credentialsId: 'tech-creds',
passwordVariable: 'TECH_PASSWORD',
usernameVariable: 'TECH_USERNAME'
)]) {
def command = """\
-Dsonar.login=$env.TECH_USERNAME \
-Dsonar.password=$env.TECH_PASSWORD \
-Dsonar.stash.login=$env.TECH_USERNAME \
-Dsonar.stash.password=$env.TECH_PASSWORD \
-Dsonar.pullrequest.key=$prInfo.id \
-Dsonar.pullrequest.branch=$prInfo.from \
-Dsonar.pullrequest.base=$prInfo.to \
clean verify sonar:sonar -U
"""
ufs_maven_build(makeMavenConfig(), [cmd: command])
}
}
stage('Report') {
junit '**/target/surefire-reports/*.xml'
addBadge icon: '/plugin/sonar/images/waves_16x16.png',
link: "$mySonarUrl&pullRequest=$prInfo.id",
text: 'Analyzed by SonarQube'
}
}
def onCommit(commitInfo) {
stage('Build') {
withCredentials([usernamePassword(
credentialsId: 'tech-creds',
passwordVariable: 'TECH_PASSWORD',
usernameVariable: 'TECH_USERNAME'
)]) {
def cmd = """clean verify sonar:sonar \
-Dsonar.login=$TECH_USERNAME \
-Dsonar.password=$TECH_PASSWORD \
-Dsonar.branch.name=$commitInfo.branch
"""
ufs_maven_build(makeMavenConfig(), [cmd: cmd])
}
}
stage('Report') {
junit '**/target/surefire-reports/*.xml'
addBadge icon: '/plugin/sonar/images/waves_16x16.png',
link: "$mySonarUrl&branch=$commitInfo.branch",
text: 'Analyzed by SonarQube'
}
}
return wrapJenkinsfile(this)
Пример Jenkinsfile со сборкой gradle#
mySonarUrl = 'https://sonar.<...>/sonar/dashboard?id=some-project'
def onPR(prInfo) {
withCredentials([usernamePassword(
credentialsId: 'tech-creds',
passwordVariable: 'TECH_PASSWORD',
usernameVariable: 'TECH_USERNAME'
)]) {
stage('Build') {
sh './gradlew build'
}
stage('Sonar') {
sh """./gradlew \
-Dsonar.login=$env.TECH_USERNAME \
-Dsonar.password=$env.TECH_PASSWORD \
-Dsonar.stash.login=$env.TECH_USERNAME \
-Dsonar.stash.password=$env.TECH_PASSWORD \
-Dsonar.pullrequest.key=$prInfo.id \
-Dsonar.pullrequest.branch=$prInfo.from \
-Dsonar.pullrequest.base=$prInfo.to \
sonar """
}
}
stage('Report') {
junit '**/target/surefire-reports/*.xml'
addBadge icon: '/plugin/sonar/images/waves_16x16.png',
link: "$mySonarUrl&pullRequest=$prInfo.id",
text: 'Analyzed by SonarQube'
}
}
def onCommit(commitInfo) {
withCredentials([usernamePassword(
credentialsId: 'tech-creds',
passwordVariable: 'TECH_PASSWORD',
usernameVariable: 'TECH_USERNAME'
)]) {
stage('Build') {
sh './gradlew build'
}
stage('Sonar') {
sh """./gradlew sonar \
-Dsonar.login=$TECH_USERNAME \
-Dsonar.password=$TECH_PASSWORD \
-Dsonar.branch.name=$commitInfo.branch
"""
}
}
stage('Report') {
junit '**/target/surefire-reports/*.xml'
addBadge icon: '/plugin/sonar/images/waves_16x16.png',
link: "$mySonarUrl&branch=$commitInfo.branch",
text: 'Analyzed by SonarQube'
}
}
return wrapJenkinsfile(this)
Jenkins job Pull Requests с подгрузкой Jenkinsfile#
def creds = 'git-creds'
def branch = 'master'
def repo = 'SSH ССЫЛКА НА РЕПОЗИТОРИЙ БИТБАКЕТ С ВАШИМ JENKINSFILE'
def merge(map, remoteConfig) {
def branchFrom = map.from ?: 'origin/pull-requests/**'
def branchTo = map.to
return checkout([
$class: 'GitSCM',
branches: [[name: branchFrom]],
extensions: [[$class: 'PreBuildMerge', options: [mergeRemote: 'origin', mergeTarget: branchTo]]],
userRemoteConfigs: [remoteConfig]
])
}
library identifier: "ufs-pipeline@$branch", retriever: legacySCM([
$class: 'GitSCM',
branches: [[name: branch]],
userRemoteConfigs: [[
credentialsId: creds,
url: 'SSH ССЫЛКА НА РЕПОЗИТОРИЙ БИТБАКЕТ С UFS-PIPELINE'
]]
])
node('Linux_Default') {
ansiColor('xterm') {
stage('Checkout') {
merge (
[to: env.PULL_REQUEST_TO_BRANCH],
[
credentialsId: creds,
url: repo
]
)
}
if( fileExists('Jenkinsfile') ) {
load('Jenkinsfile').onPR()
} else {
echo "Jenkinsfile not found" // На время переходного периода, когда PR с Jenkinsfile уже есть
manager.buildAborted() // А в основных ветках его еще нет
}
}
}
Сборка и доставка Docker образов#
В случае, если необходимо выполнить установку в OpenShift, необходимо создать следующую иерархию в репозитории с конфигурациями:
test.app.config/
├─ k8s/base/
│ ├─ test.app.backend/
│ │ ├─ Dockerfile
│ │ ├─ dc.yaml
│ ├─ test.app.frontend/
│ │ ├─ Dockerfile
│ │ ├─ dc.yaml
├─ pipeline.yml
При наличии данной структуры, созданный pipeline найдет необходимые Dockerfile и запустит их сборку, после чего выложит образы в registry. Помимо этого он вставит hash образов в соответствующие конфигурационные файлы.
Обратите внимание, что в приведенной иерархии имя Docker образа будет соответствовать имени директории в которой расположен Dockerfile (в конкретном случае это
test.app.backend,test.app.frontend), а тег это версия дистрибутива.
В Dockerfile, вместо указания
tag, можно использовать placeholder BASE_IMAGE_VERSION, который будет доставать последнюю доступную версию базового образа на текущий момент, например:
FROM registry.host/path/to/my/image:BASE_IMAGE_VERSION
В Dockerfile необходимо указать параметр BASE_IMAGE, как показано в примере:
ARG BASE_IMAGE=registry.host/path/to/my/image:tag
FROM ${BASE_IMAGE}
Настройка Docker в файле конфигурации pipeline.yml описана в соответствующем разделе.
Результат выкладки в registry отображается в логах Jenkins job (ссылка на docker-image), который можно дополнительно проверить, зайдя по адресу web-интерфейса docker-репозиториев
https://registry.<...>.ru/docker/под общим ТУЗом. В web-интерфейсе необходимо перейти по указанному пути в image_path (как пример - browse - efs/ci00428440_efs/ci00749857_efs_authorization) и/имя сервиса/tags.
Сборка приложений в Docker#
Декларативная сборка#
Декларативный подход к решению предполагает использование раздела with_docker в секции build. Данный раздел направлен на непосредственную работу с Dockerfile, в котором разработчик описывает последовательность инструкций по сборке приложений. Существует следующее соглашение, обязательное при использовании данной функциональности:
В корневой директории (
/) финального Docker-образа должна располагаться папка с названиемoutputs;В папке
outputsдолжны располагаться директории, названия которых полностью соответствуют типу добавляемого артефакта (bh, pl, ...)
Для добавления Dockerfile (Dockerfile, entrypoint.sh, etc) в дистибутив необходимо в
outputs/dockerопределить директории с наименованием соответствующего deployment-unit, которые содержат соответствующие Dockerfile-артефакты.
Раздел with_docker используется для подключения сборки приложения в Docker. Каждый элемент списка в данном разделе должен содержать следующие обязательные параметры:
name - название элемента (рекомендуется использовать уникальные значения всех name во всех блоках);
repo (<…>/helloword.git) - репозиторий, из которого нужно взять собираемый Dockerfile;
branch (master) - ветка, из которой нужно взять расширение.
context - директория сборки Docker-образов;
dockerfile_path - путь до Docker-файла относительно директории сборки;
Также раздел может включать следующие необязательные параметры:
secrets - подраздел, отвечающий за передачу секретов (файлов, переменных) в Docker-сборку:
files - расширение для добавления конфигурационных файлов (данная опция включает список
);
prod_branch - это ветка, из которой был собран предыдущий релиз (можно также указать тег);
sonarSkip - если true, пропустить SonarQube-сканирование;
create_tag - значение типа boolean, по умолчанию false (если значение параметра выставлено в true, то создается аннотированный тег с версией, декларированной разделом fp).
parallel - опция использования параллельной сборки. Если для двух приложений будет указано одинаковое значение
parallel, то они будут запускаться в общем потоке.outputs - список артефактов, которые необходимо скопировать в директорию относительно
workspace;source - путь до артефакта (может быть указана маска). Значение по умолчанию -
outputs/*;dest - директория назначения выбранного артефакта. Значение по умолчанию -
package.
Для использования данного раздела требуется заполнение секции docker
build:
with_docker:
- name: "docker-app-1"
repo: "project/dockerfile-repo.git"
branch: "release/1.0.0"
prod_branch: "master"
dockerfile_path: Dockerfile
context: ./
parallel: "A"
secrets:
files:
- <config file id>
Монтирование секретных файлов производится через флаг
--mount=type=secret,id=maven_secret_id,dst=/project/settings.xmlв инструкцииRUNв вашем Dockerfile. Заданный параметрtype(тип монтируемого файла) должен иметь значениеsecret; значение параметраidдолжно совпадать с, определенным в filesв подразделеsecretsвашего pipeline.yml; значение параметраdstопределяет расположение конфигурационного файла (требуется указать полный путь и имя файла).
Добавленные через инструкцию
filesв подразделеsecretsконфигурационные файлы по умолчанию (без указания параметраdstв инструкцииRUN) располагаются в директории/run/secrets/запущенногоDocker- образа. Имена добавленных конфигурационных файлов соответствуют указанному<config file id>в списке, определеннымfiles.
syntax- определяет расположение образа синтаксиса Dockerfile, используемого для сборки пользовательского Dockerfile. В данном контексте определение образа синтаксиса необходимо для использования инструкцииRUNс флагом--mount=type=secret,id=maven_secret_id(пример официального образа интерфейсаDockerfile-docker/dockerfile:1.2).
Важно отметить, что полнофункциональная сборка производится только при наличии установленного
buildxплагина и заполненного подразделаcacheсекцииdocker. Если же настройкаcacheпо каким либо причинам отсутсвует, то будет выполняться обыкновенная последовательная (НЕ параллельная - опцияparallelв настройке pipeline.yml игнорируется) сборка Dockerfiles без элементов кеширования в registry и без использования инструментовbuildxплагина.
Пример Dockerfile:#
# syntax = registry.host/path/to/my/dockerfile/syntax/image:tag
FROM registry.host/path/to/my/maven/image:tag AS <target>
WORKDIR project/
COPY . .
RUN --mount=type=secret,id=<config file id>,dst=/project/settings.xml mvn clean package
FROM scratch
RUN mkdir -p /outputs/bh
WORKDIR /artifacts
COPY --from=<target> /project/target/*.war /outputs/bh/
Сборка приложения с кешированием слоев:#
Кеширование слоев необходимо для увеличения скорости сборки проекта. Сборка проекта может быть разделена на несколько этапов, например - загрузка зависимостей и сборка приложения. Каждый этап может быть записан в отдельной инструкции в Dockerfile при сборке Docker-образа. Тогда для каждой инструкции создается новый слой образа, который сохраняется в кеше. В случае отсутствия изменений в исходных файлах проекта для отдельной инструкции, пересборка проекта или повторная загрузка зависимостей не осуществляется. Ниже приведены примеры сборок проектов в Dockerfile:
Пример сборки maven-проекта в Dockerfile#
Для настройки кеширования промежуточных слоев в удаленный репозиторий необходимо прописать название scratch:
# syntax = registry.host/path/to/my/dockerfile/syntax/image:tag
FROM registry.host/path/to/my/maven/image:tag AS <target>
WORKDIR project/
# Копируем из исходного репозитория конфигурационные файлы проекта
COPY ./pom.xml ./
# Производим полную загрузку зависимотей
RUN --mount=type=secret,id=maven_secret_id mvn package -s /run/secrets/maven_secret_id
# Копируем проект целиком (pom.xml файл перезапишется)
COPY . .
# Производим сборку проекта
RUN --mount=type=secret,id=maven_secret_id mvn package -s /run/secrets/maven_secret_id
FROM scratch
RUN mkdir -p /output/bh
WORKDIR /artifacts
COPY --from=<target> /project/target/*.war /outputs/bh/
При работе с кешированием необходимо убедиться, что каталоги/файлы, которые не участвуют в сборке проекта (например, .git, .idea, …), исключены из сборки Dockerfile. Инструментом для уточнения контекста сборки является файл
.dockerignore
Экспорт переменных окружения Jenkins Job#
Для доступа к переменным окружения Jenkins Job нужно смонтировать секретный файл с ID envParams. Экспорт переменных в процесс сборки производится следующей инструкцией в Dockerfile - RUN --mount=type=secret,id=envParams,dst=/project/envParams . ./envParams || source ./envParams
# syntax = registry.host/path/to/my/dockerfile/syntax/image:tag
FROM registry.host/path/to/my/maven/image:tag
WORKDIR project/
COPY . .
RUN mvn package -s settings.xml
# Монтируем секретный файл и экспортируем переменные окружения
RUN --mount=type=secret,id=envParams,dst=/project/envParams \
. ./envParams && \
printenv
Передача секретных параметров#
Создайте конфигурационный файл с типом Custom file в Jenkins:
export EXAMPLE_KEY=$SECRET_TOKEN_ID
export ...
Смонтируйте секретный файл и произведите экспорт переменных, например - RUN --mount=type=secret,id=<custom file id>,dst=/project/<custom file name> . ./<custom file name> || source ./<custom file name>.
# syntax = registry.host/path/to/my/dockerfile/syntax/image:tag
FROM registry.host/path/to/my/maven/image:tag
WORKDIR project/
# Экспортируем переменные в окружение среды
RUN --mount=type=secret,id=envParams,dst=/envs \
--mount=type=secret,id=custom_envs,dst=/custom_envs \
. ./custom_envs && . ./envs && \
printenv
Настройка SonarQube#
Для настройки сканирования приложений необходимо использовать переменные доступа к инструменту SonarQube, которые могут быть доступны в Dockerfile через инструкцию - RUN --mount=type=secret,id=envParams,dst=/project/envParams.
Существует следующее соглашение, обязательное для использования данного функционала:
В корневой директории (
/) финального Docker-образа должна располагаться папка с названиемsonar;В директории
sonarдолжны располагаться отчеты о сканировании вашего приложения. Например, SonarScanner плагин сборщика Maven после анализа приложения загружает отчеты о сканировании в директориюtarget/sonarотносительно корня репозитория
Пример сканирования maven-приложения в Docker#
# syntax = registry.host/path/to/my/dockerfile/syntax/image:tag
FROM registry.host/path/to/my/maven/image:tag as <target>
WORKDIR project/
COPY . .
RUN mvn package -s settings.xml
# Экспортируем переменные в окружение среды и производим сканирование
RUN --mount=type=secret,id=envParams,dst=/project/envParams \
. ./envParams && \
mvn sonar:sonar -s settings.xml
FROM scratch
RUN mkdir -p /output/bh /sonar
WORKDIR /artifacts
COPY --from=<target> /project/target/*.war /outputs/bh/
COPY --from=<target> /project/target/sonar/* /sonar/
Существующие точки расширений#
analyzeDependencies#
Данное расширение подключается автоматически и выполняет анализ зависимостей включенных в дистрибутив образов.
Для того чтобы отменить автоматическое подключение расширения, нужно создать переменную окружения ANALYZE_DEP = false.
Также это расширение использует сервис поиска образов по hash, который предоставляет Nexus.
Запрос к сервису генерируется следующим образом: <registry_root>/<registry_search_api><hash>,
где registry_root - это параметр docker.registry_address из pipeline.yml,
а registry_search_api - путь сервиса поиска, по умолчанию docker/service/rest/v1/search?docker.contentDigest=sha256:,
hash - хэш искомого образа
Запрос к сервису можно переопределить с помощью переменной окружения REGISTRY_SEARCH_API, причем, если она будет начинаться с https://,
ссылка на сервис будет генерироваться так: <registry_search_api><hash> (т.е. без registry_root).
Узнать адрес сервиса поиска образов можно у владельца инсталляции Nexus
Если требуется использовать какую-либо специальную версию SYFT, можно ее указать с помощью переменной окружения ]]SYFT_TOOLING - но она должна быть подключена в Jenkins.
sequrityChecks#
Данное расширение подключается автоматически и выполняет запуск проверок SAST/OSS. Результирующие флаги проверок будут загружены в qgm средствами сервиса SAST/OSS. Запуск проверок можно регулировать выключением/включением сценариев в PLAYBOOKS sast-run и oss-run.
makeReleaseNotes#
Данное расширение подключается автоматически, готовит ReleaseNotes и выкладывает его в QGM.
Настройка данного расширения осуществляется через раздел qgm в файле pipeline.yml.
Формирование Release Notes для каждого из используемых репозиториев управляется следующими параметрами:
Релизная ветка или tag (
prod_branch, между этой веткой будет браться diff. Если указываетсяtag, то в форматеrefs/tags/tagID).Регулярное выражение для определения списка задач из JIRA (
issue_pattern). Например:### Ссылки на сборочные Jenkins-файлы ### jenkinsfiles: - name: "test.app.backend" # любое repo: "ufs_ci/test.app.backend.git" # url без хоста branch: "develop" # ветка сборки prod_branch: 'master', issue_pattern: '[A-Za-z][A-Za-z0-9]+-[0-9]+' # регулярное выражение по которому определяется идентификатор запроса в JIRA из commit.
updateVersionConf#
Данное расширение подключается автоматически и выполняет копирование файла version.conf в дистрибутив из репозитория version.conf.git того же проекта, из которого запускался ufs-pipeline.
Ветка репозитория определяется по следующим правилам:
если релиз платформы
!R19.5, то используетсяApp19.5если релиз платформы
!R20.1, то используетсяApp20.1иначе используется ветка
master
Кроме того, в случае наличия соответствующих переменных окружения PLATFORM_RELEASE и/или AT_BRANCH в файл version.conf добавятся параметры atBranch и platformRelease.
Также, если в подготавливаемом дистрибутиве уже содержится файл version.conf (был в репозитории конфигураций или добавлен из Jenkinsfile), то все параметры в нем будут сохранены.
В случае, когда данный репозиторий
version.conf.gitуже есть в разделе downloads, расширение не выполняет копирование, но выводит предупреждение, если выбрана неверная ветка. При этом остальная логика (выставление параметровatBranchиplatformRelease, сохранение уже существующих параметров) также не будет выполнена – будет скопирован тот файл, который указан в downloads.
AddDescription#
Данное расширение подключается автоматически и добавляет в описание сборки таблицу с координатами дистрибутива, а также ссылками, по которым он (и его pom.xml) был загружен в хранилище.
Если в вашей инфраструктуре используется какие-либо механизмы по "перекладыванию" дистрибутивов, ссылки могут быть устаревшими.
transformDistrib#
Данное расширение позволяет трансформировать получившийся дистрибутив в какой-либо другой формат.
Для этого необходимо указать правила трансформации в параметре directories в виде <директория>: <файлы, которые надо в нее скопировать>
Пример:
extensions:
- name: transformDistrib
directories:
modules: "package/bh/*"
other/seap-lib/lib: "package/sdk/mvn/*"
config: "package/conf/application.properties"
install: "package/conf/deployment_pg.xml"
db: "package/db/*"
./:
- "package/ReleaseNotes.json"
- "package/conf/pipeline.yml"
CheckDistrib#
Расширение для проверки состава получившегося дистрибутива. Настройка проверок осуществляется с помощью следующих параметров:
exists список регулярных выражений, по которым требуется проверять наличие файлов
not_exists список регулярных выражений, по которым требуется проверять отсутствие файлов
check_rn - необязательный параметр, по-умолчанию: false. Значение true указывается для запуска проверки ReleaseNotes.
checked_flags - список QGM флагов. Указанные QGM флаги проходят проверку (ОК статус) для выпущенного дистрибутива.
Пример (проверка дистрибутива бинарников):
- name: CheckDistrib
exists:
- package/conf/data/sup2/.*
- package/docker/test.app.backend/.sha256
not_exists:
- documentation/.*
- package/conf/openshift/test.app.backend/.sha256
- package/conf/openshift/test.app.backend/Dockerfile
- package/bh/.*
- package/sdk/.*
- package/db/.*
- package/pl/.*
- package/conf/data/analyze_dep/.*
generateJenkinsFile#
Данная точка расширения предназначена для упрощения разработки jenkinsfile для своих сборок.
При ее выполнении в bh-, pl- и db-репозиториях будет создана ветка feature/conf/SUFSCI-126, в которой будет добавлен Jenkinsfile,
реализующий сборку артефактов дистрибутива в соответствии с требованиями данной библиотеки сборки.
Какой-либо настройки расширения не требуется, достаточно просто его подключить.
gettingConfigXml#
Данная точка расширения копирует файл config.xml Jenkins job сборки в дистрибутив.
По умолчанию расширение скачивает config.xml под Credentials, указанными в USERPASS_CREDS.
Также доступна настройка через свойство расширения creds, например:
extensions:
- name : gettingConfigXml
creds: some_jenkins_token_cred
MoveDockerfile#
Расширение переносит dockerfiles из package/conf/k8s/base/<deployment_unit> в package/docker/<deployment_unit> для выполнения требований стандарта STD-5.
В большинстве случаев настройка расширения не требуется, достаточно только подключение:
extensions:
- MoveDockerfile
Но если требуется помимо Dockerfile переместить еще какие-либо файлы, можно указать соотвутствующую маску в параметре mask:
extensions:
- name: MoveDockerfile
mask: *.sh
Если нужно указать несколько масок, следует указать их списком:
extensions:
- name: MoveDockerfile
mask:
- *.sh
- *.py
std5Configuration#
Расширение для сборки дистрибутива конфигураций. Детали работы описаны в соответствующем разделе
std5Binaries#
Расширение для сборки дистрибутива бинарных файлов. Детали работы описаны в соответствующем разделе.
std19Sdk#
Расширение для сборки дистрибутива sdk. Данное расширение исключает все файлы/папки из дистрибутива, кроме /sdk.
shell#
Расширение для выполнения shell команд.
Доступные инструменты сборки: maven, node(Если настроен раздел npm).
Данная точка расширения поддерживает следующие опции:
commands - список команд, которые будут выполнены
env - список переменных, которые будут доступны
Список экспортируемых переменных окружения:
CONFIGS_DIR - конфигурационными файлами
ARCHIVE_SOURCE_DIR - директория, из которой собирается архив дистрибутива
ARCHIVE_PATH - путь до архива, если он уже собран(расширение должно быть запущено после стадии pack)
Пример (скачивание зависимости maven и клонирование репозитория):
extensions:
- name: shell
env:
collection-version: 4.4
commands:
- mvn --version
- |
mvn dependency:get -DgroupId=org.apache.commons -DartifactId=commons-collections4 -Dversion=$collection-version -Dpackaging=pom -Ddest=commons-collections4.pom
cp commons-collections4.pom $ARCHIVE_SOURCE_DIR/package/bh
- git clone <...>
generateSBOMCyclonedx#
Расширение для анализа зависимостей сборочных проектов.
Данная точка расширения поддерживает следующие опции:
tools - список инструментов окружения для анализа зависимостей сборочных проектов
cdxgen - версия cdxgen (версия по умолчанию - 8.6.2)
cyclonedx_cli - версия cyclonedx (версия по умолчанию - 0.25.0)
args - дополнительные пользовательские параметры при исполнении команды cdxgen
classifier - maven classifier (значение по умолчанию -
cyclonedx-distrib)
Пример:
- name: generateSBOMCyclonedx
tools:
- 'gradle-7.3.3'
Разработка собственной точки расширения#
В предоставляемом pipeline для каждого этапа имеется поддержка точек расширения через контракт в Jenkinsfile.
Как и в случае onDistrib() необходимо написать groovy скрипт, реализовав в нем следующую обертку:
def run(extension, extensionAPI) {
}
return this
Объект из списка extensions это Map extension в функции run, то есть все поля этого объекта доступны вам внутри. Т.е. если расширение подключено так:
extensions:
- name: SomeExtension
param1: one
param2: 2
В таком случае расширение может использовать объект extension следующим образом:
def run(extension, extensionAPI) {
assert extension.name == 'SomeExtension'
assert extension.branch == 'master' // Поскольку значение по умолчанию добавляется
assert extension.param1 == 'one'
assert extension.param2 == 2
}
return this
Объект extensionAPI можно использовать для получения данных из pipeline, доступные функции:
package ru.<...>.devops
class ExtensionAPI {
def getPipelineConfig() // прочитанный в объект pipeline.yml
def getDistrib() // объект distrib, такой же, как и в onDistrib
}
В точке расширения есть возможность подгрузить файлы, находящиеся рядом с ней в том же репозитории. Загрузка файлов осуществляется при загрузке самой точки расширения.
Как использовать:
Объявить переменные вне методов без ключевого слова
def. В них подгружаем необходимые файлы.Далее эти переменные можем использовать в методах точки расширения. Пример реализации простой точки расширения, которая читает контент файла textfile и подгружает объект файла
test.groovy, а далее в своих методах имеет доступ к содержимому textfile и методамtest.groovy:// начало файла примера точки расширения fileContents = readFile("textfile") // загружаем файл в точке расширения, но вне ее методов без ключевого слова def testFile = load("test.groovy") // загружаем еще файл, путь к файлу указываем относительно пути где находится эта точка расширения def run(extension, extensionAPI) { testFile.call() // в методе точки расширения вызываем метод загруженного файла println fileContents // а также можем смотреть контент загруженного файла } // конец файла примера точки расширения
При создании новой точки расширения можно указать конфигурацию по умолчанию, чтобы не указывать ряд полей в файле pipeline.yml. Для этого надо создать новый метод getDefaultConfig, например:
def getDefaultConfig() {
return [
stage: 'upload',
phase: 'before',
description: 'Проверка состава дистрибутива'
]
}
Поля name, repo, branch и jenkinsfile_name возвращать в getDefaultConfig() не нужно, т.к. они используются до загрузки расширения.
Детали подключения расширения описаны выше.
Настройка SAST/OSS Checkmarx#
В библиотеке ufs-pipeline существует возможность настроить анализ всех git-репозиториев на сканирование Checkmarx и OSS. Для этого необходимо в pipeline.yml добавить настройки соответствующих инструментов:
### Настройки DevSecOps ###
### Общая информация о командах ###
team:
- # Код команды в МУСе
# Если не сработает код команды в МУСе, то можно попробовать прописать логин ТУЗа, который используется для сканирования в Checkmarx
mus_code: "command_code"
# Название команды в МУСе
mus_name: "command_name"
# Почтовый адрес Product Owner в МУСе для уведомлений с результатами сканирования
# !!! Почта должна быть валидной для текущего домена, чтобы корректно определить пользователя, которому впоследствии предоставятся права на доступ к АС в SALM !!!
# !!! Возможно указание нескольких почт через знаки ";" или "," внутри одной строки !!!
# Пример: "user1@mycompany.com; user2@mycompany.com, user3@mycompany.com"
mus_po_mail: "user1@mycompany.com; user2@mycompany.com, user3@mycompany.com"
# Возможно добавление нескольких команд
# !!! Вторую и последующие команды необходимо добавить по формату, аналогичному первой !!!
# - mus_code: "00040018"
# mus_name: "Web SBOL Design"
# mus_po_mail: "sspetrov@sberbank.ru"
### Общая информация о приложении ###
app:
# Конфигурационный элемент (КЭ) приложения / модуля ПО в Service Manager.
# !!! КЭ должен быть строкой, состоящей исключительно из цифр без лидирующих нулей !!!
sm_id: "number_id"
# Название КЭ приложения / модуля ПО в Service Manager
sm_name: "app_name"
### Настройки SAST Checkmarx ###
sast_cx:
# Credentials ID в Jenkins для учетной записи Checkmarx одной команды, под которой будет проводиться сканирование
creds_id: "creds"
# Проектная область в JIRA для заведения и синхронизации дефектов
jira_area: "area"
# Маски файлов и директорий для включения (**/*) в скан и исключения (!**/*) из скана.
# Пример: "!**/utils/**/*.xml" - исключение всех xml файлов в папке utils
masks: ""
# ID профиля сканирования, по умолчанию 36. 14 - для мобильного приложения. 100003 - Smoke
preset_id: "36"
# Максимальное время ожидания статуса QG в минутах
wait_qg: "2"
### Настройки OSS
oss:
# Маски файлов и директорий для исключения из сканирования
# Пример: "**/utils/**/*.xml" - исключение всех xml файлов во всех папках utils
# !!! Перечисление нескольких масок возможно через знаки "," или ";" внутри одной строки, например, "**/*test*/**; **/*.txt, .git/**" !!!
# !!! Пропуски в каждой маске справа и слева автоматически удалятся (trim) !!!
excludes: ""
Также существует возможность исключить какой-либо из подключенных репозиториев из сканирования, добавив при этом опцию sast_skip: true.
Например (в данном случае сканирование не будет выполнено ни для одного из подключенных репозиториев):
jenkinsfiles:
- name: bh-jf
repo: cije/test.app.backend.git
branch: develop
sast_skip: true
pl:
- name: my-pl
repo: cije/test.app.frontend.git
branch: develop
cmd: 'npm pack'
sast_skip: true
downloads:
- source: git
type: conf
repo: cije/test.app.backend.git
branch: develop
files: pom.xml
sast_skip: true
Более подробную информацию по настройке параметров sast/oss можно запросить у подразделения кибербезопасности компании.
Непосредственно запуск проверок осуществляется включением сценариев run-sast, run-oss.
Часто встречающиеся проблемы и пути их устранения#
Ожидание waitForQualityGate падает по timeout, несмотря на то, что QualityGate посчитан#
Такое бывает, если не настроен sonarqube webhook. В этом случае необходимо просто его добавить в настройках проекта SonarQube:
Administration → Webhooks → Create Webhook: <jenkins_url>/sonarqube-webhook/
Поиск инструментов сборки#
Для получения значения tool name необходимо перейти в Pipeline Syntax и в Sample step выбрать tool: Use a tool from a predefined Tool Installation. В Tool type указать SonarQube Scanner. В поле Tool посмотрите название инструмента.
Release Notes#
Как происходит сборка Release Notes?#
По каждому репозиторию, который был подключен, в процессе сборки выполняется команда: git log prod_branch..branch, где prod_branch - это ветка, из которой был собран предыдущий релиз (можно также указать тег), branch - это ветка,
из которой собирается релиз сейчас.
Задать prod_branch можно с помощью переменной окружения PROD_BRANCH (через параметр job
или в job есть настройка переменных окружения) или для каждого репозитория через свойство prod_branch. По умолчанию prod_branch=master.
Указанная команда возвращает список коммитов, из них регулярным выражением извлекаются JIRA issues. Далее вся эта информация укладывается в JSON
и публикуется в QGM.
Что делать, если Release Notes не выкладывается?#
Необходимо открыть stage view job и посмотреть stage "Формирование Release Notes".
Если он зеленый - значит, Release Notes у вас собирается и выкладывается.
Если он желтый - то смотрим его логи. Там должна быть красная строчка, которая скажет, какая операция закончилась неуспешно. В большинстве случаев причина заключается в отсутствии в каком-либо из репозиториев ветки, которая указана в prod_branch. Или, если prod_branch нигде не указан, причина заключается в отсутствии ветки master.
Если stage нет - проверяем конфигурацию pipeline.yml. Для всех репозиториев значения параметра skip_rn должны быть false. Затем необходимо убедиться в отсутствии "makeReleaseNotes" в параметре disabled_extensions. Подробности смотрите в разделе Существующие точки расширений.
SAST#
Что делать, если в АС CheckMarx нет отчета о сканировании SAST?#
Убедитесь, что код команды и название команды в МУСе и в pipelene.yml совпадают. Убедитесь, что почта, указанная в pipeline.yml для уведомлений о результатах сканирования, валидна для текущего домена. Если указано несколько почтовых адресов, то они отделены символами ";" или "," внутри одной строки. Заведите заявку на консультацию по работе с АС CheckMarx.
Почему в процессе сборки дистрибутива не отправляются флаги SAST и OSS в QGM?#
Job сборки дистрибутива больше не отправляет флаги SAST и OSS, т.к. QGM самостоятельно их рассчитывает. Изменение вступило в силу с 18 ноября 2021.
Как отключить сканирование SAST/OSS репозитория?#
При установленных параметрах run-sast и run-oss job выполнит сканирование репозиториев, указанных в блоках: jenkinsfiles, bh, pl, db, downloads(source="git"). Чтобы исключить репозиторий из сканирования SAST/OSS, необходимо добавить параметр sast_skip: true
Добавление функциональности в job сборки дистрибутива#
Можно ли расширить ваш конвейер (pipeline)?#
Подробности смотрите в разделе Существующие точки расширений.
Как выложить дистрибутив в несколько мест?#
Через точку расширения. Подробности смотрите в разделе Существующие точки расширений. В pipeline.yml необходимо добавить:
extensions:
- name: CloneDistrib # Имя вашей точки расширения
repo: ufs_ci/jenkinsfiles.git # Ссылка на репозиторий, где лежит точка
branch: master # Ветка по умолчанию
jenkinsfile_name: CloneDistrib.groovy # Задание имени точке расширения
stage: upload # Перекладывание дистрибутивов после основного этапа выкладки
phase: after
credId: supertuz # ID Credentials, у которого есть права для выгрузки/загрузки
coordinates: # Сами новые параметры, версия будет как у собираемого дистрибутива
- repoId: Nexus_PROD
groupId: Nexus_PROD
artifactId: CI03666221_BFS_OSEO
- repoId: Nexus_PROD
groupId: Nexus_PROD
artifactId: CI03678492_BFS_OSEO
УБЕДИТЕЛЬНАЯ ПРОСЬБА проверить, что у вашего ТУЗ есть права необходимые для выкладки во все области, а также скачивания bin из тех же новых областей в случае сборки конфигурационных файлов, так как bin будут переложены автоматически под новыми КЭ. Также необходимы права для выкладки Release Notes в новые области.
Статический анализ#
Что делать, если сканирование SonarQube отвалилось по timeout?#
Время ожидания ответа от SonarQube составляет 10 минут. Для решения проблемы необходимо:
Убедиться, что с начала сканирования действительно прошло 10 минут (считать с момента вывода в логи строки "Waiting for Sonar answer…").
Убедиться, что в pipeline.yml корректно настроена секция
sonarУбедиться, что проверка SonarQube запустилась (в логах должна присутствовать строка запуска SonarQube, например,"mvn sonar:sonar").
Убедиться, что других ошибок, связанных с SonarQube, в логах нет (использовать поиск по логам ключевого слова "sonar").
Добавить в ваш SonarQube-проект webhook по инструкции [Настройка средств анализа проекта].
Что делать, если проверка SonarQube завершилась неуспешно, и в логах присутствует ошибка "unable to find valid certification path to requested target"?#
В проекте используется устаревший tool JDK, необходимо заменить на актуальный в секции "maven" pipeline.yml.
Что делать, если не проходит проверка SAST?#
Если не проходит проверка, то нужно создать заявку из домена внешнего сегмента или через каталог для вашего домена.
Что делать, если при сборке дистрибутив не грузится в Nexus?#
Убедитесь, что для загрузки дистрибутива в Nexus используется Apache Maven. Если используется cURL, необходимо добавить параметр "use_for_deploy: true" в секцию "maven" pipeline.yml
Что делать, если не собираются Release Notes, и в логах присутствует ошибка "FATAL: [ssh-agent] Could not find specified credentials"?#
Необходимо добавить в job сборки дистрибутива параметр LIBRARY_CREDS и указать для него в качестве значения credentials с типом "SSH Username with private key" вашего ТУЗа.
Общие вопросы#
Как понять причину unstable (желтая сборка)?#
Открыть build -> Open blue ocean -> найти желтый stage, открыть его, обратить внимание на список выполненных шагов и изучить содержание желтых или красных.