J'ai deux branches sur BitBucket: master
et develop
. J'ai également un travail de dossier d'équipe BitBucket configuré sur mon serveur Jenkins pour construire ce référentiel. Le fichier Jenkins suivant se trouve sur la branche develop
:
node {
stage('Checkout') {
checkout scm
}
stage('Try different branch') {
sh "git branch -r"
sh "git checkout master"
}
}
Lorsque Jenkins l’exécute, la construction échoue lorsqu’il tente d’extraire master
:
[Pipeline] stage
[Pipeline] { (Try different branch)
[Pipeline] sh
[e_jenkinsfile-tests_develop-4R65E2H6B73J3LB52BLACQOZLBJGN2QG22IPONX3CV46B764LAXA] Running Shell script
+ git branch -r
Origin/develop
[Pipeline] sh
[e_jenkinsfile-tests_develop-4R65E2H6B73J3LB52BLACQOZLBJGN2QG22IPONX3CV46B764LAXA] Running Shell script
+ git checkout master
error: pathspec 'master' did not match any file(s) known to git.
[Pipeline] }
Je m'attendais à ce que la commande git branch -r
imprime à la fois Origin/master
et Origin/develop
, mais pour une raison quelconque, elle n’imprime que le dernier.
J'ai lu quelque chose et essayé de trouver un moyen de faire cela: Par exemple, j'ai essayé d'installer le plug-in d'agent SSH pour Jenkins et modifié le fichier Jenkins en tant que:
node {
stage('Checkout') {
checkout scm
}
stage('Try different branch') {
sshagent(['Bitbucket']) {
sh "git branch -r"
sh "git checkout master"
}
}
}
Mais il ne semble toujours pas trouver Origin/master
. Pire encore, l'agent SSH semble être tué avant de tenter de passer à la caisse master
:
[Pipeline] { (Try different branch)
[Pipeline] sshagent
[ssh-agent] Using credentials ThomasKasene (Used to communicate with Bitbucket)
[ssh-agent] Looking for ssh-agent implementation...
[ssh-agent] Exec ssh-agent (binary ssh-agent on a remote machine)
$ ssh-agent
SSH_AUTH_SOCK=/tmp/ssh-M6pIguCUpAV4/agent.11899
SSH_AGENT_PID=11902
$ ssh-add /var/jenkins_home/workspace/e_jenkinsfile-tests_develop-4R65E2H6B73J3LB52BLACQOZLBJGN2QG22IPONX3CV46B764LAXA@tmp/private_key_2394129657382526146.key
Identity added: /var/jenkins_home/workspace/e_jenkinsfile-tests_develop-4R65E2H6B73J3LB52BLACQOZLBJGN2QG22IPONX3CV46B764LAXA@tmp/private_key_2394129657382526146.key (/var/jenkins_home/workspace/e_jenkinsfile-tests_develop-4R65E2H6B73J3LB52BLACQOZLBJGN2QG22IPONX3CV46B764LAXA@tmp/private_key_2394129657382526146.key)
[ssh-agent] Started.
[Pipeline] {
[Pipeline] sh
[e_jenkinsfile-tests_develop-4R65E2H6B73J3LB52BLACQOZLBJGN2QG22IPONX3CV46B764LAXA] Running Shell script
+ git branch -r
Origin/develop
[Pipeline] sh
$ ssh-agent -k
unset SSH_AUTH_SOCK;
unset SSH_AGENT_PID;
echo Agent pid 11902 killed;
[ssh-agent] Stopped.
[e_jenkinsfile-tests_develop-4R65E2H6B73J3LB52BLACQOZLBJGN2QG22IPONX3CV46B764LAXA] Running Shell script
+ git checkout master
error: pathspec 'master' did not match any file(s) known to git.
[Pipeline] }
Mon plan éventuel est d’engager quelque chose dans develop
et de le fusionner ensuite en master
, mais j’ai eu très peu de chance jusqu’à présent. Quelqu'un at-il une solution possible ou une solution de contournement?
PS: Cela semble seulement être un problème dans Jenkinsfile; J'ai un job de freestyle qui fait quelque chose de similaire à ce que je veux, et ça marche bien.
Après quelques heures d’essais et d’erreurs, j’ai trouvé une solution possible. Cela repose en partie sur la réponse de Matt, mais je devais la modifier pour que cela fonctionne.
Matt avait raison dans l'essentiel: checkout scm
n'était tout simplement pas assez flexible pour me permettre de faire ce dont j'avais besoin, alors j'ai dû utiliser GitSCM
pour le personnaliser. Les principaux points d'intérêt sont:
LocalBranch
pour m'assurer que je consulte une succursale réelle, et pas seulement une HEAD
détachée.WipeWorkspace
pour tout supprimer dans l'espace de travail et forcer un clone complet. Je ne pense pas que cela faisait partie de la solution à ma question, mais c'était quand même pratique.credentialsId
car le référentiel est privé.Pour une raison quelconque, lorsque l'étape checkout
est exécutée, elle extrait uniquement la branche, mais ne la configure pas pour suivre la branche distante. Jusqu'à ce que je trouve une solution plus élégante, je devais le faire manuellement.
Après tout ce qui a été fait, je pouvais utiliser des sh "git checkout master"
et même des sh "git Push"
réguliers, à condition de les inclure dans une étape sshagent
.
J'ai ajouté un exemple de travail du fichier Jenkins résultant ci-dessous, mais n'oubliez pas qu'il ne devrait pas être utilisé pour des applications proches de la production, car il en est encore à ses balbutiements; numéros de version codés en dur et pas de vérification de la branche dans laquelle vous vous trouvez, par exemple.
node {
mvnHome = tool 'Maven'
mvn = "${mvnHome}/bin/mvn"
stage('Checkout') {
checkout([
$class: 'GitSCM',
branches: scm.branches,
extensions: scm.extensions + [[$class: 'LocalBranch'], [$class: 'WipeWorkspace']],
userRemoteConfigs: [[credentialsId: 'Bitbucket', url: '[email protected]:NAVFREG/jenkinsfile-tests.git']],
doGenerateSubmoduleConfigurations: false
])
}
stage('Release') {
// Preparing Git
sh "git branch -u Origin/develop develop"
sh "git config user.email \"[email protected]\""
sh "git config user.name \"Jenkins\""
// Making and committing new verison
sh "${mvn} versions:set -DnewVersion=2.0.0 -DgenerateBackupPoms=false"
sh "git commit -am \"Released version 2.0.0\""
// Merging new version into master
sh "git checkout master"
sh "git merge develop"
sh "git checkout develop"
// Making and committing new snapshot version
sh "${mvn} versions:set -DnewVersion=3.0.0-SNAPSHOT -DgenerateBackupPoms=false"
sh "git commit -am \"Made new snapshot version 3.0.0-SNAPSHOT\""
// Pushing everything to remote repository
sshagent(['Bitbucket']) {
sh "git Push"
sh "git checkout master"
sh "git Push"
}
}
}
Vous pouvez utiliser la fonction intrinsèque du pipeline Jenkins créée pour le clonage et l'extraction de Git. Je suggérerais également de cloner les branches dans des répertoires séparés.
checkout([$class: 'GitSCM',
branches: [[name: '*/branch_name']],
doGenerateSubmoduleConfigurations: false,
extensions: [[$class: 'RelativeTargetDirectory',
relativeTargetDir: 'different_directory']],
submoduleCfg: [],
userRemoteConfigs: [[url: '[email protected]:org/repo.git']]])
Je ne pouvais pas obtenir les deux réponses ci-dessus au travail. Je déclenchais un travail de pipeline Jenkins en spécifiant une branche et j'essayais de vérifier une autre branche (développer) dans le travail qui échouait avec:
error: pathspec 'develop' did not match any file(s) known to git.
Je pouvais le voir dans le travail en échec, qui indiquait que seule la branche de déclenchement était extraite:
git fetch --no-tags --progress https://<github URL> +refs/heads/branch-name:refs/remotes/Origin/branch-name
Je l'ai obtenu en changeant la configuration d'extraction à distance et en récupérant toutes les branches en procédant comme suit après avoir effectué uniquement l'étape checkout scm
par défaut dans le fichier Jenkins du travail déclenché:
sh """
git config remote.Origin.fetch '+refs/heads/*:refs/remotes/Origin/*'
git fetch --all
"""
C'est grâce à cette réponse https://stackoverflow.com/a/39986737/1988883
Cela évite également de devoir configurer Jenkins pour les approbations de script GitSCM ce que je devais faire pour essayer les deux solutions ci-dessus.
Le problème est que Jenkins définit la Origin
avec uniquement la branche découverte.
La réponse de @ swoop81 fonctionne, mais si vous souhaitez simplement passer à la caisse d'une branche, vous pouvez ne récupérer que celle-ci.
git config --add remote.Origin.fetch +refs/heads/<branch-name>:refs/remotes/Origin/<branch-name>
git fetch --no-tags https://<github-url> +refs/heads/<branch-name>:refs/remotes/Origin/<branch-name>