如何在Jenkinsfile内部为当前的git变更集打标签?

14
我希望在Jenkinsfile内标记当前git变更集并推送标签。如果该标签已经存在,则必须替换它。
我想使用此逻辑来为通过“快照”标记的构建进行标记,这将是一个移动标记。
我该如何操作?
5个回答

14

这是我实现的方式,但如果您知道更好的方法,我非常愿意听取建议。

#!groovy

stage 'build'
node {

    repositoryCommiterEmail = 'ci@example.com'
    repositoryCommiterUsername = 'examle.com'

    checkout scm

    sh "echo done"

    if (env.BRANCH_NAME == 'master') {
        stage 'tagging'

        sh("git config user.email ${repositoryCommiterEmail}")
        sh("git config user.name '${repositoryCommiterUsername}'")

        sh "git remote set-url origin git@github.com:..."

        // deletes current snapshot tag
        sh "git tag -d snapshot || true"
        // tags current changeset
        sh "git tag -a snapshot -m \"passed CI\""
        // deletes tag on remote in order not to fail pushing the new one
        sh "git push origin :refs/tags/snapshot"
        // pushes the tags
        sh "git push --tags"
    }
}

8
很有趣。你是如何对远程进行身份验证的(你是如何发送密码的)? - bsky
你应该设置SSH密钥,这样就不必输入任何密码或将其存储在任何地方。 - Ivor
不是提供另一种选择,而是改变视角:当您在Nexus上发布-SNAPSHOT时,在上传新的-SNAPSHOT之前,它不会删除旧的-SNAPSHOT,而是使用时间戳保留所有快照。使用git标签也可以轻松完成同样的事情。 - Tristan

4

对于那些无法使上述方法工作的人,我直接使用了sshagent插件,这很有效:

stage('tag build'){
checkout([
    $class: 'GitSCM', branches: [[name: '*/master']],
    userRemoteConfigs: [[credentialsId: 'git',
    url: 'ssh://<ssh URL>']],
    extensions: [[$class: 'RelativeTargetDirectory', relativeTargetDir: 'targeted-dir']]
])

sshagent(credentials: ['<credentials ID.']){
  dir('targeted-dir'){
    sh("git config user.email '<email>")
    sh("git config user.name '<user>.com'")

    // deletes current snapshot tag
    sh ("git tag -d ${PARAM_VERSION_NUMBER} || true")
    // tags current changeset
    sh ("git tag -a ${PARAM_VERSION_NUMBER} -m \"versioning ${PARAM_VERSION_NUMBER}\"")
    // deletes tag on remote in order not to fail pushing the new one
    sh ("git push origin :refs/tags/snapshot")
    // pushes the tags
    sh ("git push --tags")
    }
}

}


3
我想分享我的Jenkins流水线设置以及通过SSH发布更改/标签到git仓库的解决方案(在Git Publish Support正在开发中的情况下)。请查看详情,欢迎任何改进意见。
简而言之,您只需将git_push_ssh.groovy文件添加到您的项目中,并像这样从Jenkinsfile中调用pushSSH()方法:
env.BRANCH_NAME = "mycoolbranch"// BRANCH_NAME is predefined in multibranch pipeline job
env.J_GIT_CONFIG = "true"
env.J_USERNAME = "Jenkins CI"
env.J_EMAIL = "jenkins-ci@example.com"
env.J_CREDS_IDS = '02aa92ec-593e-4a90-ac85-3f43a06cfae3' // Use credentials id from Jenkins
def gitLib = load "git_push_ssh.groovy"
...
gitLib.pushSSH(commitMsg: "Jenkins build #${env.BUILD_NUMBER}", tagName: "build-${env.BUILD_NUMBER}", files: "changelog.txt someotherfile.txt");

我添加了上面的示例阶段,以清楚地展示如何添加标签,因为我花了一点时间查看上面的示例和链接的代码才使其正常工作。它还需要安装Jenkins的“ssh agent”插件。 - sgbel2

1

基于SSH-Agent的方法在我们的Windows构建服务器上无法使用,但是我们仍然希望使用存储在Jenkins凭据管理器中的凭据。由于我们的Git凭据是一个SSH密钥,我们意识到可以让Jenkins直接提供给我们密钥文件:

stage("Tag") {
    steps {
        script {
            def tagName = "..."
            withCredentials([sshUserPrivateKey(credentialsId: "idOfYourCredentials", keyFileVariable: "KEY")]) {
                def key = KEY.replaceAll("\\\\", "/") // Only needed on Windows
                env.GIT_SSH_COMMAND = "ssh -i ${key}"
                bat "git tag \"${tagName}\""
                bat "git push --tags"
            }
        }
    }
}

1

要使蓝色海洋(使用https连接)正常工作,请使用以下内容:

sshagent(credentials: ["406ef572-9598-45ee-8d39-9c9a227a9227"]) {
                def repository = "git@" + env.GIT_URL.replaceFirst(".+://", "").replaceFirst("/", ":")
                sh("git remote set-url origin $repository")
                sh("git tag --force build-${env.BRANCH_NAME}")
                sh("git push --force origin build-${env.BRANCH_NAME}")
            }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接