• Jenkins pipeline checkout()方法替代方案,实现自定义代码检出命令


    背景

    之前收到了一个需求, 要求用实现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'
    }
    
    • 1
    • 2
    • 3

    方法二, 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}
          '''
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    本来想分析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;
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    参考


    1. https://www.jenkins.io/blog/2021/07/27/git-credentials-binding-phase-1 ↩︎

    2. https://github.com/jenkinsci/git-plugin/tree/master/src/main/java ↩︎

  • 相关阅读:
    在PyCharm中畅游机器学习深海,以支持向量机探索图像识别新航程
    易观分析互联网+慢病管理生态洞察,助力行业升级
    rust学习-string
    远程VPN登录,IPsec,VPN,win10
    Servlet生命周期
    Hadoop:YARN、MapReduce、Hive操作
    【Python | 入门】 五分钟速通语法
    .NET周刊【2月第2期 2024-02-11】
    Docker安装xxl-job并整合到SpringBoot项目
    【640. 求解方程】
  • 原文地址:https://blog.csdn.net/qq_26545503/article/details/127568685