1. 授权认证
  2. 获取用户个人信息
  3. 项目协同
  4. 代码托管
  5. 持续集成
  6. 制品仓库
  7. 测试管理
  1. 项目协同
  2. 代码仓库
  3. DevOps 实践之旅
  4. 一分钟开始持续集成之旅
  5. 持续部署
  6. 制品库

持续集成的构建环境

功能介绍

构建环境是指用来运行构建任务的环境,它通常是一个预装了开发语言 SDK、命令行工具的操作系统环境或者 Docker 环境。

CODING 持续集成会为每个构建任务分配一台 CVM 作为构建资源,您可以通过内置的 agent label 来使用不同的环境进行构建。目前支持的构建环境有三种:

  • 默认环境:在 CODING 提供的云主机上执行 Pipeline 或 stage
  • 使用 Docker 自定义构建环境:在指定已构建好的 Docker 镜像环境中,或使用代码仓库中指定的 Dockerfile 脚本构建环境,执行 Pipeline 或 stage

默认环境

在【持续集成计划设置】->【流程配置】->【基础配置】->【图形化编辑器】中,默认选中 “使用默认构建环境”,您的持续集成任务将会在云主机 / 自定义节点的操作系统下进行构建。

如果您使用 Jenkinsfile 进行流程配置,设置 agent 为 agent any,持续集成将在默认环境运行构建程序。

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]]
                ])
            }
        }
        ...
    }
}

如果您选择 CODING 提供的云主机作为构建节点,并选择默认环境进行构建,我们已经为您安装了以下软件 SDK 和命令行工具:

预装的软件 SDK

默认环境中提供的 SDK 以及对应的版本如下(更新日期:2019 年 11 月 30 日):

  • android-sdk: 26.1.1
  • build-essential
  • java: 1.8.0_191
  • python: 2.7.12
  • python3: 3.5.2
  • python3.7: 3.7.3
  • nodejs: 10.15.3
  • php: 7.3.5
  • ruby: 2.6.0
  • go: 1.12.4
  • dotnet-core: 2.2
  • erlang: Erlang/OTP 21
  • elixir: 1.8.1

预装的命令行工具

默认环境中提供的命令行工具以及对应的版本如下(更新日期:2020 年 5 月 7 日):

  • bundler: 1.17.2
  • cmake: 3.5.1
  • composer: 1.8.5
  • coscmd: 1.8.5.36
  • docker-compose: 1.23.1
  • docker: 18.09.1
  • git-lfs: 2.7.2
  • git: 2.7.4
  • gradle: 4.10.3
  • helm: 2.13.1
  • jq: 1.5-1-a5b5cbe
  • kubectl: 1.14
  • maven: 3.6.1
  • mercurial: 3.7.3
  • nvm: 0.34.0
  • pigz: 2.3.1
  • pip3: 19.0.3
  • rancher: 2.2.0
  • rvm: 1.29.7
  • sshpass: 1.05
  • svn: 1.9.3
  • tccli: 3.0.67.1
  • vsftpd: 3.0.3
  • yarn: 1.15.2

选择不同版本的预装 SDK

若默认环境中预装的 SDK 版本不满足您的要求,您可以使用 CODING 官方提供的其他版本镜像作为构建环境。

在【持续集成计划设置】->【流程配置】->【基础配置】->【图形化编辑器】中,选择 “使用 CODING 官方提供的 Docker 镜像”,然后从列表中选择符合您构建需求的 SDK 和版本,作为 pipeline / stage 的 agent。

例如,默认预装的 node.js 版本为 10.15.3,而当前构建需要 node.js 12 以上的版本,可以在下面列表中进行选择:

对应的 Jenkinsfile 为:

pipeline {
    agent {
        docker {
            registryUrl 'https://coding-public-docker.pkg.coding.net'
            image 'public/docker/nodejs:12'
        }
    }
    stages {
        stage('Test') {
            steps {
                sh 'node --version'
            }
        }
    }
}

使用 Docker 自定义构建环境

CODING 持续集成为您提供三种方式自定义 Docker 构建环境,可以满足您不同的构建需求:

  • 使用存放在项目内制品库的 Docker 镜像:适用于项目层级的标准构建环境,保障项目内镜像安全,方便管理,通过项目令牌您也可以拉取其他项目的镜像;
  • 使用指定 Registry 地址(默认为 Docker Hub)的 Docker 镜像:适用于拉取储存在其他平台的镜像;
  • 使用 Dockerfile 脚本构建环境:适用于灵活搭建构建环境的需求;

使用存放在项目内制品库的 Docker 镜像

在【持续集成计划设置】->【流程配置】->【基础配置】->【图形化编辑器】中,选择 “使用项目内的 Docker 镜像”,即可将制品库中的镜像作为 pipeline / stage 的 agent。

对应的 Jenkinsfile 为:

pipeline {
    agent {
        docker { 
            image 'laravel-demo/laravel-docker/laravel-demo:1.0.0'
            registryUrl 'https://codes-farm-docker.pkg.coding.net/'
            registryCredentialsId env.CODING_ARTIFACTS_CREDENTIALS_ID
        }
    }
    stages {
        stage('Test') {
            steps {
                sh 'php -v'
            }
        }
    }
}

如何推送自定义构建环境镜像到制品库并作持续集成构建环境,请参见在持续集成中使用自定义 Docker 构建环境

注意:env.CODING_ARTIFACTS_CREDENTIALS_ID 只可用于本项目的制品库,而跨项目使用制品库需按照下列步骤进行操作:

  1. 在制品库所在的项目中创建「项目令牌」,获得用户名和密码;
  2. 在持续集成所在的项目中录入「项目凭据」,选择「用户名+密码」类型,并授权给持续集成;
  3. 在持续集成中添加环境变量 DOCKER_CREDENTIALS_ID,取值选用「项目凭据」,上方的代码也对应改成 registryCredentialsId env.DOCKER_CREDENTIALS_ID

如何将「项目令牌」录入凭据请参见在持续集成中使用凭据

使用指定 Registry 地址的 Docker 镜像

在【持续集成计划设置】->【流程配置】->【基础配置】->【图形化编辑器】中,选择 “使用指定的 Docker 镜像”,即可将指定地址的镜像作为 pipeline / stage 的 agent。

其中,“Docker 镜像” 为必填项,需要填入您的镜像名称;“Registry 地址” 默认为 Docker Hub (hub.docker.com);如果需要拉取私有镜像,需要填写 “Registry 认证凭据 ID”,如何录入凭据请参见在持续集成中使用凭据

下面是在公有镜像仓库中拉取指定版本 SDK 的镜像,作为持续集成的构建环境的对应 Jenkinsfile:

pipeline {
    agent {
        docker { 
            image 'node:7-alpine'
            args '-v /etc/hosts:/etc/hosts' //  args 为非必填参数,可以为 docker 执行运行时的参数
        }
    }
    stages {
        stage('Test') {
            steps {
                sh 'node --version'
            }
        }
    }
}

下面是在私有镜像仓库中拉取指定版本 SDK 的镜像,作为持续集成的构建环境的对应 Jenkinsfile:

pipeline {
    agent {
        docker { 
            image 'laravel-demo/laravel-docker/laravel-demo:1.0.0' // 修改为你的镜像名称
            registryUrl 'https://codes-farm-docker.pkg.coding.net/' // 修改为你的仓库地址
             // CODING 制品库无需修改此行,其他仓库需录入凭据管理
            registryCredentialsId env.CODING_ARTIFACTS_CREDENTIALS_ID
        }
    }
    stages {
        stage('Test') {
            steps {
                sh 'php -v'
            }
        }
    }
}

使用 Dockerfile 脚本构建环境

如果上述提供的自定义构建环境方式并不能满足您的需求,您还可以使用 Dockerfile 脚本构建环境。
如果项目已经使用 Docker,那么用同一份 Dockerfile 作为持续集成构建环境很方便,符合「DRY」原则。比如代码仓库中 Dockerfile 如下:

FROM php:7.4-apache

RUN apt-get update \
    && apt-get install -y unzip

Jenkinsfile

pipeline {
    agent any
    stages {
        stage('Checkout') {
            steps {
                checkout([
                    $class: 'GitSCM', 
                    branches: [[name: env.GIT_BUILD_REF]], 
                    userRemoteConfigs: [[url: env.GIT_REPO_URL, credentialsId: env.CREDENTIALS_ID]]
                ])
            }
        }
        stage('Use Docker') {
            agent { 
                dockerfile {
                    filename 'Dockerfile' // 可选,自定义 Dockerfile 文件名
                    dir 'build' // 可选,Dockerfile 所在目录
                    additionalBuildArgs  '--build-arg version=1.0.2' // 可选,docker build 自定义参数
                }
            }
            stages {
                stage('Test') {
                    steps {
                        sh 'php -v'
                        sh 'unzip -v'
                    }
                }
            }
        }
    }
}

每次构建都根据 Dockerfile 进行 docker build 会浪费时间,推荐进阶阅读:《最佳实践 - Jenkins Dockerfile 保存镜像用于下次构建》

使用多个 Docker 镜像或多个 Docker 后台

使用多个 Docker 镜像

pipeline {
    agent none
    stages {
        stage('Back-end') {
            agent {
                docker { image 'maven:3-alpine' }
            }
            steps {
                sh 'mvn --version'
            }
        }
        stage('Front-end') {
            agent {
                docker { image 'node:7-alpine' }
            }
            steps {
                sh 'node --version'
            }
        }
    }
}

使用多个 Docker 后台

自动化测试往往需要临时的基础设施(比如 MySQL、Redis、Elasticsearch),无需购买搭建,而是创建一个桥接网络,在其中启动多个 Docker 后台即可,测试完毕自动删除。

pipeline {
  agent any
  stages {
    stage('检出') {...}
    stage('准备依赖') {
      steps {
        script {
          sh 'docker network create bridge1';
          sh(script:'docker run --net bridge1 --name mysql -d' +
        ' -e "MYSQL_ROOT_PASSWORD=my-secret-pw" -e "MYSQL_DATABASE=test_db" mysql:5.7', returnStdout: true)
          sh(script:'docker run --net bridge1 --name redis -d redis:5', returnStdout: true)
        }
      }
    }
    stage('单元测试') {
      agent {
        docker {
          image 'openjdk:14-jdk-alpine'
          args '-v /root/.gradle/:/root/.gradle/ -v /root/.m2/:/root/.m2/' +
          ' --net bridge1 -e "DB_HOST=mysql" -e "REDIS_HOST=redis"' +
          ' -e "DB_DATABASE=test_db" -e "DB_USERNAME=root" -e "DB_PASSWORD=my-secret-pw"'
          reuseNode true
        }
      }
      steps {
        sh './gradlew test'
      }
    }
  }
}

直接在持续集成中安装工具

如果您不希望通过 Docker 自定义构建环境,也可以直接在持续集成中安装。

stage('安装 yarn') {
    steps {
        sh 'npm install -g yarn'
        sh 'yarn -v'
    }
}
stage('安装依赖') {
    steps {
        sh 'yarn install'
    }
}

更多参数

在自定义 Docker 构建环境时,可以选择是否使用根节点的的工作空间。当勾选该选项时,当前 stage 的 Docker 容器会和 pipeline 在同一个 node 运行,当前 stage 在运行时可以获取 pipeline 工作空间(workspace)的根目录下保存的所有文件。

对应的 Jenkinsfile 参数为 reuseNode ,类型:Boolean,默认为 false:

pipeline {
    agent { // pipeline agent
        docker { 
            registryUrl 'https://coding-public-docker.pkg.coding.net'
            image 'public/docker/android:29'
        }
    }
    stages {
        // 代码被检出到 pipeline agent 的工作空间根目录下
        stage('检出代码') {
            steps {
                checkout([
                    $class: 'GitSCM', 
                    branches: [[name: env.GIT_BUILD_REF]], 
                    userRemoteConfigs: [[url: env.GIT_REPO_URL, credentialsId: env.CREDENTIALS_ID]]
                ])
            }
        }
        stage('单元测试') {
            agent { // stage pipeline
                dockerfile {
                    // 默认在当前节点工作空间根目录下找名为 “Dockerfile” 的文件构建环境
                    filename 'Dockerfile'
                    // 如果 reuseNode 为 false,则无法找到之前检出到 pipeline agent 的工作空间根目录下的 Dockerfile
                    reuseNode true
                }
            }
            steps {
                sh 'npm run test:ci'
                junit '*.xml'

            }
        }
    }
}

参考资料

上一篇持续集成快速入门
最近更新
感谢反馈有用
感谢反馈没用