18

我目前正在尝试从 Jenkins Workflow 脚本中标记一个 repo。我尝试使用一个sh步骤,但由于未设置凭据而遇到问题。

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

是否有一个现有的步骤可用于标记回购或解决凭据问题?

4

5 回答 5

24

我已经设法通过使用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")
}
于 2015-11-10T12:54:24.747 回答
14

这是一个不需要知道远程 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 作为参数传递给帮助程序的命令不会与密码在同一行结束。

于 2016-10-14T08:47:28.673 回答
11

如果您的 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")
}
于 2018-01-03T02:31:01.643 回答
2

您可以创建自己的个人 API 令牌( OAuth ) 并像使用普通凭据一样使用它 (at: /settings/tokens)。例如:

git tag -a some_tag -m 'Jenkins'
git push https://4UTHT0KEN@github.com/foo/bar
于 2017-09-15T14:34:16.973 回答
0

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

//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")




}
于 2017-04-07T10:44:26.347 回答