【问题标题】:Windows Jenkins pipeline git command submodule update passing in credentialsWindows Jenkins 管道 git 命令子模块更新传递凭据
【发布时间】:2020-08-16 00:20:32
【问题描述】:

我正在尝试做与here 中所做的类似的事情,但我在 Windows 服务器上运行 Jenkins 并尝试从 Jenkins 的凭据存储中传递凭据,这需要另一个帖子。

在上面帖子的 cmets 中,我查看了 this 帖子,现在我的管道中有这个:

withCredentials([sshUserPrivateKey(credentialsId:'ci', keyFileVariable:'GITHUB_KEY')]){
  withEnv(["GIT_SSH_COMMAND=ssh -i $GIHUB_KEY -o StrictHostKeyChecking=no]){
    bat script: 'git submodule update --init --recursive'
  }
}

但是,当构建运行时,由于登录失败而出错:

using GIT_SSH to set credentials <credentials_description>
> C:\<git_install_path>\git.exe submodule update --init --recursive <submodule_name> # timeout=10
...
...
hudson.plugins.git.GitException: Command "C:\<git_install_path>\git.exe submodule update --init --recursive <submodule_name>" returned status code 1:
stdout:
stderr: Cloning into '<Jenkins job folder>'
Logon failed, use ctrl+c to cancel basic credential prompt
bash: /dev/tty: No such device or address
error: failed to execute prompt script (exit code 1)
fatal: could not read Username for '<git url>': No such file or directory
fatal: clone of '<submodule url>' into submodule path '<local submodule path>' failed
Failed to clone '<submodule>'. Retry scheduled
...

在调用git submodule 命令时,有没有办法从 Jenkins 传递这些凭据?或者我是否需要像在第一个链接的帖子中那样在环境块中设置GIT_SSH_COMMAND,并将私钥存储在构建框中的某个地方?

编辑: 我也尝试过使用结帐语法,但我得到相同的登录失败错误

checkout([
  $class: 'GitSCM',
  branches: [[name '*/<branch_name'>]],
  doGenerateSubmoduleConfigurations: false,
  extensions: [[
    $class: 'SubmoduleOption', 
    disableSubmodules: false, 
    parentCredentials: true, 
    recursiveSubmodules: true,
    reference: '',
    trackingSubmodules: false
  ]],
  submoduleCfg: [],
  userRemoteConfigs: [[credentialsId:'ci', url:'<git_url>']]
])

【问题讨论】:

  • 奇怪的是,如果我使用 checkout 命令,代码的初始提取工作正常,但它在发生登录失败的子模块(凭据有效)上。

标签: git jenkins jenkins-pipeline


【解决方案1】:

鉴于您的结帐也失败了,我怀疑您的子模块可能是https。如果是这样,您的 GIT_SSH_COMMAND 甚至不会为您的子模块调用,因为它们没有使用 SSH

您可以通过查看您的存储库中的 .gitmodules 文件来确认这一点。如果您看到 url = https:// 它是一个 http 子模块。如果您的子模块在同一台服务器上,您最好的选择可能是relative path。这将让用户自动在您的子模块和您的父 repo 上使用相同的协议。我认为大多数人会错误地认为这是子模块的默认行为。

一旦你解决了这个问题,你上面的代码看起来也会遇到这个问题:

在 Windows 上,keyFileVariable 似乎返回带有反斜杠分隔符的 Windows 样式路径。您可以通过使用 dummy credentials 并将变量的值转储到文件中进行验证,然后将其存档为构建的一部分。我不太确定会发生什么,但它似乎是一个包含驱动器号的绝对路径。

我发现更令人惊讶的是ssh -i 需要一个带有正斜杠的路径。我猜它是 Windows 上的一个 unix 实用程序,所以我们有点要求这种混淆(幸运的是,驱动器号似乎没问题)。

我必须添加一个替换路径分隔符的部分: env.GITHUB_KEY.replaceAll("\\\\","/")

所以最后是这样的:

withCredentials([sshUserPrivateKey(credentialsId:'ci', keyFileVariable:'GITHUB_KEY')]){
  script {
    def KEY_UNIX_STYLE_PATH = env.GITHUB_KEY.replaceAll("\\\\","/")
    withEnv(["GIT_SSH_COMMAND=ssh -i $KEY_UNIX_STYLE_PATH -o StrictHostKeyChecking=no]){
      bat script: 'git submodule update --init --recursive'
    }
  }
}

警告:现在可以轻松地在日志中意外暴露此路径。我实际上并不认为这很重要,因为文件的内容(私钥)才是真正的秘密。更多详细信息,请参阅Handling Credentials 上的官方文档。

【讨论】:

    猜你喜欢
    • 2017-07-06
    • 2017-05-03
    • 2012-04-27
    • 2023-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-01
    相关资源
    最近更新 更多