CODING 持续集成

持续集成

持续集成(Continuous integration),指的是**频繁地将代码集成到主干**

持续集成主要目的,就是让产品可以快速迭代,同时还能保持高质量。它的核心措施是,代码集成到主干之前,必须通过自动化测试。只要有一个测试用例失败,就不能集成。

Jenkins

Jenkins 是一款开源 CI&CD 软件,用于自动化各种任务,包括构建、测试和部署软件。Jenkins 支持各种运行方式,可通过系统包、Docker 或者通过一个独立的 Java 程序。

流水线

流水线,指的是按顺序连接在一起的事件或作业组,可以通过脚本,把项目的构建、测试、部署等阶段组合起来执行

Jenkins Pipeline

Jenkins Pipeline(或简称为 “Pipeline”)是一套插件,将持续交付的实现和实施集成到 Jenkins 中。它提供了一套可扩展的工具,用于将“简单到复杂”的交付流程实现为“持续交付即代码”。而 Jenkins Pipeline 的定义通常被写入到一个文本文件(称为 Jenkinsfile )中,该文件可以被放入项目的源代码控制库中。

Jenkinsfile

JenkinsFile 可以通过两种语法来声明流水线结构,一种是声明式语法,另一种是脚本式语法

声明式流水线

声明式流水线是由一个包含了一些指令和部分的外套代码块组成的。每个部分又可以包含其他的部分、指令和步骤,在某些情况下也会包含条件。

Pipeline

流水线(Pipeline)表示一个构建任务的总过程,包含所有阶段,如构建、测试、部署等。所有的 stage/阶段和 step/步骤都在这个块中定义。它是声明性流水线语法的关键块。

语法格式如下:

1
2
3
4
pipeline {
...
}

Agent

指定自定义工作空间。通常定义在pipeline 的顶部位置或者在每个 stage 中。

参数
  • any:可以运行在任意节点上。
1
2
3
4
pipeline {
agent any
...
}
  • none :不指定全局代理节点,如有必要,需要为单个阶段指定代理节点。
1
2
3
4
pipeline {
agent none
...
}
  • label:在指定标签的节点上运行。
1
2
3
4
pipeline {
agent {label 'my-defined-label'}
...
}
  • docker:使用指定的容器执行流水线或阶段
1
2
3
4
5
6
7
8
9
10
pipeline {
agent {
docker {
image 'hyperf/hyperf:7.4-alpine-v3.11-swoole'
reuseNode 'true'
registryCredentialsId '7ca3f680-1791-4f91-a9bc-d106fa661480'
}
}
...
}
  • dockerfile:执行流水线或阶段, 使用从源代码库包含的 Dockerfile 构建的容器
1
2
3
4
5
6
7
8
9
pipeline {
agent {
dockerfile {
filename 'Dockerfile'
dir 'docker'
}
}
...
}

Stage

流水线中可以包含多个 stage/阶段,一个 stage/阶段执行一个特定任务,例如测试、部署等,每个 stage/阶段可以包含多个步骤。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
pipeline {
...

stages {
stage ('Build') {
...
}
stage ('Test') {
...
}
stage ('Deploy') {
...
}
}

...
}

Step

一个 Step/步骤是指某个阶段中的单个任务。可以在一个阶段块中定义一系列步骤,这些步骤依次执行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
pipeline {
...

stages {
stage('Parallel Stage') {
parallel {
stage('Stage A') {
steps {
...
}
}
stage('Stage B') {
steps {
...
}
}
}
}
}

...
}

Parallel

并行执行流水线的多个阶段。 注意,一个阶段必须只有一个 steps 或 parallel 的阶段。 嵌套阶段本身不能包含进一步的 parallel 阶段, 但是其他的阶段的行为与任何其他 stage 相同。任何包含 parallel 的阶段不能包含 agent 或 tools 阶段, 因为他们没有相关 steps。

1
2
3
4
5
6
7
8
9
10
11
pipeline {
...

stages {
stage ('Build') {
steps {
echo 'Running build phase...'
}
}
}
}

Environment

定义环境变量,在整个流水线/阶段范围内可见。该指令支持一个特殊的助手方法 credentials(),该方法可用于在 Jenkins 环境中通过标识符访问预定义的凭证。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
pipeline {
...

environment {
USER_NAME = 'admin'
}

stages {
stage('Example') {
environment {
ACCESS_KEY = credentials('凭证ID或标识字符串')
}
steps {
sh 'printenv'
}
}
}
}

Script

处理非声明式的代码,如赋值语句 def name=’fq’。

1
2
3
4
5
6
7
8
9
10
11
12
13
pipeline {
...

stage('Example') {
steps {
script {
def config = [:]
config.name = "config-name"
echo "The Config is ${config.name}"
}
}
}
}

脚本式流水线

与声明式一样的是,都是建立在底层流水线的子系统上的。不同的是,脚本化流水线实际上是由 Groovy 构建的通用 DSL。 Groovy 语言提供的大部分功能都可以用于脚本化流水线的用户。这意味着它是一个非常有表现力和灵活的工具,可以通过它编写持续交付流水线。

Node

节点是执行整个工作流的机器。它是脚本化管道语法的关键部分。

语法格式如下:

1
2
3
4
5
6
7
8
9
10
// Jenkinsfile (Scripted Pipeline)
node {
stage('Example') {
if (env.BRANCH_NAME == 'master') {
echo 'I only execute on the master branch'
} else {
echo 'I execute elsewhere'
}
}
}

两者区别比较

  • 脚本化流水线为 Jenkins 用户提供了大量的灵活性和可扩展性。但 Groovy 学习曲线通常不适合给定团队的所有成员,因此创造了声明式流水线来为编写 Jenkins 流水线提供一种更简单、更有主见的语法。
  • 两者本质上是相同的流水线子系统。都是 “持续交付即代码“ 的持久实现。它们都能够使用构建到流水线中或插件提供的步骤。
  • 主要区别在于语法和灵活性
    • 声明式限制了用户使用更严格和预定义的结构, 使其成为更简单的持续交付流水线的理想选择。
    • 脚本化提供了很少的限制, 以至于对脚本和语法的唯一限制往往是由 Groovy 子集本身定义的,而不是任何特定于流水线的系统,这使他成为权利用户和那些有更复杂需求的人的理想选择。

流水线步骤(Pipeline Step

  • Basic Steps:为流水线提供常用步骤指令。常用指令有 echo、writeFile 等。
  • Nodes and Processes:为流水线提供节点以及进程管理的步骤指令。常用指令有 bat、powershell、sh 等。
  • SSH Pipeline Steps:为流水线提供 SSH 工具管理指令,用于命令执行或文件传输。
    • sshCommand:在远端机器执行指定命令
    • sshGet:从远端机器获取文件/目录到当前工作空间
    • sshPut:将当前工作空间的文件/目录放置到远端机器
    • sshRemove:将远端机器的某个文件/目录移除
    • sshScript:读取本地 shell 脚本,在远端机器执行
  • SCM Step:为流水线提供检查源代码指令。
    • checkout:从版本控制工具中检出代码。

CODING 中的持续集成

官方介绍,当提交了一部分修改完成的代码后,我们总是希望可以快速得到直观且有效的反馈,及早暴露问题。在开发过程中总有一部分工作是相对机械化,易出错的(例如打包、部署)。CODING 持续集成便是专门为此工作流而设计的得力功能。通过对每次提交的代码进行自动化的代码检查、单元测试、编译构建、甚至自动部署与发布,能够大大降低开发人员的工作负担,减少许多不必要的重复劳动,持续提升代码质量与开发效率。

凭据管理

打开在项目管理下方的项目设置。

选择开发者选项下的凭据管理,可自行进行管理。

快速上手

创建代码仓库

选择导入外部仓库,仓库地址:https://github.com/G-YDG/hyperf-demo.git

点击完成创建,等待项目导入。

导入完成后,进行创建构建计划。

选择自定义构建过程

填写构建计划名称以及选择代码仓库。

创建之后,选择流程配置。可以看到有两种编辑器,图形化编辑器以及文本编辑器。选择文本编辑器,并将以下代码粘贴进去。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
pipeline {
agent any
stages {
stage('检出') {
steps {
checkout([
$class: 'GitSCM',
branches: [[name: GIT_BUILD_REF]],
userRemoteConfigs: [[
url: GIT_REPO_URL,
credentialsId: CREDENTIALS_ID
]]])
}
}
stage('代码检查') {
parallel {
stage('自动化测试') {
agent {
docker {
image 'hyperf/hyperf:7.4-alpine-v3.11-swoole'
reuseNode 'true'
registryCredentialsId '7ca3f680-1791-4f91-a9bc-d106fa661480'
}

}
steps {
echo '自动化测试中...'
sh 'composer install && composer test'
echo '自动化测试结束...'
}
}
stage('代码风格检查') {
agent {
docker {
image 'hyperf/hyperf:7.4-alpine-v3.11-swoole'
reuseNode 'true'
}

}
steps {
echo '代码风格检查中...'
sh 'composer install && composer cs-fix'
echo '代码风格检查结束...'
}
}
}
}
stage('远程部署') {
steps {
echo '远程部署开始...'
script {
def remoteConfig = [:]
remoteConfig.name = "remote-server"
remoteConfig.host = "${REMOTE_HOST}"
remoteConfig.port = "${REMOTE_SSH_PORT}".toInteger()
remoteConfig.allowAnyHosts = true

node {
// 使用当前项目下的凭据管理中的 SSH 私钥 凭据
withCredentials([sshUserPrivateKey(
credentialsId: "${REMOTE_CRED}",
keyFileVariable: "privateKeyFilePath"
)]) {

// SSH 登陆用户名
remoteConfig.user = "${REMOTE_USER_NAME}"
// SSH 私钥文件地址
remoteConfig.identityFile = privateKeyFilePath

// 更新代码
sshCommand(
remote: remoteConfig,
command: """
cd ${DATA_PATH}
git pull
""",
sudo: false,
)

// 启动服务
sshCommand(
remote: remoteConfig,
command: """
cd /data/hyperf-demo
docker-compose up --build --always-recreate-deps -d
""",
sudo: false,
)
}
}
}

echo '远程部署结束...'
}
}
}
}

配置流程环境变量。

1
2
3
4
REMOTE_HOST:远程服务器地址
REMOTE_USER_NAME:远程连接用户名
REMOTE_CRED:Coding 凭据
DATA_PATH:项目工作路径

配置触发规则,保存修改。

配置完成后,点击保存修改并立即构建。

查看构建过程记录。

相关文档

[

](https://help.coding.net/docs/test-management/start.html)