持续集成
基本概念
- 持续集成(Continuous Integration):频繁地(一天多次)将代码集成到主干。让产品可以快速迭代,同时还能保持高质量。它的核心措施是,代码集成到主干之前,必须通过自动化测试。只要有一个测试用例失败,就不能集成。“持续集成并不能消除 Bug,而是让它们非常容易发现和改正。
- 持续交付(Continuous Delivery):频繁地将软件的新版本,交付给质量团队或者用户,以供评审。如果评审通过,代码就进入生产阶段。持续交付可以看作持续集成的下一步。它强调的是,不管怎么更新,软件是随时随地可以交付的。
- 持续部署(continuous Deployment):代码通过评审以后,自动部署到生产环境。是持续部署是持续交付的下一步,持续部署的目标是,代码在任何时刻都是可部署的,可以进入生产阶段。
持续集成有哪些优点
- 每天集成变化的代码,尽早发现风险,尽早估量软件的质量
- 流程自动化,减少重复性劳动 自动化部署工作可以解放集成、测试、部署等重复性劳动
- 保持随时部署,能快速反馈bug的修改而不是每次都需要改一段时间之后重新打包部署验证
GitLab CI
GitLab CI/CD
GitLab CI/CD
是 GitLab Continuous Integration
(Gitlab持续集成)的简称。GitLab
自GitLab 8.0
开始提供了持续集成的功能,且对所有项目默认开启。只要在项目仓库的根目录添加.gitlab-ci.yml
文件,并且配置了Runner
(运行器),那么每一次push或者合并请求(Merge Request)都会触发CI Pipeline
。
GitLab Runner
GitLab Runner是一个开源项目,可以运行在 GNU / Linux,macOS 和 Windows 操作系统上。每次push的时候 GitLab CI 会根据.gitlab-ci.yml
配置文件运行你流水线(Pipeline)中各个阶段的任务(Job),并将结果发送回 GitLab。GitLab Runner
是基于 Gitlab CI
的 API 进行构建的相互隔离的机器(或虚拟机)。GitLab Runner
不需要和 Gitlab 安装在同一台机器上,且考虑到 GitLab Runner
的资源消耗问题和安全问题,也不建议这两者安装在同一台机器上。
- 共享Runner:
Shared Runners
对于多个项目之间具有类似要求的作业非常有用。 您可以拥有一个或多个可以处理多个项目的Runners,而不是让多个Runner为多个项目空闲。 这样可以更轻松地维护和更新它们。Shared Runners
使用公平队列处理作业。与使用FIFO队列的特定Runner
相比,这可以防止项目创建数百个可能导致吃掉所有可用共享Runners资源的作业的情况。 - 专属Runner:
Specific Runners
对于具有特殊要求的作业或具有特定需求的项目非常有用。 如果某个工作有一定的要求,您可以考虑到这一点设置特定的Runner,而不必为所有Runner执行此操作。 例如,如果要部署某个项目,可以设置特定的Runner以获得正确的凭据。 在这种情况下,标签的使用可能是有用的。Specific Runners
使用FIFO队列处理作业。 - 分组Runner: 当您在一个组下有多个项目并且希望所有项目都可以访问一组Runners时,
Group Runners
非常有用。Group Runners
使用FIFO队列处理作业
Pipelines
Pipelines
我们也叫他流水线,比如一条流水线可能包含构建、测试打包、部署到服务器等步骤i,每次 push 和 Merge Request 都会触发流水线。
Stage
Stage
表示构建阶段,比如上图中的 Build、Test、Staging、Production这四个阶段,一个 Pipeline
有多个 Stage
。
- Stage会按照配置的顺序执行,当一个
Stage
完成之后才会执行下一个Stage
。 - 所有
Stage
成功完成,这个pipeline
才算成功(manual 任务可以不执行)。
3.如果一个Stage
失败,后面的Stage
都不会执行,当然也可以配置失败也往下继续执行。
Jobs
Jobs 表示每个作业,也就是 Stage
里面具体的某个任务,因为可以从上图中看到一个 Pipleline
包含多个 Stage
。一个 Stage
可以包含多个任务。
- 相同 Stage 中的 Jobs 无执行顺序要求,会并行执行
- 相同 Stage 中的 Jobs 都执行成功时,该 Stage 才会成功
- 如果任何一个 Job 失败,那么该 Stage 失败,即该构建任务 (Pipeline) 也失败(可以在.gitlab-ci.yml文件中配置允许某 Job 可以失败,也算该 Stage 成功)
.gitlab-ci.yml
1 | variables: |
上面就定义了一个简单的 pipeline
,其实只有两个阶段,一个test,一个sonar。
GitLab CI/CD yaml 常用配置
Job
Job
可以定义很多个,但是每个 Job
只能有一个唯一的名字,下面的字段来描述 job
做的事
script
: 必须,表示Runner
执行的脚本extends
: 继承的配置条目images
: 这个job
所用的 Docker 镜像services
: 依赖的 Docker 服务,比如Docker:dind
stage
: 哪个stage
的variables
: job级别的变量only
: 指定触发的情况except
: 指定不能触发的情况tags
: 筛选 Runnerallow_failure
: 允许失败,失败不影响 stage 失败when
: 定义何时开始job,可以是on_success,on_failure,always或者manualdependencies
: 定义job依赖关系,这样他们就可以互相传递artifactscache
: 定义在后续运行的缓存文件列表,后面的job可以用before_script
: script运行之前运行的脚本after_script
: script运行之后的命令environment
: 作业完成部署的环境名称retry
: 定义在发生故障时可以自动重试作业的时间和次数parallel
: 定义并行运行的作业实例数
only 和 except
only 和 except 可以指定分支名字,或者是个正则表达式,比如
1 | job: |
或者使用一些特殊的值:
branches
: 只要是分支tags
: 打tag的时候merge_requests
: Merge Request 的时候pushes
: push代码就触发schedules
: 定时任务运行trigger
: 触发器运行web
: 页面点了才运行
cache
使用paths指令选择要缓存的文件或目录。也可以使用通配符。
如果 cache 定义在 jobs 的作用域之外,那么它就是全局缓存,所有 jobs 都可以使用该缓存。
比如 rspec
阶段我缓存他的 binaries 目录下的 apk 文件和 .config
文件
1 | rspec: |
但是某个任务的缓存会覆盖全局的,比如 下面这个 rspec
job 只会缓存 binaries/
目录下的文件。
1 | cache: |
可以使用下面这个配置项缓存 binaries
下没有被 git
跟踪的文件
1 | rspec: |
缓存作业的默认行为是在执行开始时下载文件,并在最后重新上传它们。这允许将作业所做的任何更改保留以供将来运行,并称为先拉再推缓存策略。 如果您知道作业不会更改缓存文件,则可以通过设置策略跳过上传步骤:拉入作业规范。通常,这将在较早阶段与普通缓存作业配对,以确保缓存不时更新。可以使用 policy: push
跳过下载只上传
1 | stages: |
artifacts
artifacts用于指定成功后应附加到 job 的文件和目录的列表。只能使用项目工作间内的文件或目录路径。在job成功完成后artifacts将会发送到GitLab中,同时也会在 GitLab UI 中提供下载。如果想要在不通的 job 之间传递artifacts,请查阅依赖关系。以下是一些例子
发送binaries和.config中的所有文件:
1 | artifacts: |
可以配置文件过期时间
1 | job: |
比如下面这个例子,文件传递
1 | installing-dependencies: |
artifacts 默认会在多个job传递,可以使用如下配置禁止传递
1 | sonar-job: |
cache 和 artifacts 的区别
其中 cache 指的是缓存, 常用于依赖安装中, 如几个jobs都需要安装相同的依赖, 可以使用依赖, 此时可以加快依赖的安装进度;
对于artifacts则是将某个工件上传到GitLab提供下载或后续操作使用, 由于每个job启动时, 都会自动删除.gitignore中指定的文件, 因此对于依赖安装目录, 即可以使用cache, 也可以使用artifacts。
主要区别如下:
- cache不一定命中,artifacts肯定命中, 能否使用cache取决当当前机器是否生成过cache, artifacts则每次都会从GitLab下载
- 特别是开发环境, 如果每次都希望使用最新的更新, 应当删除cache, 使用artifacts, 这样可以保证确定的更新
- artifacts中定义的部分, 会自动生成, 并可以传到下面的job中解压使用, 避免了重复依赖安装等工作
- 如果使用Docker运行Gitlab-Runner, cache会生成一些临时容器, 不容易清理
- artifacts可以设置自动过期时间, 过期自动删除,cache不会自动清理
- artifacts会先传到GitLab服务器, 然后需要时再重新下载, 所以这部分也可以在GitLab下载和浏览
更多
配置定时任务
GitLab CI 中可以在 GitLab Settings -> CI/CD -> Schedules中配置定时任务,点击New Schedule按钮,可以配置你流水线的定时执行任务,包括:描述信息、定时的Cron表达式、目标分支、变量等信息。
然后在需要定时执行的作业的only分支写上schedules即可。
校验 .gitlab-ci.yml
CI/CD
-> pipelineS
列表页面右上角有个 CI Lint
可以进行校验。