常见问题

Jenkinsfile 语法相关问题

Q:不建议继续使用 ci-init

Q:为什么 2019年10月10号 之后使用带有 ci-init 的 Jenkinsfile, 创建一个新的 Job 会提示无法拉取代码?

A:2019年10月10日 之前创建的构建计划( Job )中的 ci-init 命令会为用户创建一对公私钥,并使其能够拉取项目中的代码仓库。之后创建的构建计划在调用 ci-init 时,将不会创建拉取代码的公私钥对了。

新创建的构建计划, 我们都会为用户内置一个可以用于拉取对应代码仓库的凭据 ID,直接使用 env.CREDENTIALS_ID 作为 userRemoteConfigs 的 credentialsId 即可。

旧的语法:

pipeline {
    agent any
        stages {
        stage('检出') {
            steps {
                // 旧版本的语法含有 ci-init 
                sh 'ci-init'

                checkout([
                    $class: 'GitSCM', 
                    branches: [[name: env.GIT_BUILD_REF]],
                    userRemoteConfigs: [[url: env.GIT_REPO_URL]]
                ])
            }
        }
    }
}

新的语法:

pipeline {
    agent any
        stages {
        stage('检出') {
            steps {
                checkout([
                    $class: 'GitSCM', 
                    branches: [[name: env.GIT_BUILD_REF]],
                    // 请注意新版的检出语法比旧版新增了 credentialsId: env.CREDENTIALS_ID
                    userRemoteConfigs: [[url: env.GIT_REPO_URL, credentialsId: env.CREDENTIALS_ID]]
                ])
            }
        }
    }
}

CODING 目前已经支持了凭据管理,我们强烈建议用户使用更安全的凭据 ID 来代替之前的 ci-init 操作。

关于凭据如果您想了解更多可以参考《凭据管理》

Q:之前创建的构建计划会受到影响么?

A:不会,我们保障了之前创建的构建计划依然能够正常生效,会注入有效的公私钥,但建议用户尽快替换成新的 checkout 语法。

Q:单引号和双引号用法有什么差异?

您在使用 CODING 持续集成时,经常需要在 Jenkinsfile 内拼接字符串或使用环境变量作为参数, Jenkinsfile 中的单引号和双引号在使用时,会有些不同的差异, 这里演示一下常用的 echo 与 sh 两个命令的差异。

pipeline {
    agent any
    environment {
        MY_ENV = 'this is my env'
    }
    stages {
        stage('Test') {
            steps {
                script    {
                    def MY_ENV = 'define in script'

                    echo "${env.MY_ENV}"
                    // 输出内容为 this is my env

                    echo "\${env.MY_ENV}"
                    // 输出内容为 ${env.MY_ENV}

                    echo "${MY_ENV}"
                    // 输出内容为 define in script

                    echo '${MY_ENV}'
                    // 输出内容为 ${MY_ENV}

                    sh 'echo ${MY_ENV}'
                    // 输出内容为 this is my env

                    sh "echo ${MY_ENV}"
                    // 输出内容为 define in script

                    sh "echo ${env.MY_ENV}"
                    // 输出内容为 this is my env
                }
            }
        }
    }
}

从上图输出的结果可以看出:

echo 在使用单引号时,并不会解析里面的 $ 符号,而是直接输出原文;在使用双引号时,会打印出环境变量里的 MY_ENV。

sh 在使用单引号时,将原文当作我们平时在终端里 sh 的命令一样执行,所以可以打印出环境变量里的 MY_ENV。

Q:如何在 CODING 持续集成内推送代码

在某些场景下,您可能需要在持续集成阶段推送代码。CODING 的持续集成内置了 Git、SVN 等命令工具,您可以参考如下示例。

Jenkinsfile 配置语法如下:

pipeline {
  agent any
  stages {
    stage('检出') {
      steps {
        checkout([
            $class: 'GitSCM', 
            branches: [[name: env.GIT_BUILD_REF]], 
            userRemoteConfigs: [[url: env.GIT_REPO_URL, credentialsId: env.CREDENTIALS_ID]]])
      }
    }
    stage('修改') {
        steps {
            sh "echo '# Hello CODING' > README.md"
            sh "git add ."
            sh "git commit -m 'add README.md' "

        }
    }
    stage('推送') {
        steps {
            // 使用了 CODING 持续集成系统预置的项目令牌环境变量 PROJECT_TOKEN_GK 和 PROJECT_TOKEN 来推送
            // 若希望推送到非本项目或第三方平台的代码仓库,需要自行换成有效的凭据信息
            sh "git push https://${PROJECT_TOKEN_GK}:${PROJECT_TOKEN}@e.coding.net/myteam/myrepo.git HEAD:master"
        }
    }
  }
}

Jenkinsfile 两种配置来源的区别

在创建构建计划时,你可以设置 Jenkinsfile 的配置来源,使用代码仓库中的 Jenkinsfile使用静态配置的 Jenkinsfile 有什么区别?

使用代码仓库中的 Jenkinsfile 有以下特点:

  1. Jenkinsfile 文件存储在所选择的代码仓库中,修改 Jenkinsfile 的同时也更新代码仓库。

  2. 任务 Job 的构建可由更新代码触发规则定义,若修改 Jenkinsfile 将会自动触发构建。

  3. 在任务 Job 点击立即构建,选择构建目标进行构建时,构建任务的配置将会从所构建目标拉取代码的 Jenkinsfile 进行构建,而不是该任务 Job 里当时配置的 Jenkinsfile。

使用静态配置的 Jenkinsfile 有以下特点:

  1. 静态配置的 Jenkinsfile 将不会保存在代码仓库中,修改 Jenkinsfile 的同时不会更新代码仓库。

  2. 任务 Job 的构建可由更新代码触发规则定义,修改静态配置文件 Jenkinsfile 不会自动触发构建。

  3. 在任务 Job 点击立即构建,选择构建目标进行构建时,构建任务将统一使用该静态配置,不再使用代码仓库中的 Jenkinsfile。

两者区别

  1. 使用代码仓库中的 Jenkinsfile 进行配置,可将 Jenkinsfile 保存到仓库中进行版本记录。而选择使用静态配置的 Jenkinsfile 将不存储在代码版本中,无法进行版本记录。

  2. 使用静态配置的 Jenkinsfile 进行配置,构建时所有的构建任务将统一使用该静态配置,每次代码版本更新时将会执行相同的 Jenkinsfile 进行构建。保障构建流程相同。

构建执行相关问题

Q:构建任务运行失败了怎么办?

在遇到构建任务运行失败后,您可以按照下文思路进行排查。

1. 为什么持续集成任务会构建失败

持续集成过程中执行进程的 exit code(退出码)不为 0 就会认为是“构建失败”。

目前主流的计算机操作系统内任何进程的退出,都会留下 exit code, 操作系统可以根据退出码来判断进程是否按照预期运行。通常退出码是 0-255 之间的整数,0 表示正常退出。

CODING 持续集成也根据这一状态码来判断一次构建是否“失败”。用户经常遇到的 exit code 不为 0 有以下几种情况:

  • 持续集成的配置文件语法有错误

与大多数的编程语言一样,Jenkinsfile 也是由特定领域的语言 (DSL) 组成,语法错误,就会导致编译或者运行失败。

  • 测试不通过

大多数主流的测试工具或测试框架,在测试逻辑不通过时,默认都会将退出码设置为非 0。

  • 构建超时或构建配额不足

每一个团队在使用 CODING 持续集成的时候,都会有一定的配额。为防止恶意使用持续集成,每一个构建任务都会有超时的限制,超时或者构建次数超过配额系统将会主动中止构建任务。用户遇到配额不足时,可以在团队管理内进行配额调整,购买满足自己实际需求的配额。

2. 失败了如何排查解决

持续集成过程的本质就是自动地执行一系列任务,这与过去开发者使用脚本编写的自动化任务没有本质上的差异。

  • 查看构建日志与构建快照

CODING 持续集成为用户提供了构建日志,用户可以根据日志内容,判断构建失败的原因。除此之外,CODING 持续集成还提供了每一次构建的配置快照, 用户可以根据快照获取构建使用的配置文件内容和参数,得知是否是配置差异导致的构建失败。

构建日志:

构建快照:

  • 在本地运行自动化任务

用户可以再将自动化的逻辑重新执行一遍(如:在本地重新运行测试代码),本地可以利用 Debug ,或者实时修改代码获得更多的信息反馈,以此来排查问题。

3. 常见其他构建失败原因

  • 使用了交互式命令行程序会导致构建失败

由于持续集成的整个过程中,用户是无法直接使用交互式命令的,若使用了会呼出交互式命令行窗口的程序,会导致构建失败。

常见的有 npm login docker login -u xxx ( CI 内登陆 docker 需要使用 docker -u xx -p xx 的命令)等。

上一篇在持续集成中使用 SSH
文档是否对您有用?
感谢反馈有用
感谢反馈没用