Как динамически выбрать ветвь git для использования в сборке Jenkins
Я пытаюсь создать новую конфигурацию проекта для сервера сборки Jenkins. Чтобы упростить то, что я пытаюсь сделать, я буду использовать только два компонента для описания проблемы.
Componentap >
- Изменение этого компонента запускает сборку этого проекта на сервере CI.
- Сервер CI имеет статически настроенную ветвь для мониторинга изменений и сборки. Например. мастер или разработать ветвь.
- Этот компонент содержит файл конфигурации с требуемой версией ComponentB, от которого он зависит.
ComponentB
- Изменения этого компонента не инициируют сборку этого проекта на CI-сервере (там будет еще один проект для разработки ComponentB).
- Отдельные версии компонента помечены тегом
- ComponentA имеет требуемую версию ComponentB в своем файле конфигурации
- Сервер CI не знает, какую ветку (тег) проверять до тех пор, пока файл конфигурации ComponentA не будет каким-то образом разбираться.
Каков правильный путь для достижения Дженкинса? Я пытался выяснить, как добавить это динамическое поведение для разбора файла конфигурации и создания плагина Git, чтобы проверить ветвь на основе ожидаемой версии ComponentB, но до сих пор я понятия не имею.
На следующем шаге я могу даже захотеть создать в файле конфигурации подстановочные знаки (например, 5.3. *), поэтому мне нужно будет найти новый тег ComponentB, соответствующий шаблону.
ИЗМЕНИТЬ
Теперь я вижу, что я слишком упростил свою проблему, и из-за упрощения основное ограничение больше не присутствует.
Основное ограничение заключается в том, что Компонент A и B должны быть объединены. Их невозможно создать отдельно, поскольку они образуют одну исполняемую/библиотеку, а сборку script нужны исходные файлы из обоих компонентов.
Если вы спросите, почему такая странная конфигурация, дайте Компоненту A и B некоторое описание:
- ComponentA: собственный код для конкретной платформы
- ComponentB: независимый независимый от платформы код
Может быть много Компонента As - один для каждой платформы, но только один компонент B. Объединение определенного A с B дает полный исходный код для одной платформы, но не каждая платформа может быть обновлена до последней версии B, поэтому ей необходимо имеют контроль над тем, какая версия B должна использоваться для построения.
Ответы
Ответ 1
Один из вариантов достижения того, что вы хотите, - использовать следующую настройку:
Создайте два задания Jenkins:
- "Компонент A" (автоматически срабатывает при изменениях SCM)
- "Компонент B" ( "вручную" )
Шаг # 1
Определите параметр branch
для параметра "Компонент B" :
![введите описание изображения здесь]()
Используйте этот параметр в качестве спецификатора ветки Git Plugin ":
![введите описание изображения здесь]()
Теперь вы должны иметь возможность вручную запускать сборку "Component B" , указав для нее правильный параметр ветвления (тега), например. tags/5.3.0
.
Шаг # 2
Добавьте новый шаг сборки "Execute Shell" к своей сборке "Компонент А" , которая извлечет версию "Component B" из файла конфигурации в рабочей области и подготовит файл b.properties
с помощью сборки "Component B" параметры.
![введите описание изображения здесь]()
Установите Parameterized Trigger Плагин Jenkins и добавьте новый "Trigger/call builds for other projects", чтобы построить шаг "Компонент A", работа:
![введите описание изображения здесь]()
Используя ваш файл b.properties
в качестве источника параметров сборки.
Теперь каждый раз, когда "Компонент А" перестраивается, запускается новая сборка "Компонент В", а целевой ветвь/тег - как параметр сборки.
Добавление поддержки подстановочных знаков
Если вы хотите поддерживать подстановочные версии, вы можете использовать команду git ls-remote
, чтобы найти последний тег, например:
#B=$(obtain B version from the config file in a usual way)
LATEST=$(\
git ls-remote --tags YOUR_REPOSITORY_URL "$B"\
|cut -d / -f3|sort -r --version-sort|head -1\
)
cat <<EOF > b.properties
branch=tags/$LATEST
EOF
Здесь перечислены все теги, соответствующие шаблону версии "B", в удаленном репозитории "Компонент B" и сохраните номер последней версии в переменной LATEST
.
Добавьте это к шагу "Выполнение оболочки" в задании "Компонент А" ,
и он должен иметь возможность обрабатывать шаблоны номеров версий, например: 5.3.*
Ловушка заключается в том, что оболочка script будет запущена как пользователь демона Дженкинса,
поэтому он должен иметь надлежащие учетные данные для доступа к удаленному репозиторию Git (например, через ssh pubkey).
В качестве альтернативы вы можете заглянуть в Credentials Binding Plugin, чтобы повторно использовать учетные данные Git, хранящиеся в самом Jenkins.
Использование конвейера стиля Jenkins 2.0
Вы также можете решить эту задачу, используя Jenkins 2.0-style Pipeline, который позволит вам проверить код для компонентов A и B, в одно рабочее пространство, а затем применить к ним некоторый общий шаг сборки.
Ваш трубопровод может выглядеть примерно так:
node {
//Settings
def credentialsId = '8fd28e34-b04e-4bc5-874a-87f4c0e05a03'
def repositoryA = 'ssh://[email protected]/projects/a.git'
def repositoryB = 'ssh://[email protected]/projects/b.git'
stage('Checkout component A') {
git credentialsId: credentialsId ,
url: repositoryA , branch : "master"
}
stage("Resolve and checkout component B") {
def deps = readProperties file: 'meta.properties'
echo "Resolved B version = ${deps['b']}"
dir("module/b") {
//Clone/Fetch Component B
checkout scm:[
$class: 'GitSCM',
userRemoteConfigs: [[url: repositoryB, credentialsId: credentialsId]],
branches: [[name: 'refs/tags/*']]
],
changelog: false, poll: false
//Checkout the tag, matching deps['b'] pattern
sshagent([credentialsId]) {
sh "git checkout \$(git tag -l \"${deps['b']}\" |sort -r --version-sort|head -1)"
}
}
}
stage("Build A+B") {
//Apply a common build step
}
}
Здесь мы используем команду readProperties, которая является частью "Шаблоны шагов трубопровода" , чтобы извлечь шаблон версии "Component B" от meta.properties
. Также доступны команды readYaml, readJSON.
Далее мы получаем/клонируем "Компонент B" с флагами changelog: false, poll: false
, чтобы предотвратить его регистрацию для опроса SCM, в папку "module/b" текущей рабочей области.
Затем вызовите команду оболочки, чтобы выбрать тег, на основе шаблона версии, который мы получили выше, и проверьте его (5.3. * стиль шаблонов также должен работать).
Вызов sh
завернут в sshagent, чтобы повторно использовать соответствующий
учетные данные из хранилища учетных данных Jenkins.
Ответ 2
Использование Плагин привязки учетных данных работал очень хорошо для меня (также упоминается @zeppelin)
Шаги:
В разделе Глобальные учетные данные:
-
Add Credentials
типа: "Имя пользователя с паролем". Это должно быть имя пользователя и пароль для сервера репозитория компонентов git с использованием протокола HTTPS (опция SSH не подходит для этой цели)
![введите описание изображения здесь]()
В настройке задания Jenkins:
- Поместите компонент A в регулярное Управление исходными кодами в разделе
Git
все обязательные поля (Хранилища, Ветки и т.д.).
- Будет проще и чище разместить репозиторий в подкаталоге: в разделе Дополнительные действия выберите
Check out to a sub-directory
и напишите: component_a
- Обязательно проверьте Build Triggers
Build when a change is pushed to GitHub
-
В разделе "Сборка" отметьте Use secret text(s) or file(s)
- введите
Variable
некоторое имя: MY_CRED
- в
Credentials
выберите конкретные учетные данные, созданные на шаге 1.
![введите описание изображения здесь]()
-
Теперь, используя MY_CRED
в коде Execute shell, вы получите доступ к репозиторию компонента B:
DIR="component_b"
if [ "$(ls -A $DIR/.git)" ]; then
cd $DIR
git fetch
else
git clone https://[email protected]/proj/component_b.git $DIR
cd $DIR
fi
git show
![введите описание изображения здесь]()
- Примечание: вы не увидите пользователя и пароль в журналах, поэтому он должен быть безопасным. вы увидите:
git clone 'https://****@github.com/proj/component_b.git' component_b
-
Сделайте все ваши синтаксические разборки конфигурации из компонента A, чтобы получить желаемый тег: TAG=$(cat ./component_a/config.cfg | grep ... | sed ...)
- Оформить требуемый тег:
cd component_b; git checkout -f $TAG
- Теперь запустите код и протестируйте его по желанию...
Ответ 3
1 - добавит ли проект B
в качестве вспомогательного репо проекта A
возможное решение?
2- (если действительно следует исключить полный исходный код для B): толкает сборки B в некоторый репо B_builds
, и добавление этого репо в качестве подрепого A
может быть возможным решением?
Обоснование: одним из способов более явной зависимости между A
и B
является представление его внутри зависимостей репозитория.
Это потребует добавления дополнительного шага при управлении проектом A
:
update `B` sub repo in `A` project, and push this to `A`
каждый раз, когда вы создаете новую версию для B
.
Однако у вас будет четкое представление, начиная с A
, о том, когда были интегрированы версии B
(например: "мы использовали только B 2.0.1
начиная с A 4.3.2
" ) и нажав на A
вызовет ваш обычный поток Дженкинса.