2016-04-19 14 views
26

Sto cercando di utilizzare il file Jenkins per tutte le nostre build in Jenkins e ho il seguente problema. Fondamentalmente abbiamo 3 tipi di build:Jenkinsfile e diverse strategie per le diramazioni

  • estraibile richiesta Costruito - verrà unito al master dopo la revisione del codice, e se costruire opere
  • manuale estraibile richiesta Costruito - una build che fa lo stesso sopra, ma può essere attivato manualmente dall'utente (ad esempio nel caso di test instabili)
  • una pipeline di consegna continua iniziale: questo costruirà il codice, distribuirà nel repository, installerà le risorse dal repository sul server di destinazione e avvierà il applicazione lì

Come dovrei contenere tutte le build precedenti in un singolo Jenkinsfile. In questo momento l'unica idea che ho è quella di creare un gigante se questo controllerà quale ramo è e farà i passi.

Così ho due domande:

1. E 'in questo modo appropriato per farlo in Jenkinsfile?

  1. Come ottenere il nome del ramo attualmente in esecuzione nel tipo di lavoro multi-ramo?

Per riferimento, ecco la mia attuale 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: parere rimosso domanda basata

+0

Eventuali duplicati di [Jenkins multiramo gasdotto:? Qual è la variabile nome del ramo] (http://stackoverflow.com/questions/32789619/jenkins-multibranch-pipeline-what- is-the-branch-name-variable) –

risposta

5

1) Non so se è appropriato, ma se si risolve il problema, Penso sia abbastanza appropriato.

2) Per conoscere il nome del ramo è possibile utilizzare la variabile BRANCH_NAME, il suo nome è preso dal nome del ramo.

${env.BRANCH_NAME} 

ecco la risposta: Jenkins Multibranch pipeline: What is the branch name variable?

+10

In realtà è '$ {env.BRANCH_NAME}' –

+0

sì, hai ragione, –

0

per le domande 2 si può essere in grado di fare

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

visto che stai provando da git

4

Abbiamo seguito il modello utilizzato da fabric8 per le build, ottimizzandolo come necessario, dove viene utilizzato lo Jenkinsfile per definire la logica di gestione di ramo e distribuzione e un file release.groovy per la logica di build.

Ecco ciò che il nostro Jenkinsfile sembra per un oleodotto che distribuisce in modo continuo in DEV dal ramo principale:

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

Nota: è possibile trovare il codice per la nostra biblioteca gasdotto globale here.

+0

Dirò, questo è stato molto utile per me, ma perché usare il file release.groovy di includere i metodi da release.groovy sotto vars/... e averli accessibili globalmente senza dover caricare release.groovy? Te lo chiedo solo perché sto per percorrere una strada simile dove il mio Jenkinsfile 'root' contiene solo config per la pipeline, racchiuso da un metodo di vars/... che definisce l'intera build, caricamento dei metodi vars/... e libs globali, se necessario. L'obiettivo qui è di lasciare che gli utenti finali scrivano i propri Jenkinsfiles definendo la configurazione necessaria e chiamando il loro tipo di build. – user797963

+0

Ecco un link che spiega meglio quello che sto cercando: https://jenkins.io/doc/book/pipeline/shared-libraries/#defining-a-more-structured-dsl. Il Jenkinsfile conterrà tutte le configurazioni necessarie in buildPlugin {} e il file buildPlugin.groovy conterrà più fasi e passaggi per eseguire l'intera build (non solo l'esempio banale nel collegamento). – user797963

+0

Si potrebbe certamente spingere il codice da 'release.groovy' nella propria libreria di pipeline globale, con l'avvertenza che si vorrebbe evitare una situazione in cui si ha codice specifico per una singola build in una libreria progettata per servire TUTTE le build. – rbellamy

12

È possibile aggiungere Se dichiarazione per più fasi, se si desidera saltare più fasi a seconda del ramo come in:

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

o, è possibile aggiungerlo alla fase individuale come in:

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

semplice ed eccellente! – oblivion

0

Non so se questo è ciò che vuoi .. Preferisco perché è più strutturato.

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