如何通过 Jenkinsfile 管道使用 Git 提交哈希自动标记 Docker 图像

How To Auto-Tag A Docker Image with Git Commit Hash through a Jenkinsfile Pipeline

所以我有一个 Jenkins 实例,我需要使用 Jenkinsfile 管道自动标记 Docker 图像,该管道自动使用提交哈希标记图像,然后将其推送到 Docker 存储库. Jenkins 配置正确,但我的管道仍然失败。起初,我尝试使用以下命令,returns 我存储库的当前提交哈希。

git rev-parse -short=10 HEAD

然后我注意到它返回了不止一行,所以我开始使用这个:

git rev-parse -short=10 HEAD | tail -n +2

哪个 returns 提交哈希类似于:

338fcaa318b17c40dacf81dcf7a5826e3e3f0160

我的目标是使用 Jenkinsfile 使用此哈希标记我的 docker 图像:

pipeline {
    agent any
    environment {
        tag = sh(returnStdout: true, script: "git rev-parse -short=10 HEAD | tail -n +2")
    }

    stages {
        stage('Build core lodestone image') {
            steps {
                // TODO: proper tagging
                sh "docker build -f Dockerfile.lodestone -t mirantiseng/lodestone:${var.tag} ."
                withCredentials([usernamePassword(credentialsId: 'common-dockerhub-up', usernameVariable: 'HUB_USER', passwordVariable: 'HUB_PASS')]) {
                    sh "docker login -u ${HUB_USER} -p ${HUB_PASS} && docker push mirantiseng/lodestone:${var.tag}"
                }
            }
        }
        stage('Build core lodestone-comment image') {
            steps {
                // TODO: proper tagging
                sh "docker build -f Dockerfile -t mirantiseng/lodestone-comment:${var.tag} ."
                withCredentials([usernamePassword(credentialsId: 'common-dockerhub-up', usernameVariable: 'HUB_USER', passwordVariable: 'HUB_PASS')]) {
                    sh "docker login -u ${HUB_USER} -p ${HUB_PASS} && docker push mirantiseng/lodestone-comment:${var.tag}"
                }
            }
        }
        stage('Build core lodestone-mover image') {
            steps {
                // TODO: proper tagging
                sh "docker build -f Dockerfile.mover -t mirantiseng/lodestone-mover:${var.tag} ."
                withCredentials([usernamePassword(credentialsId: 'common-dockerhub-up', usernameVariable: 'HUB_USER', passwordVariable: 'HUB_PASS')]) {
                    sh "docker login -u ${HUB_USER} -p ${HUB_PASS} && docker push mirantiseng/lodestone-mover:${var.tag}"
                }
            }
        }
    }
}

如果我取出 :${var.tag} 和后面的块,构建工作正常,但它只是推送最新的。这使得工作文件看起来像这样:

pipeline {
    agent any

    stages {
        stage('Build core lodestone image') {
            steps {
                // TODO: proper tagging
                sh "docker build -f Dockerfile.lodestone -t mirantiseng/lodestone ."
                withCredentials([usernamePassword(credentialsId: 'common-dockerhub-up', usernameVariable: 'HUB_USER', passwordVariable: 'HUB_PASS')]) {
                    sh "docker login -u ${HUB_USER} -p ${HUB_PASS} && docker push mirantiseng/lodestone"
                }
            }
        }
        stage('Build core lodestone-comment image') {
            steps {
                // TODO: proper tagging
                sh "docker build -f Dockerfile -t mirantiseng/lodestone-comment ."
                withCredentials([usernamePassword(credentialsId: 'common-dockerhub-up', usernameVariable: 'HUB_USER', passwordVariable: 'HUB_PASS')]) {
                    sh "docker login -u ${HUB_USER} -p ${HUB_PASS} && docker push mirantiseng/lodestone-comment"
                }
            }
        }
        stage('Build core lodestone-mover image') {
            steps {
                // TODO: proper tagging
                sh "docker build -f Dockerfile.mover -t mirantiseng/lodestone-mover ."
                withCredentials([usernamePassword(credentialsId: 'common-dockerhub-up', usernameVariable: 'HUB_USER', passwordVariable: 'HUB_PASS')]) {
                    sh "docker login -u ${HUB_USER} -p ${HUB_PASS} && docker push mirantiseng/lodestone-mover"
                }
            }
        }
    }
}

但我需要 docker 图像进行标记。我阅读了 Jenkinsfile,它说我可以使用 environment {<something>} 创建一个环境变量来设置全局变量。我有一个名为 tag 的变量,我想实现它用提交哈希标记 docker 图像。我怎样才能做到这一点?

所以我所要做的就是改变 tag 的定义方式:

pipeline {
    agent any
    environment {
        tag = sh(returnStdout: true, script: "git rev-parse --short=10 HEAD").trim()
    }

    stages {
        stage('Build core lodestone image') {
            steps {
                // TODO: proper tagging
                sh "docker build -f Dockerfile.lodestone -t mirantiseng/lodestone:${tag} ."
                withCredentials([usernamePassword(credentialsId: 'common-dockerhub-up', usernameVariable: 'HUB_USER', passwordVariable: 'HUB_PASS')]) {
                    sh "docker login -u ${HUB_USER} -p ${HUB_PASS} && docker push mirantiseng/lodestone:${tag}"
                }
            }
        }
        stage('Build core lodestone-comment image') {
            steps {
                // TODO: proper tagging
                sh "docker build -f Dockerfile -t mirantiseng/lodestone-comment:${tag} ."
                withCredentials([usernamePassword(credentialsId: 'common-dockerhub-up', usernameVariable: 'HUB_USER', passwordVariable: 'HUB_PASS')]) {
                    sh "docker login -u ${HUB_USER} -p ${HUB_PASS} && docker push mirantiseng/lodestone-comment:${tag}"
                }
            }
        }
        stage('Build core lodestone-mover image') {
            steps {
                // TODO: proper tagging
                sh "docker build -f Dockerfile.mover -t mirantiseng/lodestone-mover:${tag} ."
                withCredentials([usernamePassword(credentialsId: 'common-dockerhub-up', usernameVariable: 'HUB_USER', passwordVariable: 'HUB_PASS')]) {
                    sh "docker login -u ${HUB_USER} -p ${HUB_PASS} && docker push mirantiseng/lodestone-mover:${tag}"
                }
            }
        }
    }
}

主要变化是这个

tag = sh(returnStdout: true, script: "git rev-parse --short=10 HEAD").trim()`

你可以像这样$GIT_COMMIT使用

sh "docker build -f Dockerfile.mover -t mirantiseng/lodestone-mover:${GIT_COMMIT} ."