首页 > 解决方案 > 用于创建 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()
        }

    }
}

标签: mavenjenkins-pipeline

解决方案


解决方案是使用来自 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()
    }
}

}


推荐阅读