Вопрос по choice, git, parameters, jenkins, branch – Динамическое заполнение параметра выбора Jenkins с помощью веток Git в указанном репо

53

У меня есть параметризованное задание Jenkins, которое требует ввода определенной ветви Git в определенное хранилище Git. В настоящее время этот параметр является строковым параметром.

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

Ваш Ответ

11   ответов
2

фристайла на конвейер. Они не хотят, чтобы Jenkinsfile хранился в их репозиториях (историческая причина), и все еще хотят использовать плагин «Git Parameter

Так что мы должны использовать «Pipeline script» и разработать другой плагин, который работает как «Git Parameter».

Этот новый плагин не интегрируется с настройкой SCM в проекте. Плагин наhttps: //plugins.jenkins.io/list-git-branches-paramete

Надеюсь, тебе это тоже поможет

17

лагин @Extended Choice Parameter позволит вам прочитать выбор из файла.

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

Мы используемлагин @Extensible Choice Parameter с отличным сценарием:return [" "].plus(["powershell","(git.exe ls-remote -h http://review/Project)-replace '\\w{40}\\trefs/heads/'"].execute().text.tokenize()). Это PowerShell, поскольку он на компьютере с Windows, но вы можете заменить его другим инструментом для замены RegEx. Это будет обновлять список при каждой загрузке без необходимости использования внешних файлов. Stoinov
@ Stoinov Мне очень нравится ваше решение. У меня проблемы с тем, чтобы заставить это работать на сервере Linux. RockyMountainHigh
У меня очень мало опыта работы с linux, но вы должны быть в состоянии использовать любую команду linux, которая может заменить возвращаемый список из команды git. Stoinov
73

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

Но во время дальнейших расследований я нашел другой способ сделать то же самое -https: //wiki.jenkins-ci.org/display/JENKINS/Git+Parameter+Plugi Я обнаружил, что этот метод намного проще, и в нем меньше настроек!

Вот что я настроил -

Установлен плагин для параметра gitПроверил 'Эта сборка параметризована' и добавил 'Git параметр'

Добавлены следующие значения:

Затем в разделе git SCM задания я добавил то же значение, что и в разделе «Имя», как если бы это была переменная окружения. (Если вы внимательно прочитаете справку для этого плагина параметров git, вы поймете это

После этого я просто запустил сборку, выбрал свою ветвь (Дженкинс проверяет эту ветку перед сборкой), и она успешно завершила сборку, И выбрав указанную мной ветвь.

К сожалению, я не могу получить название ветки без 'origin /'. $ {BRANCH_SELECTOR ## * /} не работает при вводе переменных. igor
@ AmokHuginnsson это исправлено и выпущено в начале июля Issues.jenkins-ci.org/browse/JENKINS-1629 montss
Известные ограничения / ошибки: плагин для параметра git не поддерживает установку подчиненного устройства Jenkins с репозиториями git, проверенными только на подчиненных устройствах AmokHuginnsson
Я был очень взволнован этим, но, к сожалению, его мучает ошибка, из-за которой он не передает учетные данные на git-сервер. Поэтому, если вам нужны учетные данные (например, для частных репозиториев Github), это не сработает, пока не будет решен JENKINS-28597. Mike Post
Ну, для меня сам список выбора содержит origin / <branch-name> .. Так что это автоматически входит в переменную $ BRANCH_SELECTOR .. Ravindra Mijar
14

Я смог достичь этого результата, используялагин динамических параметров @Jenkins. Я использовал параметр Dynamic Choice Parameter и для сценария выбора использовал следующее:

proc1 = ['/bin/bash', '-c', "/usr/bin/git ls-remote -h ssh://[email protected]/path/to/repo.git"].execute()
proc2 = ['/bin/bash', '-c', "awk '{print \$2}'"].execute()
proc3 = ['/bin/bash', '-c', "sed s%^refs/heads%origin%"].execute()

all = proc1 | proc2 | proc3
String result = all.text

String filename = "/tmp/branches.txt"
boolean success = new File(filename).write(result) 

def multiline = "cat /tmp/branches.txt".execute().text
def list = multiline.readLines()
О, похоже на то, что я нашел с помощью плагина Git Parameter. (Опубликовал мои выводы в качестве другого возможного ответа ниже). Спасибо за эту информацию, хотя. Ravindra Mijar
Хороший ответ, но, к сожалению, я вынужден понизить голос, потому что плагин динамических параметров был приостановлен из дистрибутива Jenkins из-за уязвимости удаленного выполнения кода: Jenkins.io / безопасность / совещательный / 2017-04-10 / ... Nik Reiman
По какой-то причине ветка на 8-й позиции всегда поднимается. (У меня около 19 филиалов). Неважно, что я выберу. Любая идея, если какая-то дополнительная настройка должна быть сделана в работе Дженкинс? Или что-то не так с плагином? Я оставил поле 'ветка' пустым. Ravindra Mijar
Звучит так, будто вы описываете проблему ниже по течению, это просто объясняет, как динамически заполнить параметр вашими ветками git. Чтобы использовать ветку в сборке, я обычно называю параметр «ветвь», а затем в разделе «Управление исходным кодом» (с выбранным Git) используйте «$ {branch}» (без кавычек) для «Отрасли для построения» «Спецификатор ветви (пустое поле для любого). Надеюсь, это поможет veritius
Как дополнение, я обнаружил, что ssh не всегда доступен, но не обязательно нужен. Альтернативой было бы использовать что-то вроде этого:proc1 = ['/bin/bash', '-c', "/usr/bin/git ls-remote -h [email protected]:path/to/repo.git"].execute() Это особенно полезная информация при работе с github. veritius
1

Я запускаю свой конвейер, проверяя проект git. Я использую awk commade для создания файла barnch.txt со списком всех ветвей На этапе установки я читаю файл и использую его для генерации параметров ввода

Когда пользователь запускает конвейер, он будет ждать его выбора в списке.

pipeline{
agent any

stages{

    stage('checkout scm') {
        steps {
            script{
                git credentialsId: '8bd8-419d-8af0-30960441fcd7', url: 'ssh://[email protected]:/usr/company/repositories/repo.git'
                sh 'git branch -r | awk \'{print $1}\' ORS=\'\\n\' >>branch.txt'
            }

        }
    }
     stage('get build Params User Input') {
        steps{
            script{

                liste = readFile 'branch.txt'
                echo "please click on the link here to chose the branch to build"
                env.BRANCH_SCOPE = input message: 'Please choose the branch to build ', ok: 'Validate!',
                        parameters: [choice(name: 'BRANCH_NAME', choices: "${liste}", description: 'Branch to build?')]


            }
        }
    } 
    stage("checkout the branch"){
        steps{
            echo "${env.BRANCH_SCOPE}"
            git  credentialsId: 'ea346a50-8bd8-419d-8af0-30960441fcd7', url: 'ssh://[email protected]/usr/company/repositories/repo.git'
            sh "git checkout -b build ${env.BRANCH_NAME}"
        }
    }
    stage(" exec maven build"){
        steps{
            withMaven(maven: 'M3', mavenSettingsConfig: 'mvn-setting-xml') {
               sh "mvn clean install "
            }
        }
    }
    stage("clean workwpace"){
        steps{
            cleanWs()
        }
    }
}

}

И тогда пользователь будет взаимодействовать с ним при сборке:

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

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

2

я создания файла, который используется плагином Extended Choice.

Вы можете сделать следующее (я сделал это как выполнить шаги оболочки в jenkins, но вы можете сделать это в скрипте):

git ls-remote [email protected]:my/repo.git |grep refs/heads/* >tmp.txt
sed -e 's/.*refs\/heads\///' tmp.txt > tmp2.txt
tr '\n' ',' < tmp2.txt > tmp3.txt
sed '1i\branches=' tmp3.txt > tmp4.txt
tr -d '\n'  < tmp4.txt > branches.txt

Затем я использую плагин Artifact для развертывания, чтобы переместить этот файл в общую папку, которая находится в веб-URL, а затем просто использовать 'http: //localhost/branches.txt' в плагине Extended Choice в качестве URL-адреса. работает как шарм.

grep refs/heads/* у меня не работает jspooner
hmm. это публичное репо? Вы можете поделиться Git URL? Мне было бы интересно узнать, почему это не сработало Ben
2

я написал небольшой отличный сценарий, который делает свое дело. Вы должны добавить «параметр динамического выбора» к своей работе и настроить следующий отличный сценарий для своих нужд:

#!/usr/bin/groovy

def gitURL = "git repo url"
def command = "git ls-remote --heads --tags ${gitURL}"

def proc = command.execute()
proc.waitFor()              

if ( proc.exitValue() != 0 ) {
   println "Error, ${proc.err.text}"
   System.exit(-1)
}

def text = proc.in.text
# put your version string match
def match = /<REGEX>/
def tags = []

text.eachMatch(match) { tags.push(it[1]) }
tags.unique()
tags.sort( { a, b ->
         def a1 = a.tokenize('._-')
         def b1 = b.tokenize('._-')
         try {
            for (i in 1..<[a1.size(), b1.size()].min()) { 
                 if (a1[i].toInteger() != b1[i].toInteger()) return a1[i].toInteger() <=> b1[i].toInteger()
            }
            return 1
         } catch (e) {
            return -1;
         }
} )
tags.reverse()

В моем случае строка версии была в следующем формате X.X.X.X и могла иметь ветви пользователя в формате X.X.X-username и т. Д. Поэтому мне пришлось написать собственную функцию сортировки. Это был мой первый отличный сценарий, поэтому, если есть способы лучше, я хотел бы знать.

Остерегайтесь этого скрипта, запускающего его в параметре динамического выбора, он разбил мой Дженкинс (2.7, 2.8) Noam Manos
это, вероятно, из-за вызова System.exit () (не относится к версии Jenkins) Noam Manos
Можешь сказать почему? у вас есть обратный след? Я никогда не пробовал это на 2.X версии sagi
2

используя плагин расширенного выбора параметров, упомянутый ранее malenkiy_scot, и простой сценарий php следующим образом (при условии, что у вас есть сервер для развертывания сценариев php, которые вы можете использовать на компьютере Jenkins)

<?php
chdir('/path/to/repo');
exec('git branch -r', $output);
print('branches='.str_replace('  origin/','',implode(',', $output)));
?>

ил

<?php
exec('git ls-remote -h http://user:[email protected]', $output);
print('branches='.preg_replace('/[a-z0-9]*\trefs\/heads\//','',implode(',', $output)));
?>

При первом варианте вам нужно будет клонировать репо. Со вторым вы этого не сделаете, но в обоих случаях вам нужно установить git на сервере, где размещен ваш php-скрипт. Несмотря на то, что любой из этих параметров становится полностью динамическим, вам не нужно создавать файл списка. Просто введите URL-адрес вашего сценария в поле расширенного параметра «файл свойств».

Так что вам нужен этот php-скрипт на веб-сервере с установленным git + учетными данными ssh для доступа к git-серверу. ХОРОШО. Но как вы называете этот php-скрипт из плагина параметров расширенного выбора? Amedee Van Gasse
10

"Git Parameter Plug-in".

Добавьте имя, например, «SELECT_BRANCH» ## Убедитесь, что эта переменная будет использована позже. Тогда Тип параметра: Ветвь

Затем обратитесь к SCM: выберите: Git и спецификатор ветви: $ {SELECT_BRANCH}

Чтобы проверить, выполните ниже в shell в jenkins:

echo $ {SELECT_BRANCH}

env.enter описание изображения здесь

В моем случае мы работаем с тематическими ветками. Jenkins должен собираться автоматически, когда кто-то также передает код в ветку функций. Когда код запускается изменениями SCM, тогда параметр будет пустым. Поэтому мне пришлось нажать «Дополнительно» и ввести ** в поле «Значение по умолчанию», чтобы автоматическая сборка в результате изменения SCM заработала. Antony
0

Следующий полезный скрипт будет полезен, если ваша работа не использует «Управление исходным кодом» напрямую (аналогично «Плагин параметров Git»), но все еще имеет доступ к локальному (клонированному) репозиторию git:

import jenkins.model.Jenkins

def envVars = Jenkins.instance.getNodeProperties()[0].getEnvVars() 
def GIT_PROJECT_PATH = envVars.get('GIT_PROJECT_PATH') 
def gettags = "git ls-remote -t --heads origin".execute(null, new File(GIT_PROJECT_PATH))

return gettags.text.readLines()
         .collect { it.split()[1].replaceAll('\\^\\{\\}', '').replaceAll('refs/\\w+/', '')  }
         .unique()

Смотрите полное объяснение здесь:https: //stackoverflow.com/a/37810768/65849

0

Мы можем устранить ненужные файлы для чтения / записи с помощьюtext. Мое полное решение заключается в следующем:

proc1 = ['/bin/bash', '-c', 
  "/usr/bin/git ls-remote --heads ssh://repo_url.git"].execute()
proc2 = ['/bin/bash', '-c', 
  "/usr/bin/awk ' { gsub(/refs\\/heads\\//, \"\"); print \$2 }' "].execute()
all = proc1 | proc2

choices = all.text
return choices.split().toList();

Похожие вопросы