上篇文章我们成功使用了Gitlab Runner
执行了第一个CI
程序,本文在上篇的基础上进行.gitlab-ci.yml
文件的配置教程,让你可以利用CI
程序轻松做到前端团队项目的自动化部署,如果还没有阅读过上篇文章,请关注 深入浅出,前端团队的自动化部署指南 - 环境篇
任务机制
在CI
文件中,我们可以对一系列任务做定义,每个任务至少需要包含一条可执行的语句
job1:
script:
- npm run build:job1
job2:
script:
- npm run build:job2
你可以在 script
定义 Runner
环境可执行的所有语句,每一个任务都会按照定义顺序执行,需要注意的是,以下关键词不能用作任务名
关键字 | 描述信息 |
---|---|
image | 当前CI程序运行的Docker镜像 |
services | 当前CI程序使用的Docker服务 |
stages | 定义构建场景 |
types | stages 的别名 |
before_script | 定义每个任务启动前的执行脚本 |
after_script | 定义每个任务启动后的执行脚本 |
variables | 定义构建变量 |
cache | 定义构建时的缓存文件,用于之后的任务执行 |
构建场景
stages
关键字用于定义构建场景,可以被构建任务引用定义自己的构建场景,stages
定义的顺序也决定了任务执行的顺序,下面给出一个基本的场景示例
stages:
- test
- build
- publish
- 首先所有任务的构建场景为
test
的任务全部并行执行 - 接着会执行构建场景为
build
的所有任务 - 最后执行构建场景为
publish
的所有任务 - 其中任何一个任务失败,整个流水线会失败,并且之后的任务不会执行
stages
可以不被定义,那么程序会默认为 test
build
deploy
三个场景,如果一个任务没有指定自己的 stage
,那么它将默认使用 test
任务切面
这里所说的是 before_script
和 after_script
两个关键字,因为他们的作用类似于AOP
,所以我习惯称为任务切面,切点就是所有任务的执行前和执行后
before_script
会在所有任务开始之前执行,所有可以在该关键字中定义依赖环境的安装
before_script:
- npm install
- echo 'Install successful'
after_script
会在任务执行之后开始执行,所有可以再这里做一些通知类的操作,需要注意的是,after_script
应该是基于独立环境运行,所有该执行栈不能访问到环境中的某些变量定义和文件缓存,部署等动作建议放在 publish
或者 deploy
环节
after_script:
- /data/bin/emitUsers.sh $CI_PROJECT_NAME $GITLAB_USER_EMAIL # 通知所有用户完成构建
上面的 CI_PROJECT_NAME
以及 GITLAB_USER_EMAIL
是引用 Runner
程序中自带的内置变量,内置变量的种类请参考以下 CI程序内置变量
自定义构建变量
CI
程序允许你向构建过程中添加自定义变量,需要注意的是,CI
文件中定义的变量都是存储在 Git
仓库中,所以关键的路径或程序设置不应该设置在自定义变量中
你可以使用 variables
关键字定义你的自定义变量
variables:
MY_DATA: 'This is test message'
变量还可以单独定义在某一个任务中,仅可以在该任务使用变量
job1:
variables:
BUILD_PATH: '/data/web/$CI_PROJECT_NAME'
script:
- echo $BUILD_PATH
- echo $MY_DATA
使用缓存
有的时候我们需要在执行构建中多个任务之间缓存一些文件,让多个任务同时使用该缓存,比如前端项目中我们需要缓存 node_modules
文件夹, 那我们可以使用 cache
关键字如下定义,paths
关键字是一个缓存对象数组
cache:
paths:
- node_modules/
cache 中的 key 属性可以用来定义缓存的作用于,如果不设置,默认为全部分支的全部任务都可以使用该策略,可以选择如下设置
cache:
key: $CI_JOB_NAME # 不同分支的不同任务都使用该缓存
key: $CI_COMMIT_REF_NAME # 相同分支使用同一份缓存
key: $CI_JOB_STAGE-$CI_COMMIT_REF_NAME # 允许每个分支的每个任务通用缓存
paths:
- node_modules/
cache
中还存在 policy
的相关设置,可以定义缓存在每个任务中的下载推送规则,如果设置得当,则会大量提速你的构建任务,这里不再赘述,请阅读官方文档 Cache
使用 Docker
image
关键字允许当前CI程序基于某个Docker镜像中运行,当然前提是你的任务指定的tags
必须是以Docker形式注册的Github Runner
,CI程序会默认在你本地寻找镜像,如果不存在的话,则会从Docker Hub拉取
services
关键字定义基于images
运行的程序中需要依赖的其他镜像程序
总体使用Docker的方法类似于 Docker-Compose
任务机制详解
job_name:
# 要跑的脚本或命令列表
script:
- npm install
- npm run lint
# pipelines阶段
stage: test
# 只针对哪个分支
only:
- master
# 除了哪个分支以外
except:
- develop
# 指定哪些runner适用该job
tags:
- fe-vue
# 是否容错
allow_failure: true
关键字 | 描述信息 |
---|---|
script | 需要执行的脚本或者命令 |
image | 当前Job运行的镜像 |
services | 当前Job依赖的服务 |
stage | 任务的工作场景,默认是test |
variables | 任务级别的变量声明 |
only | 在哪些分支生效 |
except | 除了哪些分支生效 |
tags | 设置任务使用的runners |
when | 定义任务什么时候能被执行,可以是on_success,on_failure,always或者manual |
artifacts | 任务级别缓存,在各个任务之间负责产物传递 |
environment | 定义任务完成的环境,一般用于在deploy后声明环境使用,在Github中可以查看环境部署 |
retry | 任务失败后的重试次数 |
script
用来定义一个任务中需要执行的shell脚本
script: "npm install"
# 也可以多组脚本
script:
- npm install
- npm run lint
- npm run build
image && services
与外部的关键字作用一致,不过作用于仅在当前任务
stage
定义当前任务的工作场景,通常是stages
关键字中定义的一个,也可以使用默认的场景,如果忽略的话,场景默认为test
variables
在当前任务定义的变量,会覆盖掉已经声明的全局变量,如果设置了该关键字的话,在当前任务中YAML文件设置的全局变量则不生效
only && except
这两个关键字定义任务什么时候将会被创建
only
定义了任务需要执行的所在分支或者标签except
定义了任务不会执行的所在分支或者标签
以下是这两个参数的几条用法规则:
- 两者如果都存在在一个任务声明中,则所需引用将会使用两者交集过滤
- 两者均允许使用正则
tags
指定当前任务适用的 runners
when
指定当前任务在什么时候执行,支持以下四个关键字
on_success
只有在之前场景执行的所有作业成功的时候才执行当前任务,该值为默认值,也就是说如果流水线中任何一个任务失败,整个流水线将失败on_failure
只有在之前场景执行的任务中至少有一个失败的时候才执行always
总是执行manual
手动执行
artifacts
指定当前任务的产物缓存,可以用于在多个任务之间传递产物,其中也包含多种个性化设置,参考原文档
CI程序内置变量
自定义变量存在优先级策略,如果设置了相同名称的具备变量,其值可以覆盖CI的内置变量,变量的优先级排序如下,优先级从高到低
Secret variables
(私有变量,可以在Gitlab
中手动设置,适用于所有流水线)YAML-defined job-level variables
(CI
文件中定义的局部变量,例如任务中定义的变量)YAML-defined global variables
(CI
文件中定义的全局变量)Deployment variables
(项目变量,文档)Predefined variables
(内置变量)
在这里提供 Gitlab CI 的一些内置变量,目前是基于 Gitlab 9.0 版本以上的说明,如果你发现某些变量不存在或者不符合预期,可以访问原文档查看目前的名称及含义
变量名称 | 描述信息 |
---|---|
CI | 标识该任务是在CI 环境中执行 |
CI_COMMIT_REF_NAME | 用于构建项目的分支或Git tag 名称 |
CI_COMMIT_SHA | commit 的版本号 |
CI_COMMIT_TAG | commit 的 tag 名称,任务对应的 tag |
CI_DEBUG_TRACE | debug tracing 开启时才生效 |
CI_ENVIRONMENT_NAME | 任务的环境名称 |
CI_ENVIRONMENT_SLUG | 环境名称的简化版本,适用于DNS ,URLs ,Kubernetes labels 等 |
CI_JOB_ID | GitLab CI 内部调用任务的一个唯一标识 |
CI_JOB_NAME | .gitlab-ci.yml 中定义的任务名称 |
CI_JOB_STAGE | .gitlab-ci.yml 中定义的场景名称 |
CI_JOB_TOKEN | 用于 Gitlab Runner 仓库验证的口令 |
CI_REPOSITORY_URL | Git 仓库地址 |
CI_RUNNER_DESCRIPTION | Gitlab 中的 Runner 描述 |
CI_RUNNER_ID | Runner 所使用的唯一标识 |
CI_RUNNER_TAGS | Runner 定义的tags |
CI_PIPELINE_ID | GitLab CI 在内部使用的当前流水线的唯一标识 |
CI_PROJECT_DIR | 仓库克隆的完整本地地址 |
CI_PROJECT_ID | 当前项目的唯一标识 |
CI_PROJECT_NAME | 当前正在构建的项目名称 |
CI_PROJECT_NAMESPACE | 当前正在构建的项目命名空间 |
CI_PROJECT_PATH | 命名空间加项目名称 |
CI_PROJECT_PATH_SLUG | $CI_PROJECT_PATH 的小写字母,除了0-9和a-z的其他字母都替换成-,用于地址和域名名称 |
CI_PROJECT_URL | 项目的访问地址 |
CI_SERVER_NAME | 用于协调任务的 CI 服务器名称 |
CI_SERVER_VERSION | 用于调度任务的 Gitlab 版本 |
ARTIFACT_DOWNLOAD_ATTEMPTS | 尝试运行下载 artifacts 的任务的次数 |
GET_SOURCES_ATTEMPTS | 尝试运行获取源的任务次数 |
GITLAB_USER_ID | 开启该任务的用户ID |
GITLAB_USER_EMAIL | 开启该任务的用户邮箱 |
RESTORE_CACHE_ATTEMPTS | 尝试运行存储缓存的任务的次数 |
在多种环境中使用变量的时候,需要区分变量的使用方式有些许不同
bash/sh
>>>$variable
windows batch
>>>%variable%
PowerShell
>>>$env:variable
你也可以使用 export 关键字打印出所有的变量,需要注意的是,该关键字也会打印出任务中定义的所有私有变量
job:
script:
- export
内置变量打印的例子如下
export CI_JOB_ID = '50'
export CI_COMMIT_SHA = '1ecfd275763eff1d6b4844ea3168962458c9f27a'
export CI_COMMIT_SHORT_SHA = '1ecfd275'
export CI_COMMIT_REF_NAME = 'master'
export CI_REPOSITORY_URL = 'https://gitlab-ci-token:abcde-1234ABCD5678ef@example.com/gitlab-org/gitlab-foss.git'
export CI_COMMIT_TAG = '1.0.0'
export CI_JOB_NAME = 'spec:other'
export CI_JOB_STAGE = 'test'
export CI_JOB_MANUAL = 'true'
export CI_JOB_TRIGGERED = 'true'
export CI_JOB_TOKEN = 'abcde-1234ABCD5678ef'
export CI_PIPELINE_ID = '1000'
export CI_PIPELINE_IID = '10'
export CI_PAGES_DOMAIN = 'gitlab.io'
export CI_PAGES_URL = 'https://gitlab-org.gitlab.io/gitlab-foss'
export CI_PROJECT_ID = '34'
export CI_PROJECT_DIR = '/builds/gitlab-org/gitlab-foss'
export CI_PROJECT_NAME = 'gitlab-foss'
export CI_PROJECT_TITLE = 'GitLab FOSS'
export CI_PROJECT_NAMESPACE = 'gitlab-org'
export CI_PROJECT_PATH = 'gitlab-org/gitlab-foss'
export CI_PROJECT_URL = 'https://example.com/gitlab-org/gitlab-foss'
export CI_REGISTRY = 'registry.example.com'
export CI_REGISTRY_IMAGE = 'registry.example.com/gitlab-org/gitlab-foss'
export CI_REGISTRY_USER = 'gitlab-ci-token'
export CI_REGISTRY_PASSWORD = 'longalfanumstring'
export CI_RUNNER_ID = '10'
export CI_RUNNER_DESCRIPTION = 'my runner'
export CI_RUNNER_TAGS = 'docker, linux'
export CI_SERVER = 'yes'
export CI_SERVER_URL = 'https://example.com'
export CI_SERVER_HOST = 'example.com'
export CI_SERVER_PORT = '443'
export CI_SERVER_PROTOCOL = 'https'
export CI_SERVER_NAME = 'GitLab'
export CI_SERVER_REVISION = '70606bf'
export CI_SERVER_VERSION = '8.9.0'
export CI_SERVER_VERSION_MAJOR = '8'
export CI_SERVER_VERSION_MINOR = '9'
export CI_SERVER_VERSION_PATCH = '0'
export GITLAB_USER_EMAIL = 'user@example.com'
export GITLAB_USER_ID = '42'
结语
参照上面的配置文件设置,已经足够完成大多数的CI,CD任务,但是在个性化设置层次还略有不足,另外文字描述略显生硬,基本都是参考原文档的翻译内容,对于学习来说难度略大
下篇文章会给大家带来实战篇的CI,CD部署教程,更多细节性的策略与应用,敬请关注