持续集成
基本概念
- 持续集成(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:dindstage: 哪个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 可以进行校验。