GitLab CI CD

GitLab CI CD

Posted by WTJ on January 1, 2019

目录

一、基本概念

1.1. CI/CD

CI,Continuous Integration,为持续集成。即在代码构建过程中持续地进行代码的集成、构建、以及自动化测试等;有了 CI 工具,我们可以在代码提交的过程中通过单元测试等尽早地发现引入的错误;

CD,Continuous Deployment,为持续交付。在代码构建完毕后,可以方便地将新版本部署上线,这样有利于快速迭代并交付产品。

1.2. GitLab CI/CD

GitLab CI/CD(后简称 GitLab CI)是一套基于 GitLab 的 CI/CD 系统,可以让开发人员通过 .gitlab-ci.yml 在项目中配置 CI/CD 流程,在提交后,系统可以自动/手动地执行任务,完成 CI/CD 操作。而且,它的配置非常简单,CI Runner 由 Go 语言编写,最终打包成单文件,所以只需要一个 Runner 程序、以及一个用于运行 jobs 的执行平台(如裸机+SSH,Docker 或 Kubernetes 等,我推荐用 Docker,因为搭建相当容易)即可运行一套完整的 CI/CD 系统。

cicd_pipeline_infograph

概念 描述
Pipelines 通过管道构建您的 CI/CD 流程。
CI/CD variables 基于变量/值键对重用值。
Environments 将您的应用程序部署到不同的环境(例如,登台、生产)。
Job artifacts 输出、使用和重用作业工件。
Cache dependencies 缓存您的依赖项以加快执行速度。
GitLab Runner 配置您自己的运行器以执行您的脚本。
Pipeline efficiency 配置您的管道以快速高效地运行。
Test cases 创建测试场景。

pipeline

pipeline 实际是一组 stages 中执行 job 的集合,代表着使用者触发的一次构建 。任何提交,包括 MR 在符合配置文件要求的情况下都可以触发 pipeline,其在网页中的体现如下:

Snip20180715_13

stage

pipeline 中的 jobs 按照构建阶段进行分类,这些分类就是一个个 stage 。如 pipeline 示意图所示,一个 pipeline 中可以定义多个 stage ,比如 build, test, staging, production,其对应配置语法如下:

stages:
  - build
  - test
  - staging
  - production

stage 的触发顺序和 stages 字段值定义的顺序一致,并且只有完成当前 stage , pipeline 才会触发下一个 stage ,如果 stage 失败了,则下一个 stage 将不会被触发,完成所有的 stage 表示此次 pipeline 构建成功。

job

job 表示 stage 中实际执行的任务。如 pipeline 示意图所示,一个 stage 中可以有多个 job,比如 Test stage 的 test1、test2 job,其对应配置语法如下:

test1:
  stage: Test
  script: 
    - xxxx
  only:
    - xxxx
  tags:
    - xxxx
    
test2:
  stage: Test
  script: 
    - xxxx
  only:
    - xxxx
  tags:
    - xxxx

在有足够 runner (job 执行宿主机) 的情况下,同个 stage 中的 job 是并行的,当 stage 中的所有 job 都执行成功后,该 stage 才算完成,否则视为失败。

GitLab Runner

针对iOS项目,准备一台空闲(团队使用)Mac OS电脑当做服务器,内网服务器能访问外网即可,在此服务器上安装Runner,后续ci/cd相关脚本亦在此运行

下文操作基于 macOS 系统 Snip20180718_1

GitLab Runner 和 GitLab 的关系大体如上所示, GitLab Runner 内部会起一个无限循环,根据 check_interval 字段设置的时间间隔,去 GitLab 请求需要执行的任务。

更详细的信息可以查看 How shared Runners pick jobs How check_interval works

GitLab Runner 按服务对象可划分 shared runner 和 specific runner ,10.8 版本后还有 group runner,三者应用场景如下:

  • shared runner 主要针对要求配置相似的工程,可以运行不同仓库上的任务。
  • specific runner 主要针对要求特殊配置的工程,只能运行特定仓库上的任务。
  • group runner 主要针对某个分组下的所有工程(10.8 及以后版本才有)。

因为团队内部对工程进行了组件化,所以 specific runner 是比较合适的选择,也利于后期向其他业务线推广 CI 。 specific runner 注册需要 shared-runner token ,这个 token 只有 admin 账户可见,一般找 GitLab 的管理人员获取即可。以下为注册成功页(工程页 -> Settings -> CI / CD -> Runners -> Expand): Snip20180712_4

左边为注册的 specific runner ,使用上方显示的 npeoZhFa1nHYvTAsf7f_ token 即可,右边即是注册成功的 shared runner,运行状态为绿色表示正在运行。

接下来看下如何在 macOS 上安装注册 GitLab Runner。

安装 Gitlab Runner

Install Docker.app before registering a runner under macOS.

  • 通过 homebrew 安装:
    brew install gitlab-runner
    
  • 手动安装 为您的系统下载二进制文件:
  • 对于基于 Intel 的系统:

    sudo curl –output /usr/local/bin/gitlab-runner “https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-darwin-amd64”

  • 对于基于 Apple Silicon 的系统:

    sudo curl –output /usr/local/bin/gitlab-runner “https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-darwin-arm64”

  • 授予它执行权限:

sudo chmod +x /usr/local/bin/gitlab-runner

注册 Gitlab Runner

1、交互式注册 runner

1、输入

gitlab-runner register

对应的反向操作:

gitlab-runner unregister -u url -t token

# url 为下一个步骤输入值
# token 可以从网页端或者配置文件中查看

截止到 GitLab Runner 10, MacOS 中已验证可行的运行模式是用户模式,使用系统模式 (sudo) 注册的 Runner 会一直处于 Stuck 状态。

2、输入 GitLab URL 地址

Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/ )
> GitLab URL 地址

3、输入注册 Runner 需要的 Token

Please enter the gitlab-ci token for this runner
> Token

Token 分为 special token 和 shared token,前者在项目设置页可以拿到,后者只能联系 GitLab 管理员或者有 Admin 权限的情况下获得。注册后,会分别成为 special runner 和 shared runner。

4、输入标志 Runner 的 Tags

Please enter the gitlab-ci tags for this runner (comma separated):
iOS,Andriod

.gitlab-ci.yml 中可以设置 tags 字段来声明,当前任务只在拥有匹配 Tags 的 Runner 上运行。比如 iOS 编译阶段只能在 Mac Runner 上运行,那么就可以设置这个 Runner 的 Tags 为 ‘iOS’,并且在 iOS 工程中在字段 tags 中,添加‘iOS’ 值。 Tags 最好不要随便命名,遵循适当的命名规则会让后期 CI 的维护轻松许多。

5、是否允许运行没有设置 tags 的任务

Whether to run untagged jobs [true/false]:
[false]: false

可以在 GitLab 界面上更改 ,一般为 false

6、是否锁定当前工程

Whether to lock Runner to current project [true/false]:
[true]: true

在 Runner 是 special 的情况下比较有用,可以在 GitLab 界面上更改。

###7、Runner 执行者

Please enter the executor: ssh, docker+machine, docker-ssh+machine, kubernetes, docker, parallels, virtualbox, docker-ssh, shell:
shell

一般为 shell。

8、选择 docker 为执行者时,需要设置默认的 docker image

Please enter the Docker image (eg. ruby:2.1):
alpine:latest

非 docker 执行者,没有这一步。

2、命令式注册 runner

1、请运行以下命令

gitlab-runner register -h

2、常用的注册命令

sudo gitlab-runner register \
  --non-interactive \
  --url "https://gitlab.com/" \
  --registration-token "PROJECT_REGISTRATION_TOKEN" \
  --executor "docker" \
  --docker-image alpine:latest \
  --description "docker-runner" \
  --maintenance-note "Free-form maintainer notes about this runner" \
  --tag-list "docker,aws" \
  --run-untagged="true" \
  --locked="false" \
  --access-level="not_protected"

3、启动/关闭 Gitlab Runner

执行以下命令安装 runner 服务,并且启动它:

gitlab-runner install [--working-directory]
gitlab-runner start

如已经启动 runner 服务,添加了新的 runner ,直接执行 gitlab-runner start 即可。

关闭操作:

gitlab-runner stop
gitlab-runner uninstall

需要注意的是, 在不加 –working-directory 参数的情况下,runner 工作目录默认为执行 install 命令目录 ,触发了任务后,runner 会在此目录下创建 builds 文件夹 。

更多关于 runner 的命令,可以查看 GitLab Runner Commands

配置GitLab Runner

注册后 runner 的配置信息默认保存在 ~/.gitlab-runner/config.toml 文件中,其文件格式如下:

concurrent = 1
check_interval = 0

[[runners]]
  name = "iOS & Android CI Runner on packboy"
  url = "http://git.2dfire-inc.com/"
  token = "1ff160dc4d8f9c36e9b138adc4712a"
  executor = "shell"
  output_limit = 4096
  [runners.cache]
  
[[runners]]
  name = "xxxx"
  ...
  [runners.cache]

文件分为 Global Section 和 [[runners]] Section 两部分,这里只说下常用字段,想要了解更多信息,可以查看 GitLab Runner advanced configuration

Global Section 常用部分:

Setting Description
concurrent 可并发执行的最大任务数,0 不代表无限制
log_level Log 等级 (可选择: debug, info, warn, error, fatal, panic)。优先级比通过命令行 —debug, -l 或 –log-level 设置低
check_interval 设置轮询新任务的周期,单位(秒)。默认值为 3 秒,如果设置为 0 或者比 3 小,此字段使用默认值。

这里需要注意的是, CocoaPods 1.3.0 Release BlogNotable Enhancements 一节指出:

Each lint execution now runs in a unique temp folder. This allows for running multiple lint processes in parallel, for example within a CI environment.

也就是说, 在 1.3.0 版本之前,由于共用了承载 lint 操作的文件夹, CocoaPods 并不支持多个组件同时进行 lint。这就需要我们在设置 runner 的 concurrenct 配置时,确认实际使用的 CocoaPods 版本,如果低于 1.3.0 ,concurrenct 必须设置成 1 。

[[runners]] Section 常用部分

Setting Description  
name runner 名称  
url GitLab URL  
token runner 专有 token (不是注册 runner 时输入的 GitLab token),unregister 时可以使用  
limit 这个 token 下可并发执行的最大任务数,默认 0 ,表示无限制(需要结合上述 CocoaPods 1.3.0 版本以下的限制考虑)  
builds_dir runner 工作目录,默认会在 install 目录下创建 builds 文件夹  
cache_dir cache 保存目录  
environment 添加/覆盖环境变量,如 environment = [“ENV=value”, “LC_ALL=en_US.UTF-8”]  
output_limit 输出 log 大小限制,默认 4096 (4M),建议设置成 4096000pre_clone_script clone 之前执行的脚本,可以用来调整 Git 客户端配置
pre_build_script clone 之后,build 之前执行的脚本  
post_build_script build 之后,after_script 之前执行的脚本  
clone_url 自定义 clone 仓库的 url  

参考: 1、火掌柜 iOS 团队 GitLab CI 集成实践

2、runners 范围

3、runners 注册

4、在 macOS 上安装 GitLab Runner

5、GitLab CI/CD,iOS项目管控实战应用