在處理POM之後,Jenkins構建是否可以知道項目的Maven版本號?在Jenkins中獲取Maven版本
我有一些項目,其中版本控制是由Maven控制的,在後期構建工作中,我們想創建一個Debian包並調用一些shell腳本。我需要的是Maven曾經作爲Jenkins環境變量提供的版本號,所以我可以將它傳遞給構建後的操作。
要清楚,我是而不是需要知道如何讓Jenkins將版本號傳遞給Maven;相反,我希望Maven將一個版本號傳遞給Jenkins!
在處理POM之後,Jenkins構建是否可以知道項目的Maven版本號?在Jenkins中獲取Maven版本
我有一些項目,其中版本控制是由Maven控制的,在後期構建工作中,我們想創建一個Debian包並調用一些shell腳本。我需要的是Maven曾經作爲Jenkins環境變量提供的版本號,所以我可以將它傳遞給構建後的操作。
要清楚,我是而不是需要知道如何讓Jenkins將版本號傳遞給Maven;相反,我希望Maven將一個版本號傳遞給Jenkins!
很多四處之後(我從來沒有意識到不良的記錄詹金斯怎麼樣了!)我發現了一個很平凡的解決方案。
Post Step
到Maven構建類型的Execute **system** Groovy script
腳本:
import hudson.model.*;
import hudson.util.*;
def thr = Thread.currentThread();
def currentBuild = thr?.executable;
def mavenVer = currentBuild.getParent().getModules().toArray()[0].getVersion();
def newParamAction = new hudson.model.ParametersAction(new hudson.model.StringParameterValue("MAVEN_VERSION", mavenVer));
currentBuild.addAction(newParamAction);
調用的構建環境變量MAVEN_VERSION
現在可用於以通常方式替換到其他構建後步驟(${MAVEN_VERSION}
)。我將其用於Git標記等。
這個工程就像一個魅力,如果你更新'def mavenVer ='行到什麼在你的[稍後跟進](http://stackoverflow.com/a/10205702/487663) - def mavenVer = currentBuild.getParent() .getModules()。toArray()[0] .getVersion();' – 2012-09-26 13:13:36
確實將「def mavenVer ...」替換爲上一條評論中的代碼。 – 2012-10-29 15:25:24
這與'POM_VERSION'相同,因爲這個bug .jenkins-ci.org/browse/JENKINS-24869 – yegeniy 2016-10-31 14:35:55
我們使用了Groovy Postbuild Plugin。
String regex = '.*\\[INFO\\] Building .+ (.+)';
def matcher = manager.getLogMatcher(regex);
if (matcher == null) {
version = null;
} else {
version = matcher.group(1);
}
將此添加到Jenkins供以後使用有點棘手。給我一個鏡頭,雖然我記得這讓我們頭疼。 (很抱歉,我們在很久以前這樣做)
def addBuildParameter(String key, String value) {
manager.build.addAction(new hudson.model.ParametersAction(new hudson.model.StringParameterValue(key,value)));
}
你會怎樣做,然後'版本'可用於其他事情步驟的工作? – 2012-03-28 11:22:56
你好,我有點擴大了答案。祝你好運! – 2012-03-28 11:41:25
此解決方案適用於在POM文件中使用變量有動態填充的版本號的情況。在這些情況下使用POM_VERSION或解析pom.xml文件將不起作用。 – swbandit 2015-02-10 15:42:51
與Groovy解析pom時所提出的需求和解決方案相同。
import jenkins.util.*;
import jenkins.model.*;
def thr = Thread.currentThread();
def currentBuild = thr?.executable;
def workspace = currentBuild.getModuleRoot().absolutize().toString();
def project = new XmlSlurper().parse(new File("$workspace/pom.xml"))
def param = new hudson.model.StringParameterValue("project.version", project.version.toString())
currentBuild.addAction(new hudson.model.ParametersAction(param));
添加此腳本類型的後工序「執行系統Groovy腳本」(所以安裝的Groovy是沒有必要的),並粘貼在「常規命令」的代碼。
請參閱[項目版本從maven到sonar -using-hudson](http://stackoverflow.com/questions/14691818/project-version-from-maven-to-sonar-using-hudson/15879456# 15879456) – Sylvain 2013-04-08 12:51:57
我嘗試在shell腳本步驟中使用'$ {project.version}',之後它失敗了:''''''''''''''''''''''' 。似乎jenkins不允許var名稱中的'dot'? – yetanothercoder 2013-05-20 10:01:09
這在Jenkins 2.46+中似乎不起作用。雖然Groovy提取的版本很好,但我的Freestyle項目的其餘部分中的'project.version'環境變量是空的。在Jenkins 2+中有沒有改變它的作用?我試圖以'$ {project.version}'的形式訪問這個var' – 2017-07-26 21:14:43
你也可以這樣做:
MAVEN_VERSION=`grep A -2 -B 2 "<your_project_name>" pom.xml | grep version | cut -d\> -f 2 | cut -d\< -f 1`-commit-"`echo $GIT_COMMIT`"
說明:假設你一兩行中有你的項目名稱高於/低於版本像一個正常的POM:
<groupId>org.apache.bigtop</groupId>
<artifactId>bigpetstore</artifactId>
<version>1.0-SNAPSHOT</version>
然後你就可以很容易地對於artifactId使用grep,使用「before/after」grep操作來吸引版本,然後grep版本,並使用簡單的unix「cut」命令來拼接出「版本」標籤之間的內容。
我喜歡Jenkins-groovy集成,但是這很容易,即使在你不能控制的構建服務器上(即bash是通用的),它也能工作。
這個工作就像一個魅力,但是獲取了多個版本信息,因爲它也包含一個版本標籤。 在它爲我工作的grep和管道之前添加一個頭 MAVEN_VERSION ='head「
@JoeDred我仍然獲得多個版本。但我的 「另一版本」 是不是從依賴,但是從性能:**
@agad也許你應該限制你管道的第一個grep。 Head採用可選參數-n或--lines。試試** head --help **,它顯示了它是如何使用的。 – JoeDred 2017-01-20 07:03:36
您可以使用$ {POM_VERSION}變量,這與https://issues.jenkins-ci.org/browse/JENKINS-18272
太棒了!驗證你需要Jenkins maven plugin v2.3或更高版本的'$ {POM_VERSION}'工作,我認爲它需要是一個Maven項目類型。 – 2014-05-13 12:55:08
這不適合我。 Jenkins中的Maven Interation插件是2.5版本,仍然是這樣說的:$ {ENV,var =「POM_VERSION」}:如果我嘗試直接或通過上述方式嘗試使用此變量,則會導致錯誤的替換。 「Build Number Set」插件框中的「$ {POM_VERSION}。$ {BUILD_NUMBER}」中無法識別宏'POM_VERSION'。 – 2014-07-30 20:46:28
請記住,POM_VERSION不會考慮可能已傳遞給maven構建過程的任何環境變量。例如:
介紹,執行中的「執行shell」的Maven插件「的exec-Maven的插件」作爲「條件步」工作對我來說:
mvn -q -Dexec.executable="echo" -Dexec.args='${projects.version}' --non-recursive org.codehaus.mojo:exec-maven-plugin:1.3.1:exec
整合詹金斯:
-> "Add post-build step"
-> "Conditional steps (single or multiple)"
-> "Execute Shell:"
出口MY_POM_VERSION =`MVN -q -Dexec.executable =「ECH o「 -Dexec.args ='$ {projects.version}' - 非遞歸org.codehaus.mojo:exec-maven-plugin:1.3.1:exec` & & [[ 」$ {MY_POM_VERSION}「 == 「THE_VERSION_TO_BE_MATCHED」]] & &呼應 「CONDITION_IS_MET」
-> "Steps to run if condition is met"
-> Add any build step you need
注:
這種方法比「grep」更可靠,如果沒有安裝Jenkins Ruby插件,它可能是一種替代方案。
正如已經指出的其他答案,如果您使用Maven項目類型,您可以訪問$ POM_VERSION變量。但如果你不是,你可以使用這一系列的步驟(醜陋但可靠)。這樣做依賴於相同版本的maven來確定pom版本(同時處理複雜的父/子pom繼承,其中<版本>可能甚至不存在給孩子)。
Maven的一步這一目標:
org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version -l version.log
殼牌邁:(您可能需要調整路徑取決於你的層次結構件version.log)
echo "POM_VERSION=$(grep -v '\[' version.log)" > props.properties
進樣環境變量步驟(環境噴油器插件):
屬性文件路徑:props.properties
現在你可以使用$ POM_VERSION彷彿這是一個Maven項目。
這是幹什麼的:使用maven打印輸出一起輸出的版本,然後輸出只剩下版本的輸出亂碼,使用屬性文件格式將其寫入文件,然後將其注入到構建中環境。這比像mvn ..... | grep -v '\['
這樣的單線程更好的原因在於,使用Maven步驟不會對已安裝的Maven版本做出假設,並且將通過與任何其他Maven步驟相同的自動安裝進行處理。
存在grep過濾器的一個問題:如果你沒有存儲庫中的插件,你會得到還有POM_VERSION中的「下載...」行。例如:'+ echo'POM_VERSION =正在下載:...' – apa64 2017-11-22 08:23:57
解決方案:
POM_VERSION=$(\
xmlstarlet sel \
-N x='http://maven.apache.org/POM/4.0.0' \
-t \
-v '//x:project/x:version/text()' \
pom.xml \
)
說明:
您可以在一個班輪使用命令行工具的XPath,如在 「How to execute XPath one-liners from shell?」 提到的那些做到這一點。我選擇了XMLStarlet,但它們都有類似的語法。
解析POM時,必須考慮命名空間。文檔here幫助我弄清楚了這一點。
爲了獲取XPath中元素的文本,可以使用text()函數,如XPath: select text node中所述。
我POM看起來是這樣的:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.foo.bar</groupId>
<artifactId>foobar</artifactId>
<version>1.0.6-SNAPSHOT</version>
<packaging>jar</packaging>
的這裏的缺點是,如果命名空間的變化,你必須改變的命令。
我在聲明式管道作業中使用Pipeline Utility Steps插件來獲取Maven版本。在下面的示例中,我使用腳本變量而不是環境變量,因爲可以修改並在各階段之間傳遞。
def TAG_SELECTOR = "UNINTIALIZED"
pipeline {
agent any
stages {
stage('Build') {
steps {
sh "mvn --batch-mode -U deploy"
script {
TAG_SELECTOR = readMavenPom().getVersion()
}
echo("TAG_SELECTOR=${TAG_SELECTOR}")
}
}
}
}
注:您必須在創建工作後,批准的getVersion()方法管理詹金斯>在處理腳本審批。
參見:
只是一個建議:這個是什麼:http://mojo.codehaus.org/deb-maven-plugin/ – khmarbaise 2012-03-28 09:04:51