Verwendung des Maven Release Plugins in der Jenkins-Pipeline

Lesezeit: 7 Minuten

Ich verwende Jenkins Pipeline, um meine Java-Apps automatisch zu erstellen und bereitzustellen. Ich verwende auch maven-release-plugin, um die Maven-Bereitstellung in Artifactory durchzuführen.

Das Problem ist meine Jenkinsfile (oder Jenkins Pipeline Configuration):

  1. Wir schreiben eine Version 0.1.00-SNAPSHOT in den Release-Zweig
  2. Jenkins Pipeline erhält den Code und führt die Maven-Freigabe durch
  3. Maven Release ändert die Version auf 0.1.00
  4. Maven Release markiert den GIT-Zweig, schreibt das Artefakt fest und stellt es bereit
  5. Maven Release ändert die Version auf 0.2.00-SNAPSHOT und committe
  6. Die Jenkins-Pipeline erkennt eine Änderung im GIT und löst daher einen neuen Build aus

Sie haben verstanden, dass der letzte Schritt eine Endlosschleife erzeugt, selbst wenn es keinen nützlichen Commit gibt.

Hier ist der interessante Teil meiner Jenkinsfile:

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

Wie kann ich die Schleife unterbrechen (vermeiden, dass Jenkins einen neuen Build auslöst, wenn Maven auf GIT festschreibt)?

Vielen Dank

  • Entschuldigung, ich verstehe es nicht, Sie möchten bei jeder Änderung einen Build durchführen, und das ist üblich, aber warum führen Sie bei jedem Commit auch eine Veröffentlichung durch? Ich denke, das Problem ist, dass der durch den Commit ausgelöste Build nicht auch eine Freigabe ausführen sollte. Meiner Meinung nach sollte der ausgelöste Job der Build-Job sein, der Release-Job sollte nicht automatisch ausgelöst werden. Die erste Art von Job wird es nicht haben Jede Schleife, da ein einfacher Maven-Build nichts festschreibt, sollte die Veröffentlichung nicht durch eine Festschreibung ausgelöst werden, da sie selbst eine letzte Festschreibung durchführt, um die Dev-Version zu aktualisieren … eine Schleife zu erstellen

    – ivoruJavaBoy

    26. August 2016 um 8:30 Uhr


  • Das Ziel ist es, automatisch ein Maven-Release durchzuführen, wenn etwas auf den „Release“-Zweig gepusht wird. Ich löse bereits Build auf jedem „Master“-Zweig aus, um einen Komponententest durchzuführen. Wenn Sie möchten, könnte es als Continuous Deployment bezeichnet werden.

    – frinux

    26. August 2016 um 8:36 Uhr

  • Meine Schuld, ich habe verpasst, als Sie sich auf die Release-Zweige bezogen haben. Lassen Sie mich darüber nachdenken, klingt interessant 🙂

    – ivoruJavaBoy

    26. August 2016 um 8:39 Uhr

  • Ich habe einige Ideen: Können Sie den Pom von der Änderung vermeiden, um die Veröffentlichung auszulösen? Es sollte das Problem beheben, da meiner Annahme nach die einzige Übergabe des Plugins in den Zweigen die aktualisierte DEV-Version ist. Außerdem können Sie eine Datei mit der Pipeline erstellen, wobei Sie die von Maven übergebene Revision notieren und vor jeder Veröffentlichung von Maven danach suchen , wenn die Revision dieselbe ist, möchtest du die Veröffentlichung erneut auslösen, wenn nicht, würdest du auslösen. Wie klingt es?

    – ivoruJavaBoy

    26. August 2016 um 8:49 Uhr


  • Nur aus Neugier, wäre das Ignorieren von Commits bestimmter Benutzer/Pfade unter „Zusätzliche Verhaltensweisen“ im SCM-Git-Schritt eine Möglichkeit? Ich gehe davon aus, dass Jenkins als Systembenutzer ausgeführt wird, sodass Sie alle Commits von diesem Benutzer ignorieren könnten, um einen neuen Build auszulösen. Oder Sie könnten diese Datei ignorieren, um einen neuen Build auszulösen?

    – Daniel Omoto

    27. August 2016 um 7:34 Uhr


Benutzer-Avatar
Dennis Hör

IMHO mit dem Aufkommen von Git- und Pull-Anforderungen halte ich die Verwendung von maven-release-plugin oder maven-version-plugin mit einer Jenkins-Pipeline für keine gute Idee.

Die Verwendung von Multibranch Pipeline mit der hier erwähnten Versionierungstechnik entspricht eher der kontinuierlichen Bereitstellung:
https://axelfontaine.com/blog/dead-burried.html

Unter Verwendung der obigen Versionierungstechnik sieht die pom.xml nun so aus:

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

Sie können jetzt ganz einfach Releases auf Ihrem Jenkins-Server erstellen, indem Sie eine Multibranch-Pipeline mit einer Jenkins-Datei konfigurieren, um auf allen Branches aufzubauen und nur vom Master-Branch bereitzustellen:

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}'
      }
    }
  }
} 

Sehen https://jenkins.io/blog/2017/02/07/declarative-maven-project/#set-up zum Konfigurieren einer Multibranch-Pipeline.

Mit dieser Technik entwickeln Sie nur auf Nicht-Master-Branches. Erstellen Sie dann eine Pull-Anforderung, um Ihre Änderungen wieder mit dem Master-Branch zusammenzuführen. Dadurch sollte Ihr Artefakt automatisch in Ihrem Artefakt-Repository bereitgestellt werden.


Nachtrag

Beim Veröffentlichen in einem Maven-Repository mit der obigen Methode hat die pom.xml nicht die richtige Version. Um Maven dazu zu bringen, die richtige Version zu veröffentlichen, verwenden Sie das flatten-maven-plugin: http://www.mojohaus.org/flatten-maven-plugin/usage.html.

Siehe auch: https://maven.apache.org/maven-ci-friendly.html

  • Was passiert also an dem Tag, an dem Sie einen Bugfix aus dem Tag (Zweig des Tags) erstellen müssen? Wie ich verstehe, werden mit dem obigen Prozess nur die Artefakte bereitgestellt, die strenge Versionen erhalten. Die Versionen auf dem Tag in der Quelle enthalten immer noch -SNAPSHOT, daher gibt es keine Garantie dafür, dass Sie beim späteren Erstellen dasselbe Ergebnis erhalten.

    – u123

    25. Januar 2018 um 13:11 Uhr

  • Das ist eine gute Frage. Wenn Sie einen Zweig aus einem Tag erstellen, können Sie die Jenkins-Datei aktualisieren, z. B. das Tag 1.0.5 verzweigen und die Revision auf aktualisieren REVISION = "1.0.5.${env.BUILD_ID}"

    – Dennis Hör

    26. Januar 2018 um 2:52 Uhr

  • Maven beschwert sich <version>${revision}</version> in einem Root-Pom und wird nicht ausgeführt, wenn sich dies in einem Modul-Pom befindet. Dieser Ansatz funktioniert meiner Meinung nach also nicht für Projekte mit mehreren Modulen

    – Adriaan Köster

    4. Oktober 2018 um 8:29 Uhr

  • @AdriaanKoster verwenden Sie möglicherweise die Maven-Version, die diese Funktion nicht unterstützt. Entsprechend maven.apache.org/maven-ci-friendly.html Sie benötigen Maven 3.5.0-beta-1 oder höher und Multimodul-Projekte werden unterstützt

    – Michail Skotnikow

    20. November 2020 um 6:07 Uhr


  • @MikhailSkotnikov Mein Kommentar stammt aus dem Jahr 2018, also hat es wohl damals nicht funktioniert. Danke für das Update.

    – Adriaan Köster

    20. November 2020 um 9:40 Uhr

Dank des Kommentars von @Daniel Omoto habe ich herausgefunden, dass Jenkins eine Option für die GIT-Abfrage bietet. Eines ist genau das, was ich brauchte (und das bereitgestellte Beispiel ist für maven-release-plugin!):

GIT-Umfrage-Screenshot

Falls jemand das gleiche Problem mit der Schleife hat oder dass nachfolgende Builds ausgelöst werden, ABER einen Trigger hat, der die Jenkins-Pipeline bei jedem Push zum Repository startet (anstelle von Abfragen).

Hier ist, wer ich es getan habe: Ich habe überprüft, ob der letzte Commit “[maven-release-plugin]“ im Kommentar.

Code in jenkinsfile:

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...>
        }

Folgendes haben wir als ersten Schritt in unsere Pipeline aufgenommen:

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')
     }
}

Sie müssen installieren https://jenkins.io/doc/pipeline/steps/pipeline-utility-steps/ plugin, um maven pom zu lesen, oder geben Sie einfach eine feste Beschreibung für den übersprungenen Build ein. Der Build nach der Veröffentlichung hat eine graue Farbe.

Benutzer-Avatar
Benutzer2131878

Eine Lösung kann darin bestehen, den Post-Receive-Hook zu ändern, der die Benachrichtigungs-URL von jenkins aufruft:

#!/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

1158180cookie-checkVerwendung des Maven Release Plugins in der Jenkins-Pipeline

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy