2016-04-19 13 views
26

Ich versuche, Jenkins-Datei für alle unsere Builds in Jenkins zu verwenden, und ich habe folgendes Problem. Wir haben im Grunde drei Arten von Builds:Jenkinsfile und verschiedene Strategien für Niederlassungen

  • Pull-Anfrage Baujahr - es nach dem Code-Review zu meistern zusammengeführt werden, und wenn Build arbeitet
  • manuelle Pull-Anfrage Baujahr - einen Build, der das gleiche tut wie oben, kann aber vom Benutzer manuell ausgelöst werden (zB im Fall haben wir einig instabilen Test)
  • eine anfängliche Pipeline kontinuierlich liefern - dies den Code aufbauen, implementieren die zu Repository installiert Artefakte aus dem Repository auf dem Zielserver und startet Anwendung dort

Wie sollte ich alle obigen Builds in einer einzigen Jenkins-Datei enthalten? Im Moment ist die einzige Idee, die ich habe, ein Riese zu machen, wenn das prüft, welcher Zweig es ist und die Schritte machen wird.

So habe ich zwei Fragen:

1. Ist der geeignete Weg, um es in Jenkinsfile zu tun?

  1. Wie erhält man den Namen der aktuell ausgeführten Verzweigung in einem Multi-Branch-Jobtyp?

als Referenz, hier ist meine aktuelle Jenkinsfile:

def servers = ['server1', 'server2'] 

def version = "1.0.0-${env.BUILD_ID}" 

stage 'Build, UT, IT' 
node { 
    checkout scm 
    env.PATH = "${tool 'Maven'}/bin:${env.PATH}" 
    withEnv(["PATH+MAVEN=${tool 'Maven'}/bin"]) { 
     sh "mvn -e org.codehaus.mojo:versions-maven-plugin:2.1:set -DnewVersion=$version -DgenerateBackupPoms=false" 
     sh 'mvn -e clean deploy' 
     sh 'mvn -e scm:tag' 
    } 
} 


def nodes = [:] 
for (int i = 0; i < servers.size(); i++) { 
    def server = servers.get(i) 
    nodes["$server"] = { 
     stage "Deploy to INT ($server)" 
     node { 
      sshagent(['SOME-ID']) { 
       sh """ 
       ssh ${server}.example.com <<END 
       hostname 
       /apps/stop.sh 
       yum -y update-to my-app.noarch 
       /apps/start.sh 
       END""".stripIndent() 
      } 
     } 
    } 
} 

parallel nodes 

EDIT: entfernt Beurteilung aufgrund Frage

+0

Mögliche Duplikat [Jenkins Pipeline mehrfach verzweigten: Was die Zweignamen Variable] (http://stackoverflow.com/questions/32789619/jenkins-multibranch-pipeline-what- is-the-branch-name-variable) –

Antwort

5

1) Ich weiß nicht, ob es angemessen ist, aber wenn es Ihr Problem löst, Ich denke, es ist angemessen genug.

2) Um den Namen der Branche wissen Sie branch_name Variable verwenden können, wird sein Name von dem Zweignamen genommen. Hier

${env.BRANCH_NAME} 

ist die Antwort: Jenkins Multibranch pipeline: What is the branch name variable?

+10

Eigentlich ist es '$ {env.BRANCH_NAME}' –

+0

ja, du hast Recht –

0

für Fragen 2 Sie in der Lage sein kann

sh 'git branch> GIT_BRANCH' def gitBranch = readfile 'GIT_BRANCH'

zu tun da Sie überprüfen von git aus

4

Wir folgten dem Modell vonverwendetfür Builds, optimieren Sie es wie wir brauchten, wobei die Jenkinsfile verwendet wird, um die Verzweigung und Deployment-Handling-Logik zu definieren, und eine release.groovy Datei für Build-Logik.

Hier ist, was unsere Jenkinsfile wie für eine Pipeline sieht, die in DEV setzt sich kontinuierlich von master-Zweig:

#!groovy 
import com.terradatum.jenkins.workflow.* 

node { 

    wrap([$class: 'TimestamperBuildWrapper']) { 
    checkout scm 

    echo "branch: ${env.BRANCH_NAME}" 
    def pipeline = load "${pwd()}/release.groovy" 

    if (env.DEPLOY_ENV != null) { 
     if (env.DEPLOY_ENV.trim() == 'STAGE') { 
     setDisplayName(pipeline.staging() as Version) 
     } else if (env.DEPLOY_ENV.trim() == 'PROD') { 
     setDisplayName(pipeline.production() as Version) 
     } 
    } else if (env.BRANCH_NAME == 'master') { 
     try { 
     setDisplayName(pipeline.development() as Version) 
     } catch (Exception e) { 
     hipchatSend color: 'RED', failOnError: true, message: "<p>BUILD FAILED: </p><p>Check console output at <a href='${env.BUILD_URL}'>${env.JOB_NAME} [${env.BUILD_NUMBER}]</a></p><p><pre>${e.message}</pre></p>", notify: true, room: 'Aergo', v2enabled: false 
     throw e; // rethrow so the build is considered failed 
     } 
    } else { 
     setDisplayName(pipeline.other() as Version) 
    } 
    } 
} 

def setDisplayName(Version version) { 
    if (version) { 
    currentBuild.displayName = version.toString() 
    } 
} 

Hinweis: Sie den Code für unsere globale Pipeline Bibliothek here finden.

+0

Ich sage, das war wirklich hilfreich für mich, aber warum benutze stattdessen die release.groovy Datei die Methoden von release.groovy unter vars/... einzubinden und global zugänglich zu machen, ohne release.groovy zu laden? Ich frage nur, weil ich eine ähnliche Straße hinuntergehen soll, wo meine 'root' Jenkinsdatei nur config für die Pipeline enthält, umhüllt von einer Methode von vars/..., die den gesamten Build definiert, wobei vars/... Methoden geladen werden und globale Bibliotheken nach Bedarf. Das Ziel besteht darin, Endbenutzer ihre eigenen Jenkins-Dateien schreiben zu lassen, indem sie die notwendige Konfiguration definieren und ihren Build-Typ aufrufen. – user797963

+0

Hier ist ein Link, der besser erklärt, was ich vorhabe: https://jenkins.io/doc/book/pipeline/shared-libraries/#defining-a-more-structureddsl. Die Jenkins-Datei würde alle notwendigen Konfigurationsdateien in buildPlugin {} enthalten, und die buildPlugin.groovy-Datei würde mehrere Stufen und Schritte enthalten, um den gesamten Build auszuführen (nicht nur das triviale Beispiel in der Verknüpfung). – user797963

+0

Sie könnten den Code von 'release.groovy' sicher in Ihre globale Pipeline-Bibliothek verschieben, mit dem Vorbehalt, dass Sie eine Situation vermeiden möchten, in der Sie Code haben, der für einen einzelnen Build in einer Bibliothek spezifisch ist ALLE baut. – rbellamy

12

Sie können hinzufügen If-Anweisung für mehrere Stufen, wenn Sie mehrere Stufen nach dem Zweig überspringen wollen, wie in:

if(env.BRANCH_NAME == 'master'){ 
    stage("Upload"){ 
     // Artifact repository upload steps here 
     } 
    stage("Deploy"){ 
     // Deploy steps here 
     } 
    } 

oder, können Sie es auf einzelne Stufe wie in hinzufügen:

stage("Deploy"){ 
    if(env.BRANCH_NAME == 'master'){ 
    // Deploy steps here 
    } 
} 
+0

einfach und ausgezeichnet! – oblivion

0

Weiß nicht, ob das was du willst .. Ich bevorzuge, weil es strukturierter aussieht.

Jenkinsfile

node { 
    def rootDir = pwd() 

    def branchName = ${env.BRANCH_NAME} 

    // Workaround for pipeline (not multibranches pipeline) 
    def branchName = getCurrentBranch() 

    echo 'BRANCH.. ' + branchName 
    load "${rootDir}@script/Jenkinsfile.${branchName}.Groovy" 
} 

def getCurrentBranch() { 
    return sh (
     script: 'git rev-parse --abbrev-ref HEAD', 
     returnStdout: true 
    ).trim() 
} 

Jenkinsfile. mybranch .groovy

echo 'mybranch' 
// Pipeline code here 
Verwandte Themen