wake-up-neo.com

Ist es nicht möglich, eine andere Filiale in Jenkinsfile zu besuchen?

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.

8
Thomas Kåsene

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:

  • Die Erweiterung LocalBranch wurde hinzugefügt, um sicherzustellen, dass ich zu einem tatsächlichen Zweig auschecke, und nicht nur eine freistehende HEAD.
  • Erweiterung 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.
  • Die SSH-Berechtigungsnachweise wurden mit der Eigenschaft 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"
        }
    }
}
8
Thomas Kåsene

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']]])
4
Matt Schuchard

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

2
swoop81

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>
0
D0m3