JenkinsビルドがPOMの処理後にプロジェクトのMavenバージョン番号を認識する方法はありますか?
バージョン管理がMavenによって制御されるプロジェクトがいくつかあります。ビルド後のジョブでは、Debianパッケージを作成し、シェルスクリプトを呼び出します。必要なのは、MavenがJenkins環境変数として使用可能であったバージョン番号で、ビルド後のアクションに渡すことができるようにするためです。
明確にするために、私はnot Jenkinsにバージョン番号をMavenに渡す方法を知る必要があります。代わりに、MavenからJenkinsにバージョン番号を渡してほしいです!
多くのことを掘り下げた後(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のタグ付けに使用しています。
https://issues.jenkins-ci.org/browse/JENKINS-18272 で導入された$ {POM_VERSION}変数を使用できます
他の回答がすでに指摘したように、Mavenプロジェクトタイプを使用している場合は、$ POM_VERSION変数にアクセスできます。ただし、そうでない場合は、この一連の手順を使用できます(ugいですが信頼性があります)。この方法で行うと、同じバージョンのmavenに依存してpomバージョンが決定されます(<version>が存在しない複雑な親/子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
Inject Environment Variablesステップ(Environment Injector Plugin):
プロパティファイルパス:_props.properties
_
これで、$ POM_VERSIONをMavenプロジェクトのように使用できます。
これが何をするのか:mavenを使用して、出力の混乱とともにバージョンを印刷し、出力の混乱を把握してバージョンだけを残し、プロパティファイル形式を使用してファイルに書き込み、ビルド環境にそれを注入します。これが_mvn ..... | grep -v '\['
_のようなワンライナーよりも優れている理由は、Mavenステップの使用はインストールされたMavenバージョンについての仮定を行わず、他のMavenステップと同じ自動インストールによって処理されるためです。
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}")
}
}
}
}
注:Manage jenkins> In-process]でジョブを作成した後、getVersion()メソッドを承認する必要があります。スクリプト承認。
こちらもご覧ください:
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をインストールする必要はありません)、「Groovyコマンド」にコードを貼り付けます。
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)));
}
「条件付きステップ」が私のために働いたとして、「シェルを実行」でMavenプラグイン「exec-maven-plugin」を実行します。
mvn -q -Dexec.executable="echo" -Dexec.args='${projects.version}' --non-recursive org.codehaus.mojo:exec-maven-plugin:1.3.1:exec
Jenkinsに統合します。
-> "Add post-build step"
-> "Conditional steps (single or multiple)"
-> "Execute Shell:"
export MY_POM_VERSION = `mvn -q -Dexec.executable =" echo "-Dexec.args = '$ {projects.version}' ---非再帰org.codehaus.mojo:exec-maven-plugin:1.3.1:exec `&& [[" $ {MY_POM_VERSION} "==" THE_VERSION_TO_BE_MATCHED "]] && echo" CONDITION_IS_MET "
-> "Steps to run if condition is met"
-> Add any build step you need
ノート:
このアプローチは「grep」よりも信頼性が高く、Jenkins Rubyプラグインがインストールされていない場合、代替手段になる可能性があります。
解決策:
POM_VERSION=$( \
xmlstarlet sel \
-N x='http://maven.Apache.org/POM/4.0.0' \
-t \
-v '//x:project/x:version/text()' \
pom.xml \
)
説明:
これは、「 シェルからXPathワンライナーを実行する方法? 」で説明したようなコマンドラインXPathツールを使用して、ワンライナーで実行できます。 XMLStarlet を選択しましたが、それらはすべて同様の構文を持っています。
POMを解析するときは、名前空間を考慮する必要があります。ドキュメント here は、これを理解するのに役立ちました。
XPathの要素のテキストを取得するには、 XPath:テキストノードの選択 で説明されているようにtext()関数を使用します。
私の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>
ここでの欠点は、名前空間が変更された場合、コマンドを変更する必要があることです。
次のように「システムGroovyスクリプトの実行」を使用します。
import jenkins.util.*;
import jenkins.model.*;
def thr = Thread.currentThread();
def currentBuild = thr?.executable;
def projectManager = build.getProject()
def file = projectManager.getWorkspace().child("pom.xml");
def project = new XmlSlurper().parseText(file.readToString())
def param = new hudson.model.StringParameterValue("currentVersion", project.version.toString())
currentBuild.addAction(new hudson.model.ParametersAction(param));
Execute System Groovyスクリプトを使用すると、ビルドに直接アクセスでき、そこからプロジェクトを取得できます。したがって、この場合はpom.xmlの「子」ファイルを取得できます。
新しいファイルを作成する必要はなく、ご覧のとおり、ワークスペース内のすべてのファイルに非常に強力なアクセスを提供します。
@Akomの answer に基づいて、POM_VERSIONを使用するための事前手順は次のとおりです。
スクリプト
mvn org.Apache.maven.plugins:maven-help-plugin:evaluate -Dexpression=project.version -l project_version
# grep for the version pattern rather than not mentioning '\['
echo "POM_VERSION=$(grep -E '^[0-9.]+(-SNAPSHOT)?$' project_version)" > your_property_file
あなたもできます:
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のように、プロジェクトの名前が1行または2バージョン上/下にあると仮定します。
<groupId>org.Apache.bigtop</groupId>
<artifactId>bigpetstore</artifactId>
<version>1.0-SNAPSHOT</version>
次に、artifactIdを簡単にgrepし、「before/after」grepアクションを使用してバージョンを取り込み、次にバージョンをgrepし、単純なunixの「cut」コマンドを使用して「version」間でコンテンツを継ぎますタグ。
私はJenkinsとGroovyの統合が好きですが、これはかなり簡単で、制御できないビルドサーバーでも動作します(つまり、bashはユニバーサルであるため)。