背景
之前收到了一个需求, 要求用实现jenkins支持自定义命令检出git代码仓库, 并且要自动添加用户密码, 还要求用户密码不可见. 嗯… 有点意思, 这种情况下jenkins流水线语法生成器
生成的checkout()
方法就不太适用了
方法一. gitUsernamePassword凭据变量方式
通过gitUsernamePassword
方式1在执行git命令时可以自动进行身份, 但是该方式要求jenkins的git插件版本要是4.8.1
以上,而且最新版的jenkins git:4.12.2
插件要求jenkins版本是2.332.4
如果直接在jenkins 上升级git插件可能还会不兼容,而且会导致流水线不可用, 非要尝试升级jenkins插件的话也不是不可以, 最好先备份下$JENKINS_HOME
下面的plugins
目录,避免jenkins出现问题无法恢复
示例如下:
withCredentials([gitUsernamePassword(credentialsId: 'my-credentials-id', gitToolName: 'git-tool')]) {
sh 'git fetch --all'
}
方法二, withCredentials通过环境变量方式手动添加账密
经过不断尝试, 终于实现了自动在git检出命令里面添加账密并隐藏的方式, 其中${CERT_ID}
是自定义凭据, checkoutCmd
是自定义检出命令参数
withCredentials([usernamePassword(credentialsId: "${CERT_ID}", usernameVariable: 'username', passwordVariable: 'password')]) {
//获取http或https开头的域名, 例如http://gitlab.com/project.git 截取为gitlab.com
def domain=sh(script: ''' echo '${checkoutCmd}' | grep -Eo '(https?://)[^/]+' |head -n 1 | awk -F '://' '{print \$2}' ''', returnStdout: true).trim()
//在域名中加上用户密码,组成user:passwod@gitlab.com"这种格式
passWithDomain="${username}:${password}@${domain}"
//替换后检出命令
checkoutCmd=checkoutCmd.replaceAll(domain,passWithDomain)
//set +x关闭日志输出避免输出用户密码, 参考 https://www.jenkins.io/doc/pipeline/steps/credentials-binding
sh '''
set +x
${checkoutCmd}
'''
}
本来想分析jenkins git插件的代码逻辑看看有没有更好的实现方式的, jenkins git:4.12.2
插件2绑定账密的代码逻辑如下, 看样子会在workspace下面生成一个auth.sh
的临时文件, 但是我还不清楚这个文件是怎么用的
@Override
protected FilePath write(StandardUsernamePasswordCredentials credentials, FilePath workspace)
throws IOException, InterruptedException {
FilePath gitEcho;
//Hard Coded platform dependent newLine
if (this.unixNodeType) {
gitEcho = workspace.createTempFile("auth", ".sh");
// [#!/usr/bin/env sh] to be used if required, could have some corner cases
gitEcho.write("case $1 in\n"
+ " Username*) echo " + this.userVariable
+ " ;;\n"
+ " Password*) echo " + this.passVariable
+ " ;;\n"
+ " esac\n", null);
gitEcho.chmod(0500);
} else {
gitEcho = workspace.createTempFile("auth", ".bat");
gitEcho.write("@ECHO OFF\r\n"
+ "SET ARG=%~1\r\n"
+ "IF %ARG:~0,8%==Username (ECHO " + this.userVariable + ")\r\n"
+ "IF %ARG:~0,8%==Password (ECHO " + this.passVariable + ")", null);
}
return gitEcho;
}