Как динамически выбрать ветвь git для использования в сборке Jenkins

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

Componenta​​p >

  • Изменение этого компонента запускает сборку этого проекта на сервере 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:

  1. Поместите компонент A в регулярное Управление исходными кодами в разделе Git все обязательные поля (Хранилища, Ветки и т.д.).
    • Будет проще и чище разместить репозиторий в подкаталоге: в разделе Дополнительные действия выберите Check out to a sub-directory и напишите: component_a
  2. Обязательно проверьте Build Triggers Build when a change is pushed to GitHub
  3. В разделе "Сборка" отметьте Use secret text(s) or file(s)

    • введите Variable некоторое имя: MY_CRED
    • в Credentials выберите конкретные учетные данные, созданные на шаге 1.

    введите описание изображения здесь

  4. Теперь, используя 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
  5. Сделайте все ваши синтаксические разборки конфигурации из компонента A, чтобы получить желаемый тег: TAG=$(cat ./component_a/config.cfg | grep ... | sed ...)

  6. Оформить требуемый тег: cd component_b; git checkout -f $TAG
    • Примечание: тег силы -f.
  7. Теперь запустите код и протестируйте его по желанию...

Ответ 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 вызовет ваш обычный поток Дженкинса.