Ich habe zwei Zweige in BitBucket: master
und develop
. Ich habe auch einen BitBucket Team Folder-Job auf meinem Jenkins-Server konfiguriert, um dieses Repository zu erstellen. Auf dem Zweig develop
gibt es folgende Jenkins-Datei:
node {
stage('Checkout') {
checkout scm
}
stage('Try different branch') {
sh "git branch -r"
sh "git checkout master"
}
}
Wenn Jenkins es ausführt, schlägt der Build fehl, wenn versucht wird, master
auszuchecken:
[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] }
Ich hatte erwartet, dass der Befehl git branch -r
sowohl Origin/master
als auch Origin/develop
ausdrucken würde, aber aus irgendeinem Grund wird nur der letztere gedruckt.
Ich habe herumgelesen und versucht, die folgenden Möglichkeiten zu finden: Zum Beispiel habe ich versucht, das SSH-Agenten-Plugin für Jenkins zu installieren und die Jenkins-Datei zu ändern:
node {
stage('Checkout') {
checkout scm
}
stage('Try different branch') {
sshagent(['Bitbucket']) {
sh "git branch -r"
sh "git checkout master"
}
}
}
Es scheint aber immer noch nicht Origin/master
zu finden. Was noch schlimmer ist, der SSH-Agent scheint vor dem Auschecken von master
zu töten:
[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-tes[email protected]tmp/private_key_2394129657382526146.key
Identity added: /var/jenkins_home/workspace/e_jenkinsfile-tes[email protected]tmp/private_key_2394129657382526146.key (/var/jenkins_home/workspace/e_jenkinsfile-tes[email protected]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] }
Mein letzter Plan ist es, etwas in develop
zu übergeben und dann in master
zu mischen, aber bisher hatte ich wenig Glück. Hat jemand eine mögliche Lösung oder einen Workaround?
PS: Dies scheint nur ein Problem in Jenkinsfile zu sein. Ich habe einen Freestyle-Job, der etwas tut, was ich will, und es funktioniert gut.
Nach einigen Stunden Versuch und Irrtum habe ich eine mögliche Lösung gefunden. Es baut teilweise auf Matts Antwort auf, aber ich musste es ändern, damit es funktioniert.
Matt hatte im Wesentlichen recht: checkout scm
war einfach nicht flexibel genug, um mir das zu ermöglichen, was ich brauchte, also musste ich GitSCM
verwenden, um es anzupassen. Die wichtigsten Punkte von Interesse sind:
LocalBranch
wurde hinzugefügt, um sicherzustellen, dass ich zu einem tatsächlichen Zweig auschecke, und nicht nur eine freistehende HEAD
.WipeWorkspace
hinzugefügt, um alles im Arbeitsbereich zu löschen und einen vollständigen Klon zu erzwingen. Ich denke nicht, dass dies ein Teil der Lösung meiner Frage war, aber es war trotzdem praktisch.credentialsId
angegeben, da das Repository privat ist.Aus welchem Grund auch immer, wenn der Schritt checkout
ausgeführt wird, wird der Zweig nur ausgecheckt, aber nicht festgelegt, dass er den entfernten Zweig verfolgt. Bis ich eine elegantere Lösung gefunden habe, musste ich dies manuell tun.
Nachdem alles erledigt war, konnte ich reguläre sh "git checkout master"
und sogar sh "git Push"
verwenden, solange ich sie in einem sshagent
-Schritt einfügte.
Ich habe unten ein funktionierendes Beispiel für das resultierende Jenkinsfile hinzugefügt. Beachten Sie jedoch, dass es nicht für produktionsnahe Elemente verwendet werden sollte, da es sich noch in den Kinderschuhen befindet. Versionsnummern und keine Überprüfungen, in welchem Zweig Sie sich befinden.
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"
}
}
}
Sie können die intrinsische Funktion in Jenkins Pipeline verwenden, die für das Klonen und Ziehen von Git erstellt wurde. Ich würde auch vorschlagen, die Zweige in separate Verzeichnisse zu klonen.
checkout([$class: 'GitSCM',
branches: [[name: '*/branch_name']],
doGenerateSubmoduleConfigurations: false,
extensions: [[$class: 'RelativeTargetDirectory',
relativeTargetDir: 'different_directory']],
submoduleCfg: [],
userRemoteConfigs: [[url: '[email protected]:org/repo.git']]])
Ich konnte die beiden obigen Antworten nicht zum Laufen bringen. Ich habe einen Jenkins-Pipeline-Job ausgelöst, indem ich einen Zweig angegeben habe, und habe versucht, einen anderen Zweig (Entwicklung) des Jobs zu überprüfen, der fehlgeschlagen ist mit:
error: pathspec 'develop' did not match any file(s) known to git.
Ich konnte dies in dem fehlgeschlagenen Job sehen, der darauf hinwies, dass nur der auslösende Zweig abgerufen wurde:
git fetch --no-tags --progress https://<github URL> +refs/heads/branch-name:refs/remotes/Origin/branch-name
Ich habe es zum Laufen gebracht, indem ich die entfernte Abrufkonfiguration geändert und alle Zweige abgerufen habe, indem ich Folgendes getan habe, nachdem ich nur den Standardschritt checkout scm
in der Jenkinsfile des ausgelösten Jobs ausgeführt habe:
sh """
git config remote.Origin.fetch '+refs/heads/*:refs/remotes/Origin/*'
git fetch --all
"""
Dies ist dank dieser Antwort https://stackoverflow.com/a/39986737/1988883
Dies vermeidet auch die Notwendigkeit, Jenkins für GitSCM-Skriptfreigaben zu konfigurieren, was ich tun musste, um die beiden oben genannten Lösungen auszuprobieren
Das Problem ist, dass Jenkins die Variable Origin
nur mit dem erkannten Zweig definiert.
@Swoop81 Antwort funktioniert, aber wenn Sie nur einen Zweig auschecken möchten, können Sie nur diesen Zweig abrufen.
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>