maven - 用于创建 Maven 工件和 Docker 映像的 Jenkins 管道
问题描述
我需要我的管道来生成 SNAPSHOT 或发布工件,然后还生成一个带有最新标记或发布版本号的 Docker 映像。我正在使用fabric8 插件并利用将根据POM 文件的版本字段生成标签的功能。
由于阶段的顺序,标签将始终是最新的,无论它是快照还是发布。我需要一些帮助来确定执行此操作的正确方法,因为我看不到将它们按不同顺序排列的方法。
涉及的工具有 Maven + fabric8、Jenkins、Artifactory 和 SVN。
在 Maven 发布和准备步骤之后,POM 将有一个 SNAPSHOT 版本,因此“创建 Docker 映像”阶段将始终生成一个“最新”标签。
我可以做一些事情,比如找出发布版本的 SVN 标签 url 并检查它,然后进行构建。虽然感觉不对,但也许不是。必须有一种更“官方”的方式来做到这一点。
pipeline{
agent any
tools{
maven 'M3'
}
parameters {
booleanParam(
name: 'RELEASE',
description: 'Build a release from current commit.',
defaultValue: false
)
booleanParam(
name: 'SCAN_CODE',
description: 'Scan your code to see how awesome it is.',
defaultValue: true
)
}
environment {
ARTIFACT_ID = readMavenPom().getArtifactId()
}
stages{
stage("Unit tests"){
steps{
configFileProvider([configFile(fileId: '1a4e39cc-eacf-4bd0-af47-337f536fd2bd', variable: 'MVN_SETTINGS')]) {
sh 'mvn -gs $MVN_SETTINGS test '
}
}
}
stage("SonarQube Scan"){
when {
expression { params.SCAN_CODE == true}
}
steps{
withSonarQubeEnv('codequality') {
configFileProvider([configFile(fileId: '1a4e39cc-eacf-4bd0-af47-337f536fd2bd', variable: 'MVN_SETTINGS')]) {
sh 'mvn clean install -gs $MVN_SETTINGS ' +
'org.sonarsource.scanner.maven:sonar-maven-plugin:3.3.0.603:sonar -f pom.xml ' +
'-DskipTests' +
'-Dsonar.projectKey=com.etisoftware:$ARTIFACT_ID ' +
'-Dsonar.login=$DOCKER_REPO_USER ' +
'-Dsonar.password=$DOCKER_REPO_PASSWORD ' +
'-Dsonar.language=java ' +
'-Dsonar.sources=. ' +
'-Dsonar.tests=. ' +
'-Dsonar.test.inclusions=**/*Test*/** ' +
'-Dsonar.exclusions=**/*Test*/**'
}
}
}
}
stage("Quality Gate") {
when {
expression { params.SCAN_CODE == true}
}
steps {
timeout(time: 5, unit: 'MINUTES') {
// Parameter indicates whether to set pipeline to UNSTABLE if Quality Gate fails
// true = set pipeline to UNSTABLE, false = don't
waitForQualityGate abortPipeline: true
}
}
}
stage("Build Snapshot"){
when {
expression { params.RELEASE == false}
}
steps{
configFileProvider([configFile(fileId: '1a4e39cc-eacf-4bd0-af47-337f536fd2bd', variable: 'MVN_SETTINGS')]) {
sh 'mvn -gs $MVN_SETTINGS -DskipTests clean deploy'
}
}
}
stage("Release") {
when {
expression { params.RELEASE == true}
}
steps {
configFileProvider([configFile(fileId: '1a4e39cc-eacf-4bd0-af47-337f536fd2bd', variable: 'MVN_SETTINGS')]) {
sh 'mvn -gs $MVN_SETTINGS clean; ' +
'mvn -gs $MVN_SETTINGS -B release:prepare; ' +
'mvn -gs $MVN_SETTINGS -B release:perform'
}
}
}
stage("Create Docker Image"){
steps{
configFileProvider([configFile(fileId: '1a4e39cc-eacf-4bd0-af47-337f536fd2bd', variable: 'MVN_SETTINGS')]) {
sh 'mvn -gs $MVN_SETTINGS ' +
'-Ddocker.username=${DOCKER_REPO_USER} -Ddocker.password=${DOCKER_REPO_PASSWORD} ' +
'-DskipTests ' +
'clean package spring-boot:repackage ' +
'docker:build docker:push'
}
}
}
}
post{
always{
cleanWs()
}
}
}
解决方案
解决方案是使用来自 target/checkout 的 POM 文件。请参阅标有“为发布创建 Docker 映像”的阶段。
pipeline{
agent any
tools{
maven 'M3'
}
parameters {
booleanParam(
name: 'RELEASE',
description: 'Build a release from current commit.',
defaultValue: false
)
booleanParam(
name: 'SCAN_CODE',
description: 'Scan your code to see how awesome it is.',
defaultValue: true
)
}
environment {
ARTIFACT_ID = readMavenPom().getArtifactId()
}
stages{
stage("Unit tests"){
steps{
configFileProvider([configFile(fileId: '1a4e39cc-eacf-4bd0-af47-337f536fd2bd', variable: 'MVN_SETTINGS')]) {
sh 'mvn -gs $MVN_SETTINGS test '
}
}
}
stage("SonarQube Scan"){
when {
expression { params.SCAN_CODE == true}
}
steps{
withSonarQubeEnv('codequality') {
configFileProvider([configFile(fileId: '1a4e39cc-eacf-4bd0-af47-337f536fd2bd', variable: 'MVN_SETTINGS')]) {
sh 'mvn clean install -gs $MVN_SETTINGS ' +
'org.sonarsource.scanner.maven:sonar-maven-plugin:3.3.0.603:sonar -f pom.xml ' +
'-DskipTests' +
'-Dsonar.projectKey=com.etisoftware:$ARTIFACT_ID ' +
'-Dsonar.login=$DOCKER_REPO_USER ' +
'-Dsonar.password=$DOCKER_REPO_PASSWORD ' +
'-Dsonar.language=java ' +
'-Dsonar.sources=. ' +
'-Dsonar.tests=. ' +
'-Dsonar.test.inclusions=**/*Test*/** ' +
'-Dsonar.exclusions=**/*Test*/**'
}
}
}
}
stage("Quality Gate") {
when {
expression { params.SCAN_CODE == true}
}
steps {
timeout(time: 5, unit: 'MINUTES') {
// Parameter indicates whether to set pipeline to UNSTABLE if Quality Gate fails
// true = set pipeline to UNSTABLE, false = don't
waitForQualityGate abortPipeline: true
}
}
}
stage("Build Snapshot"){
when {
expression { params.RELEASE == false}
}
steps{
configFileProvider([configFile(fileId: '1a4e39cc-eacf-4bd0-af47-337f536fd2bd', variable: 'MVN_SETTINGS')]) {
sh 'mvn -gs $MVN_SETTINGS -DskipTests clean deploy'
}
}
}
// SNAPSHOTS
stage("Create Docker Image For SNAPSHOT"){
when {
expression { params.RELEASE == false}
}
steps{
configFileProvider([configFile(fileId: '1a4e39cc-eacf-4bd0-af47-337f536fd2bd', variable: 'MVN_SETTINGS')]) {
sh 'mvn -gs $MVN_SETTINGS ' +
'-Ddocker.username=${DOCKER_REPO_USER} -Ddocker.password=${DOCKER_REPO_PASSWORD} ' +
'-DskipTests ' +
'clean package spring-boot:repackage ' +
'docker:build docker:push'
}
}
}
// RELEASES
stage("Release") {
when {
expression { params.RELEASE == true}
}
steps {
configFileProvider([configFile(fileId: '1a4e39cc-eacf-4bd0-af47-337f536fd2bd', variable: 'MVN_SETTINGS')]) {
sh 'mvn -gs $MVN_SETTINGS clean'
sh 'mvn -gs $MVN_SETTINGS -B release:prepare'
sh 'mvn -gs $MVN_SETTINGS -B release:perform'
}
}
}
stage("Create Docker Image For Release"){
when {
expression { params.RELEASE == true}
}
steps{
configFileProvider([configFile(fileId: '1a4e39cc-eacf-4bd0-af47-337f536fd2bd', variable: 'MVN_SETTINGS')]) {
sh 'mvn -gs $MVN_SETTINGS ' +
'-f target/checkout/pom.xml ' +
'-Ddocker.username=${DOCKER_REPO_USER} -Ddocker.password=${DOCKER_REPO_PASSWORD} ' +
'-DskipTests ' +
'clean package spring-boot:repackage ' +
'docker:build docker:push'
}
}
}
}
post{
always{
cleanWs()
}
}
}
推荐阅读
- javascript - 如何从外部 Javascript 文件调用路由/渲染 ejs 页面
- android - Android MediaBrowserService:onLoadChildren 为 id null 发送了 null 列表
- javascript - 无法遍历 AJAX 响应
- java - Drools:使用 Query 获取无状态会话结果
- sql - 通过计算记录并将其插入表中,我的 while 循环将永远运行
- c++14 - 使用内置 (==) 运算符比较 C++ 中的 2 个有序集合的复杂性是什么?(假设集合大小 = n))
- excel - 如何删除 Excel 工作表中单元格中的附加值
- facebook - Vue 参数在 Instagram、Facebook 等应用内浏览器中丢失
- java - 如何在java中将时间格式转换为日期格式的今天时间?
- javascript - 检查对象数组是否存在