web-dev-qa-db-fra.com

Jenkinsfile et différentes stratégies pour les branches

J'essaie d'utiliser le fichier Jenkins pour toutes nos versions dans Jenkins, et j'ai le problème suivant . Nous avons essentiellement 3 types de versions:

  • pull-request build - il sera fusionné avec master après la révision du code, et si build fonctionne
  • construction manuelle de demande de tirage - une construction qui fait la même chose que ci-dessus, mais peut être déclenchée manuellement par l'utilisateur (par exemple, au cas où nous aurions un test instable)
  • un pipeline initial de distribution continue - cela va créer le code, le déployer dans le référentiel, installer les artefacts du référentiel sur le serveur cible et y démarrer l'application

Comment dois-je contenir toutes les versions ci-dessus dans un seul fichier Jenkins… .. À l'heure actuelle, la seule idée que j'ai est de créer un géant si cela permet de vérifier quelle branche il s'agit et d'effectuer les étapes.

J'ai donc deux questions:

1. Est-ce une manière appropriée de le faire dans Jenkinsfile?

  1. Comment obtenir le nom de la branche en cours d'exécution dans le type de travail multi-branches?

Pour référence, voici ma Jenkinsfile actuelle:

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: question basée sur l'opinion retirée

31
Krzysztof Krasoń

Vous pouvez ajouter une instruction If pour plusieurs étapes si vous souhaitez ignorer plusieurs étapes en fonction de la branche, comme dans:

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

ou, vous pouvez l'ajouter à chaque étape comme dans:

stage("Deploy"){
  if(env.BRANCH_NAME == 'master'){
   // Deploy steps here
  }
}
23
Sukhman Sandhu

1) Je ne sais pas si c'est approprié, mais si cela résout votre problème, je pense que c'est assez approprié.

2) Pour connaître le nom de la branche, vous pouvez utiliser la variable BRANCH_NAME. Son nom provient du nom de la branche.

${env.BRANCH_NAME}

Voici la réponse: Pipeline Jenkins Multibranch: Quelle est la variable du nom de la branche?

6
Kendru Estrada

Nous avons suivi le modèle utilisé par fabric8 for builds, en le peaufinant au besoin, la variable Jenkinsfile étant utilisée pour définir la logique de traitement de la branche et du déploiement et un fichier release.groovy pour la logique de génération.

Voici à quoi ressemble notre Jenkinsfile pour un pipeline déployé de manière continue dans DEV à partir de la branche 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()
  }
}

Remarque: vous pouvez trouver le code de notre bibliothèque de pipeline globale ici .

3
rbellamy

Je ne sais pas si c'est ce que vous voulez ... Je préfère parce que c'est plus structuré.

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
0
b.ben

Dans mon scenarium, je n'avais besoin de lancer une étape Deploy Artifactory que si la branche était maître (webhook Gitlab), sinon je ne pourrais pas effectuer le déploiement.

Ci-dessous le code de mon jenkinsfile:

stages {

    stage('Download'){

        when{
            environment name: 'gitlabSourceBranch', value: 'master'

        }

        steps{
            echo "### Deploy Artifactory ###"

            }       
    }

}

0
Renato Coutinho

pour les questions 2, vous pourrez peut-être faire

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

depuis que vous sortez de git

0
Ross Beazley