web-dev-qa-db-fra.com

Remplir dynamiquement le paramètre Jenkins Choice avec des branches Git dans un référentiel spécifié

J'ai un travail Jenkins paramétré qui nécessite la saisie d'une branche Git spécifique dans un dépôt Git spécifique. Actuellement, ce paramètre est un paramètre de chaîne.

Existe-t-il un moyen de faire de ce paramètre un paramètre de choix et de remplir dynamiquement la liste déroulante avec les branches Git? Je ne veux pas demander à quelqu'un de gérer ce paramètre de choix en configurant manuellement le menu déroulant chaque fois qu'une nouvelle branche est créée.

57
mkez00

plugin Extended Choice Parameter vous permettra de lire les choix d'un fichier.

Bien sûr, vous avez maintenant un autre problème: comment s’assurer que le fichier est à jour (ce qui peut être fait avec un hook post-commit) et propagé à tous les utilisateurs (cela peut être fait en le plaçant sur un disque partagé). serveur de fichiers). Mais il peut y avoir de meilleures solutions.

20
malenkiy_scot

J'ai essayé quelques réponses mentionnées dans ce lien, mais je ne savais pas comment dire à Jenkins de la branche sélectionnée par l'utilisateur. Comme mentionné dans mon commentaire précédent dans le fil de discussion ci-dessus, j'avais laissé le champ de sélection de branche vide.

Mais, au cours de nouvelles investigations, j’ai trouvé un autre moyen de faire la même chose - https://wiki.jenkins-ci.org/display/JENKINS/Git+Parameter+Plugin J’ai trouvé cette méthode comme une beaucoup plus simple, et avait moins de choses à configurer!

Voici ce que j'ai configuré -

  1. Installé le plugin de paramètre git
  2. A coché la case 'Cette construction est paramétrée' et a ajouté un 'paramètre Git'
  3. Ajout des valeurs suivantes: Git Parameter plugin config in the job

  4. Ensuite, dans la section git SCM du travail, j'ai ajouté la même valeur que celle mentionnée dans la section 'Nom', comme s'il s'agissait d'une variable d'environnement. (Si vous lisez attentivement l'aide de ce plugin de paramètres git, vous vous en rendrez compte) Branch Selector

Après cela, je viens juste de lancer la construction, de choisir ma branche (Jenkins vérifie cette branche avant de construire) et elle a terminé la construction avec succès, ET en choisissant la branche que j'avais spécifiée.

78
Ravindra Mijar

Ce résultat a été obtenu avec le plug-in Jenkins Dynamic Parameter . J'ai utilisé l'option Dynamic Choice Parameter et, pour le script choices, les éléments suivants:

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()
14
veritius

C'est assez simple en utilisant le "Git Parameter Plug-in" .

Ajoutez un nom comme "SELECT_BRANCH" ## Assurez-vous que cette variable sera utilisée ultérieurement. Type de paramètre: branche

Ensuite, contactez SCM: Sélectionnez: Spécificateur Git et branch: $ {SELECT_BRANCH}

Pour vérifier, exécutez ci-dessous dans Shell dans Jenkins:

echo $ {SELECT_BRANCH}

env.enter image description ici

enter image description here

10
Smit Jain

Je suis confronté à un problème similaire ici. Nos utilisateurs migrent leurs emplois du freestyle au pipeline. Ils ne veulent pas que Jenkinsfile soit stocké dans leurs dépôts (raison historique) et veulent toujours utiliser le plugin "Git Parameter"

Nous devons donc utiliser "Pipeline script" et développer un autre plugin qui fonctionne comme "Git Parameter".

Ce nouveau plugin n’intègre pas les paramètres SCM dans le projet. Le plugin est à https://plugins.jenkins.io/list-git-branches-parameter

J'espère que ça vous aide aussi

4
黄索远

Vous pouvez accomplir la même chose en utilisant le plugin de paramètre de choix étendu mentionné précédemment par malenkiy_scot et un script php simple comme suit (en supposant que vous ayez un serveur pour déployer des scripts php que vous pouvez utiliser à partir de la machine Jenkins)

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

ou

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

Avec la première option, vous devez cloner le référentiel. Avec le second, ce n'est pas le cas, mais dans les deux cas, vous devez installer git sur le serveur hébergeant votre script php. Avec toutes ces options, il devient totalement dynamique, vous n'avez pas besoin de créer un fichier liste. Placez simplement l'URL de votre script dans le champ "fichier de propriétés" du paramètre de choix étendu.

2
Ulises

Oui, j'ai écrit un petit script groovy qui fait l'affaire. Vous devez ajouter un "paramètre de choix dynamique" à votre travail et personnaliser le script groovy suivant selon vos besoins:

#!/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()

Dans mon cas, la chaîne de version était au format suivant X.X.X.X et pouvait avoir des branches d’utilisateur au format X.X.X-nom d’utilisateur, etc ... Je devais donc écrire ma propre fonction de tri. C'était mon premier scénario groovy, donc s'il y a de meilleures façons de faire, j'aimerais le savoir.

2
sagi

Pour moi, j'utilise le paramètre stage stage:

  1. Je commence mon pipeline en vérifiant le projet Git.
  2. J'utilise une commande awk pour générer un fichier barnch.txt avec la liste de toutes les branches
  3. Dans les décors de scène, je lis le fichier et l’utilise pour générer un paramètre de choix d’entrée

Lorsqu'un utilisateur lance un pipeline, celui-ci attendra de choisir dans la liste.

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()
        }
    }
}

}

Et puis l'utilisateur va interagir avec la construction:

entrez la description de l'image ici

entrez la description de l'image ici

2
idriss Eliguene

développer la réponse de @ malenkiy_scot. J'ai créé un nouveau travail Jenkins pour créer le fichier utilisé par Extended Choice Plugin.

vous pouvez faire ce qui suit (je l'ai fait en exécutant les étapes du shell dans Jenkins, mais vous pouvez le faire dans un script):

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

J'utilise ensuite le plugin Artifact deployer pour pousser ce fichier vers un emplacement partagé, qui se trouve dans une URL Web, puis utilisez simplement 'http: //localhost/branches.txt' dans le plugin Extended Choice comme URL. fonctionne comme un charme.

2
Ben

Nous pouvons éliminer les fichiers inutiles en lecture/écriture en utilisant text. Ma solution complète est la suivante:

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();
1
janoskk

J'ai une nouvelle réponse pour ce cas: le moyen facile de résoudre ce problème est de vous avoir jenkinsFile à partir du code source.

Ensuite, vous avez choisi: ce travail a un paramètre git

enter image description here

De plus, et la configuration du pipeline, décochez la case "Vérification légère", cela effectuera une vérification vraiment géniale dans l'espace de travail.

enter image description here

Ensuite, le paramètre sera automatiquement rempli par votre branche git

0
idriss Eliguene

Le script groovy suivant serait utile, si votre travail n’utilise pas directement "Gestion du code source" (de même que "Git Parameter Plugin"), mais ont toujours accès à un dépôt git local (cloné):

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()

Voir l'explication complète ici: https://stackoverflow.com/a/37810768/658497

0
Noam Manos