标记来自 Jenkins 工作流脚本的回购

Tag a Repo from a Jenkins Workflow Script

我目前正在尝试从 Jenkins Workflow 脚本中标记回购。我已尝试使用 sh 步骤,但由于未设置凭据,这会遇到问题。

fatal: could not read Username for 'https://<repo>': Device not configured

是否有可用于标记存储库或绕过凭据问题的现有步骤?

我已经通过使用凭据绑定插件提供的 withCredentials 步骤成功地完成了这项工作。

它不是很好,因为它涉及在 URL 中指定它,但这些值在控制台输出中被屏蔽了。

withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: 'MyID', usernameVariable: 'GIT_USERNAME', passwordVariable: 'GIT_PASSWORD']]) {

    sh("git tag -a some_tag -m 'Jenkins'")
    sh("git push https://${env.GIT_USERNAME}:${env.GIT_PASSWORD}@<REPO> --tags")
}

这是一个不需要知道遥控器的 URL 的替代方法:

try {
  withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: 'MyID', usernameVariable: 'GIT_USERNAME', passwordVariable: 'GIT_PASSWORD']]) {
    sh("${git} config credential.username ${env.GIT_USERNAME}")
    sh("${git} config credential.helper '!echo password=$GIT_PASSWORD; echo'")
    sh("GIT_ASKPASS=true ${git} push origin --tags")
  }
} finally {
    sh("${git} config --unset credential.username")
    sh("${git} config --unset credential.helper")
}

这通过 git 从配置中读取用户名,并让凭证助手仅提供密码来实现。末尾的额外 echo 用于使 git 作为参数传递给助手的命令不会与密码在同一行结束。

所以我尝试了@user3617723 的解决方案,但由于某些原因缺少一些东西。过了一会儿,我发现了我的问题。 我有一个上层工作负责拉取 git 存储库并使用我的工作流脚本触发管道作业,该脚本具有不同的工作空间:

//use the jenkins global credential id and create the env parametrs of GIT_PASSWORD and GIT_PASSWORD
withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: 'cred-github', usernameVariable: 'GIT_USERNAME', passwordVariable: 'GIT_PASSWORD']]) {

//change directory to the work dir with the ".git" files and create tags
sh("cd ${MANAGER_WORKSPACE} ; git tag -a v-${props.'VERSION_NUMBER'} -m ${BUILD_URL}")

//get only the url after the https
giturl_push = GIT_URL.split("//")[1]

// change directory to the work dir with the ".git" files and push the tags to the repo
sh("cd ${MANAGER_WORKSPACE} ; git push https://${env.GIT_USERNAME}:${env.GIT_PASSWORD}@${giturl_push} --tags")




}

您可以创建自己的 personal API token (OAuth) 并像使用普通凭据一样使用它(在:/settings/tokens)。例如:

git tag -a some_tag -m 'Jenkins'
git push https://4UTHT0KEN@github.com/foo/bar

如果您的 git 密码包含特殊字符,例如“%”、“:”、“@”或“/”,将 ${env.GIT_PASSWORD} 作为 git 的一部分传递url 即 https://${env.GIT_USERNAME}:${env.GIT_PASSWORD}@<REPO> 不进行任何编码很可能导致 Invalid username or password 错误。

为了避免麻烦,使用内联 credential.helper 是一种更好的方法,但是 !echo password=$GIT_PASSWORD; echo' 的建议会导致构建日志 warning: invalid credential line: get 中出现警告,因为 credential.helper 传递了一个参数以指示所需的操作(获取、存储、擦除)。在这种情况下,凭证助手试图将 get 操作解释为凭证输入。有效输入是协议、主机、路径、用户名、密码,url。参见 https://git-scm.com/docs/git-credential#IOFMT

更好的内联 credential.helper 应该是 !f() { echo password=$GIT_PASSWORD; }; f 这样 credential.helper 操作 get 就会被忽略。

完整示例:

try {
  withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: 'MyID', usernameVariable: 'GIT_USERNAME', passwordVariable: 'GIT_PASSWORD']]) {
    sh("${git} config credential.username ${env.GIT_USERNAME}")
    sh("${git} config credential.helper '!f() { echo password=$GIT_PASSWORD; }; f'")
    sh("GIT_ASKPASS=true ${git} push origin --tags")    
  }
} finally {
    sh("${git} config --unset credential.username")
    sh("${git} config --unset credential.helper")
}