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

持续集成的构建环境

功能介绍

构建环境是指用来运行构建任务的环境,它通常是一个预装了开发语言 SDK、命令行工具的环境,分为两种:

  • 默认环境:操作系统环境
  • Docker 环境:Docker 镜像或 Dockerfile

默认环境

「使用默认构建环境」即在「构建节点」的操作系统上运行。CODING 持续集成为每个构建任务分配一台 Linux 云主机(VM),即「CODING 云主机」,也可以接入「自定义构建节点」。

对应的 Jenkinsfileagent any

pipeline {
  agent any
  stages  {
    stage("检出") {...}
    stage("检查代码规范") {...}
  }
}

「CODING 云主机」为 Ubuntu 系统,预装了以下 SDK 和命令行工具:

预装的语言和 SDK

默认环境中提供的 SDK(更新日期:2021 年 3 月 1 日):

  • 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(以及 7.0、7.1、7.2、7.4、8.0)
  • 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
  • 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

切换语言版本

stage('切换 Node.js 版本') {
  steps {
  sh 'curl -fsSL https://deb.nodesource.com/setup_14.x | bash -'
  // sh 'curl -fsSL https://deb.nodesource.com/setup_15.x | bash -'
  sh 'apt-get install -y nodejs'
  sh 'node -v'
  }
}
stage('切换 PHP 版本') {
  steps {
  // sh 'update-alternatives --set php /usr/bin/php7.4'
  sh 'update-alternatives --set php /usr/bin/php8.0'
  sh 'php -v'
  echo '安装 redis 扩展'
  sh 'apt-get install -y php8.0-redis'
  sh 'php -i | grep redis'
  }
}

使用 Docker 自定义构建环境

若默认环境中预装的 SDK 版本不满足要求,您可以使用自定义 Docker 构建环境作为 pipeline / stage 的 agent:

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

CODING 官方 Docker 镜像

在【持续集成计划设置】->【流程配置】->【基础配置】->【图形化编辑器】中,选择 「使用 CODING 官方提供的 Docker 镜像」,比如 Node.js 14:

对应的 Jenkinsfile 为:

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

项目制品库 Docker 镜像

对应的 Jenkinsfile

pipeline {
  agent {
    docker {
      reuseNode 'true'
      registryUrl 'https://codes-farm-docker.pkg.coding.net'
      registryCredentialsId "${env.DOCKER_REGISTRY_CREDENTIALS_ID}"
      image 'coding-workshop/release/workshop-web-app:1.2.3'
    }
  }
}

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

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

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

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

指定地址的 Docker 镜像

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

对应的 Jenkinsfile

pipeline {
  agent {
    docker {
      image 'node:lts-alpine'
      reuseNode 'true'
    }
  }
  stages {
    stage('Test') {
      steps {
        sh 'node --version'
      }
    }
  }
}

Dockerfile

如果项目已经使用 Docker,建议把 Dockerfile 提交到代码库,用它作为持续集成构建环境。Dockerfile 示例代码:

FROM php:8.0-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

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 'adoptopenjdk:11-jdk-hotspot'
          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 的 Docker 容器会和 pipeline 在同一个 node 运行,当前 stage 在运行时可以获取 pipeline 工作空间(workspace)的根目录下保存的所有文件。

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

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 {
        dockerfile {
          // 默认在当前节点工作空间根目录下找名为 「Dockerfile」的文件构建环境
          filename 'Dockerfile'
          // 如果 reuseNode 为 false,则无法找到之前检出到 pipeline agent 的工作空间根目录下的 Dockerfile
          reuseNode true
        }
      }
      steps {
        sh 'npm run test:ci'
        junit '*.xml'

      }
    }
  }
}

参考资料

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

在阅读中是否遇到以下问题?

您希望我们如何改进?