在使用 jenkins 2(声明式)管道和 maven 时,我总是遇到如何组织管道内的内容以使其可重用和灵活的问题。
一方面,我想将管道分成如下逻辑阶段:
pipeline
{
stages
{
stage('Clean') {}
stage('Build') {}
stage('Test') {}
stage('Sanity check') {}
stage('Documentation') {}
stage('Deploy - Test') {}
stage('Selenium tests') {}
stage('Deploy - Production') {}
stage('Deliver') {}
}
}
另一方面,我有maven,它与
mvn clean deploy site
简单地说,我可以把maven分成
mvn clean
mvn deploy
mvn site
但“部署”包括所有生命周期阶段,从
所以我看到了很多 pipline 的例子,它们可以做这样的事情
sh 'mvn clean compile'
和
sh 'mvn test'
这导致第二次重复验证和编译步骤,并以这种方式浪费“时间/资源”。这可以通过执行
sh 'mvn surefire:test'
而不是再次运行整个生命周期。
所以我的问题是 - 在jenkins pipline阶段和maven生命周期之间取得良好平衡的最佳方法是什么?对我来说,我看到两种方式:
还是我错过了CI / CD实践中的某些内容?
我认为没有正确的答案,但以下示例对我们有用。
stage('Build and Unit Test') {
mvn clean deploy -> with unit tests, without integration tests, deploy local
deploy local:
You can define in a maven profile the distributionManagement like:
<distributionManagement>
<repository>
<id>localFile</id>
<url>file:target/repository/</url>
</repository>
<snapshotRepository>
<id>localFile</id>
<url>file:target/repository/</url>
</snapshotRepository>
</distributionManagement>
}
stage('Pre Integration Tests') {
The binaries are now in target/repository.
From there you can use the binaries as you like.
Copy them to a server, deploy them on an application server, etc.
}
stage('Integration Tests') {
maven failsafe:integration-test failsafe:verify
Already all tests are compiled, just execute them and verify the result.
}
stage('Deploy to Binary Repository (Nexus, Artifactory, etc)') {
Now if everything is ok, finally upload the Binaries.
For that we use wagon-maven-plugin
So from target/repository the files are uploaded to the Binary Repository.
}
因此,总结一下:
两个月后,我想我有了一个平衡良好的Jenkins管道脚本,它不完整,但在windows和linux上运行稳定。它避免了我看到的其他例子的陷阱。
詹金斯文件
pipeline
{
agent any
tools
{
maven 'Maven3'
jdk 'JDK8'
}
options
{
buildDiscarder(logRotator(numToKeepStr: '4'))
skipStagesAfterUnstable()
disableConcurrentBuilds()
}
triggers
{
// MINUTE HOUR DOM MONTH DOW
pollSCM('H 6-18/4 * * 1-5')
}
stages
{
stage('Clean')
{
steps
{
script
{
if (isUnix())
{
sh 'mvn --batch-mode clean'
}
else
{
bat 'mvn --batch-mode clean'
}
}
}
}
stage('Build')
{
steps
{
script
{
if (isUnix())
{
sh 'mvn --batch-mode compile'
}
else
{
bat 'mvn --batch-mode compile'
}
}
}
}
stage('UnitTests')
{
steps
{
script
{
if (isUnix())
{
sh 'mvn --batch-mode resources:testResources compiler:testCompile surefire:test'
}
else
{
bat 'mvn --batch-mode resources:testResources compiler:testCompile surefire:test'
}
}
}
post
{
always
{
junit testResults: 'target/surefire-reports/*.xml'
}
}
}
stage('Sanity check')
{
steps
{
script
{
if (isUnix())
{
sh 'mvn --batch-mode checkstyle:checkstyle pmd:pmd pmd:cpd com.github.spotbugs:spotbugs-maven-plugin:spotbugs'
}
else
{
bat 'mvn --batch-mode checkstyle:checkstyle pmd:pmd pmd:cpd com.github.spotbugs:spotbugs-maven-plugin:spotbugs'
}
}
}
}
stage('Packaging')
{
steps
{
script
{
if (isUnix())
{
sh 'mvn --batch-mode jar:jar'
}
else
{
bat 'mvn --batch-mode jar:jar'
}
}
}
}
stage('install local')
{
steps
{
script
{
if (isUnix())
{
sh 'mvn --batch-mode jar:jar source:jar install:install'
}
else
{
bat 'mvn --batch-mode jar:jar source:jar install:install' // maven-jar-plugin falseCreation default is false, so no doubled jar construction here, but required for maven-install-plugin internal data
}
}
}
}
stage('Documentation')
{
steps
{
script
{
if (isUnix())
{
sh 'mvn --batch-mode site'
}
else
{
bat 'mvn --batch-mode site'
}
}
}
post
{
always
{
publishHTML(target: [reportName: 'Site', reportDir: 'target/site', reportFiles: 'index.html', keepAll: false])
}
}
}
stage('Deploy test')
{
steps
{
script
{
if (isUnix())
{
// todo
}
else
{
bat returnStatus: true, script: 'sc stop Tomcat8'
sleep(time:30, unit:"SECONDS")
bat returnStatus: true, script: 'C:\\scripts\\clean.bat'
bat returnStatus: true, script: 'robocopy "target" "C:\\Program Files\\Apache Software Foundation\\Tomcat 9.0\\webapps" Test.war'
bat 'sc start Tomcat8'
sleep(time:30, unit:"SECONDS")
}
}
}
}
stage('Integration tests')
{
steps
{
script
{
if (isUnix())
{
sh 'mvn --batch-mode failsafe:integration-test failsafe:verify'
}
else
{
bat 'mvn --batch-mode failsafe:integration-test failsafe:verify'
}
}
}
}
}
}
希望这对其他开发者来说是有趣的。
当我随着时间的推移显著改进它时,我会在这里更新它。
对于那些还希望看到maven pom和Jenkinsfile的人,请看看我在github上的小示例项目:TemplateEngine
问题内容: 在使用jenkins 2(声明性)管道和Maven时,我总是在如何组织管道中的事物以使其可重用和灵活方面遇到问题。 一方面,我想将管道分成逻辑阶段,例如: 另一方面,我有与 我可以简单地将Maven拆分为 但是,“部署”包括以下所有生命周期阶段 验证 编译 测试 包 校验 安装 部署 所以我看了很多例子,例如 和 这导致第二次重复验证和编译步骤,并以此方式浪费“时间/资源”。这可以通过
主要内容:生命周期与插件的关系,三套生命周期,clean 生命周期,示例 1,default 生命周期,示例 2,site 生命周期在 Maven 出现之前,项目构建的生命周期就已经存在,开发人员每天都在对项目进行清理,编译,测试及部署,但由于没有统一的规范,不同公司甚至不同项目之间的构建的方式都不尽相同。 Maven 从大量项目和构建工具中学习和反思,最后总结了一套高度完美的,易扩展的生命周期。这个生命周期将项目的清理、初始化、编译、测试、打包、集成测试、验证、部署和站点生成等几乎所有构建过程
我有家长[项目]pom 在子项目[childpom]中,我在第一行得到这个错误 不兼容的生命周期映射插件版本1.4.0跳转到父pom中的定义。 更多环境详情: IDE:Jboss jeveloper studio v9.0.0 JDK:java 8 64位 MAVEN:apache-MAVEN-3.3.3 我是马文的新手,请告诉我哪里出了问题?
我正在玩maven插件,特别是我试图开发一个自定义maven插件的eclipse。一切顺利,它从控制台构建...等等,直到:' “生命周期配置不包括插件执行” 出现。我研究发现: http://wiki.eclipse.org/M2E_plugin_execution_not_covered; 显然我不想忽略插件的执行,执行指令似乎不起作用,至于project configurator的委托,我无
我对铁锈寿命的学习过程如下(基于铁锈书): 我想注释,当引用后面的值超出范围时 通常(并不总是!请参阅. data部分,即'静态')值位于块中 我们注释像这样的块,例如结构字段像 。 在哪一点上我的理解是错误的?提前感谢你对我的宽容。 免责声明:
null