web-dev-qa-db-fra.com

Utilisation du plug-in Maven Release dans le pipeline Jenkins

J'utilise Jenkins Pipeline pour créer et déployer automatiquement mes applications Java. J'utilise également maven-release-plugin pour effectuer le déploiement Maven sur Artifactory.

Le problème est mon Jenkinsfile (ou configuration du pipeline Jenkins): 

  1. Nous commettons une version 0.1.00-SNAPSHOT sur la branche release
  2. Jenkins Pipeline obtient le code et effectue la publication de Maven
  3. Maven Release change la version à 0.1.00
  4. Maven Release marque la branche GIT, valide et déploie l'artefact
  5. La version Maven change la version à 0.2.00-SNAPSHOT et commet
  6. Le pipeline Jenkins détecte un changement de GIT et déclenche une nouvelle construction.

Vous avez compris que la dernière étape crée une boucle infinie, même s’il n’ya pas de commit utile.

Voici la partie intéressante de mon Jenkinsfile:

sshagent([git_credential]) {
    sh "${maven_bin} --settings ${maven_settings} -DreleaseVersion=${release_version} -DdevelopmentVersion=${development_version} release:prepare release:perform -B"
}

Comment puis-je rompre la boucle (éviter que Jenkins ne déclenche une nouvelle construction lorsque Maven s’engage sur GIT)?

Merci

13
frinux

Merci à @Daniel Omoto , j'ai découvert que Jenkins fournit une option pour l'interrogation GIT. L'une correspond exactement à ce dont j'avais besoin (et l'exemple fourni est celui de maven-release-plugin!):

 GIT poll screenshot

8
frinux

IMHO avec l'avènement des requêtes git et pull, je ne pense pas que l'utilisation de maven-release-plugin ou de maven-version-plugin avec un pipeline Jenkins soit une bonne idée.

L’utilisation de Multibranch Pipeline avec la technique de gestion des versions mentionnée ici est plus conforme à la distribution continue: https://axelfontaine.com/blog/dead-burried.html

En utilisant la technique de gestion de version ci-dessus, le fichier pom.xml se présente comme suit:

<project>
    ...
    <version>${revision}</version>

    <properties>
        <!-- Sane default when no revision property is passed in from the commandline -->
        <revision>0-SNAPSHOT</revision>
    </properties>

    <scm>
        <connection>scm:git:your-git-repo-url</connection>
    </scm>

    <distributionManagement>
        <repository>
            <id>artifact-repository</id>
            <url>your-artifact-repo-url</url>
        </repository>
    </distributionManagement>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-scm-plugin</artifactId>
                <version>1.9.5</version>
                <configuration>
                   <tag>${project.artifactId}-${project.version}</tag>
                </configuration>
            </plugin>
        </plugins>
    </build>
    ...
</project>

Vous pouvez désormais produire très facilement des versions sur votre serveur Jenkins en configurant un pipeline multibranches avec un fichier Jenkins à construire sur toutes les branches et à déployer uniquement à partir de la branche principale:

pipeline {
  agent any
  environment {
    REVISION = "0.0.${env.BUILD_ID}"
  }
  triggers {
    pollSCM('')
  }
  options {
    disableConcurrentBuilds()
    buildDiscarder(logRotator(numToKeepStr: '30'))
  }
  tools {
    maven '3.5.2'
    jdk 'jdk8'
  }
  stages {
    stage ('Initialize') {
      steps {
        sh '''
          echo "PATH = ${PATH}"
          echo "M2_HOME = ${M2_HOME}"
        '''
      }
    }
    stage ('Build') {
      steps {
        sh 'mvn clean package'
      }
    }
    stage ('Deploy') {
      when {
        branch 'master'
      }
      steps {
        script {
          currentBuild.displayName = "${REVISION}"
        }
        sh 'mvn deploy scm:tag -Drevision=${REVISION}'
      }
    }
  }
} 

Voir https://jenkins.io/blog/2017/02/07/declarative-maven-project/#set-up sur la configuration d'un pipeline multibranches.

Avec cette technique, vous ne développez que sur des branches non maîtres. Créez ensuite une demande d'extraction pour fusionner vos modifications dans la branche principale. Cela devrait ensuite déployer votre artefact automatiquement dans votre référentiel d'artefacts.


Addenda 

Lors de la publication dans un référentiel Maven à l'aide de la méthode ci-dessus, le fichier pom.xml n'aura pas la version appropriée. Pour que Maven publie la version appropriée, utilisez le plugin flatten-maven: http://www.mojohaus.org/flatten-maven-plugin/usage.html .

Consultez également: https://maven.Apache.org/maven-ci-friendly.html

9
Dennis Hoer

Si quelqu'un a le même problème avec la boucle ou que les constructions suivantes sont déclenchées MAIS un déclencheur déclenche le pipeline jenkins à chaque transfert vers le référentiel (au lieu de la scrutation).

Voici qui je l'ai fait: j'ai vérifié si le dernier commit contenait "[maven-release-plugin]" dans le commentaire.

Code dans le fichier jenkins:

def lastCommit = sh returnStdout: true, script: 'git log -1 --pretty=%B'

if (lastCommit.contains("[maven-release-plugin]")){
            sh "echo  Maven release detected"  //dont trigger build

        } else {
            sh "echo Last commit is not from maven release plugin" //do build steps 
            <..build Job...>
        }
7
Daniel Föhr

C’est ce que nous mettons comme première étape dans notre pipeline:

stage('Check commit message') {
     when { changelog '.*\\[maven-release-plugin\\].*' }
     steps {
       script {
          pom = readMavenPom file: 'pom.xml'
          currentBuild.displayName = pom.version
          currentBuild.result = 'NOT_BUILT'
       }
       error('Skipping release build')
     }
}

Vous devrez installer https://jenkins.io/doc/pipeline/steps/pipeline-utility-steps/ plugin pour lire maven pom, ou simplement mettre une description fixe pour la construction ignorée. La construction qui suit la publication aura une couleur grise.

0
anydoby

Une solution peut être de changer le hook post-réception qui appelle l'URL de notification de jenkins:

#!/bin/bash
git_log=$(git log --branches -1)
if ! [[ $git_log =~ .*maven-release-plugin.* ]] ;
then
curl http://buildserver:8080/git/notifyCommit?url=ssh://git@server:22/projects/Name.git;
fi
0
user2131878