持续集成gitlab-ci.yml配置文档基础
作者:快盘下载 人气:[TOC]
0x00 简述
答:gitlab-ci全称是gitlab continuous integration的意思就是持续集成;gitlab-ci.yaml是Gitlab-CI做持续集成和发布的执配置文件,里面定义了如何测试、编译、以及部署阶段执行的脚本,该文件的配置高度依赖于项目本身,以及 CI/CD 流水线的需求。即每次在我们push到gitlab的时候,都会触发此脚本
WeiyiGeek.CI/CD流程概览
1.Pipeline 描述:一次 Pipeline 其实相当于一次构建任务,里面可以包含很多个流程,如安装依赖、运行测试、编译、部署测试服务器、部署生产服务器等流程。任何提交或者 Merge Request 的合并都可以触发 Pipeline 构建,如下图所示
+----------------+ +----------+ | | trigger | | | Commit / Merge +---------->+ Pipeline | | | | | +----------------+ +----------+
2.Stages 描述:Stages 表示一个构建阶段,也就是上面提到的一个流程。我们可以在一次 Pipeline 中定义多个 Stages,这些 Stages会有以下特点:
1) 所有 Stages 会按照顺序运行,即当一个 Stage 完成后下一个 Stage 才会开始
2) 只有当所有 Stages 完成后,该构建任务 (Pipeline) 才会成功
3) 如果任何一个 Stage 失败,那么后面的 Stages 不会执行,该构建任务 (Pipeline) 失败 Stages 和 Pipeline 的关系如下所示:
+--------------------------------------------------------+ | | | Pipeline | | | | +-----------+ +------------+ +------------+ | | | Stage 1 |->| Stage 2 |->| Stage 3 | | | +-----------+ +------------+ +------------+ | | | +--------------------------------------------------------+3.Jobs 描述:Jobs 表示构建工作,表示某个 Stage 里面执行的工作。我们可以在 Stages 里面定义多个 Jobs,这些 Jobs 会有以下特点:1) 相同 Stage 中的 Jobs 会并行执行2) 相同 Stage 中的 Jobs 都执行成功时,该 Stage 才会成功3) 如果任何一个 Job 失败,那么该 Stage 失败,即该构建任务 (Pipeline) 失败, 但是可以通过参数设置allow_failure进行跳过
Jobs 和 Stage 的关系如下所示:
+------------------------------------------+ | | | Stage 1 | | | | +---------+ +---------+ +---------+ | | | Job 1 | | Job 2 | | Job 3 | | | +---------+ +---------+ +---------+ | | | +------------------------------------------+
.gitlab-ci.yml 基础实例:
#构建阶段-任务 stages: - analytics - test - build - package - deploy #构建工作job名称 build_analytics: #该工作执行阶段 stage: analytics #设置只对master分支有效 only: - master - tags tags: - runner-tag-snoreqube script: - echo "=============== 开始代码质量检测 ===============" - echo "=============== 结束代码质量检测 ===============" build_test: stage: test only: - master - tags tags: - runner-tag script: - echo "=============== 开始测试任务 ===============" - echo "=============== 结束测试任务 ===============" build: stage: build only: - master - tags tags: - runner-tag script: - echo "=============== 开始编译任务 ===============" - echo "=============== 结束编译任务 ===============" package: stage: package tags: - runner-tag script: - echo "=============== 开始打包任务 ===============" - echo "=============== 结束打包任务 ===============" deploy_test: stage: deploy tags: - runner-tag #输出在gitlab-ci中设置的变量 script: - echo "=============== 自动部署到测试服务器 ===============" - echo "测试服务器:" ${SERVER_TEST} #环境变量 environment: name: test url: https://staging.example.com deploy_test_manual: stage: deploy tags: - runner-tag script: - echo "=============== 手动部署到测试服务器 ===============" environment: name: test url: https://staging.example.com #设置条件 manual 允许失败 when: manual deploy_production_manual: stage: deploy tags: - runner-tag script: - echo "=============== 手动部署到生产服务器 ===============" - echo "测试服务器:" ${SERVER_TEST} environment: name: production url: https://staging.example.com when: manual
0x01 配置文档
描述:本章主要用于描述 .gitlab-ci.yml 的语法,. gitlab-ci.yml 文件被用来管理项目的 runner 任务。 任务是由Runners接管并且由服务器中runner执行。更重要的是每一个任务的执行过程都是独立运行的,这将意味着上个脚本产生的变量是无法在下一个任务脚本中进行使用。
下面列出保留字段,这些保留字段不能被定义为 job 名称:
关键字 是否必须 描述 image 否 用于docker镜像,查看docker文档 services 否 用于docker服务,查看docker文档 stages 否 定义构建阶段 types 否 stages 的别名(已废除) before_script 否 定义在每个job之前运行的命令 after_script 否 定义在每个job之后运行的命令 variable 否 定义构建变量 cache 否 定义一组文件列表,可在后续运行中使用
开始构建之前YAML文件定义了一系列带有约束说明的任务,用下面这个例子来说明:
image: ruby:2.1 services: - postgres before_script: - bundle install after_script: - rm secrets stages: - build - test - deploy job1: stage: build script: - execute-script-for-job1 only: - master tags: - docker job2: stage: deploy script: "execute-script-for-job2"
上面这个例子就是带有四个独立任务的CI配置,每个任务分别执行不同的命令,可以看出这些任务都是以任务名开始并且至少要包含 script 部分,并且script 可以直接执行系统命令(例如:./configure;make;make install)或者是直接执行脚本(test.sh)需要注意其执行权限;
gitlab-ci.yml指令约束说明
image和services
这两个关键字允许使用一个自定义的Docker镜像和一系列的服务,并且可以用于整个job周期。详细配置文档请查看:https://docs.gitlab.com/ce/ci/docker/README.html
before_script
用来定义所有job之前运行的命令,包括deploy(部署) jobs,但是在修复artifacts之后。它可以是一个 数组或者是多行字符串。
after_script
用来定义所有job之后运行的命令。它必须是一个数组或者是多行字符串
stages
前面简述了stages与pipelins之键的关系,它用来定义可以被job调用的stages。stages的规范允许 有灵活的多级pipelines,stages中的元素顺序决定了对应job的执行顺序。
1.相同stage的job可以平行执行。
2.下一个stage的job会在前一个stage的job成功后开始执行。
#例如上面stages构建阶段任务的例子 1. 首先,所有 build 的jobs都是并行执行的。 2. 所有 build 的jobs执行成功后, test 的jobs才会开始并行执行。 3. 所有 test 的jobs执行成功, deploy 的jobs才会开始并行执行。 4. 所有的 deploy 的jobs执行成功,commit才会标记为 success 5. 任何一个前置的jobs失败了,commit会标记为 failed 并且下一个stages的jobs都不会执行 #有两个特殊的例子值得一提: 1. 如果 .gitlab-ci.yml 中没有定义 stages ,那么job's stages 会默认定义为 build , test 和 deploy 。 2. 如果一个job没有指定 stage ,那么这个任务会分配到 test stage。
variables GItLab CI 允许在 .gitlab-ci.yml 文件中添加变量,并在job环境中起作用。因为这些配置是存储在git仓库中,所以最好是存储项目的非敏感配置,例如:
variables: DATABASE_URL:"postgres://postgres@postgres/WeiyiGeek"
这些变量可以被后续的命令和脚本使用。服务容器也可以使用YAML中定义的变量,因此我们可以很好的调控服务容 器。变量也可以定义成job level。除了用户自定义的变量外,Runner也可以定义它自己的变量例如 CI_COMMIT_REG_NAME 它的值表示用于构建项目的分支或tag名称。除了在 .gitlab-ci.yml 中设置变量外,还有可以通过GitLab的CI/CD界面上设置私有变量。
cache 用来指定需要在job之间缓存的文件或目录。只能使用该项目工作空间内的路径,从GitLab 9.0开始,pipelines和job就默认开启了缓存,如果 cache 定义在jobs的作用域之外,那么它就是全局缓存,所有jobs都可以使用该缓存。
#局部缓存 #缓存 binaries 和 .config 中的所有文件: rspec: script: test cache: paths: - binaries/ - .config #缓存git中没有被跟踪的文件: rspec: script: test cache: untracked: true #全局缓存 #job中优先级高于全局的。下面这个 rspec job中将只会缓存 binaries/ 下的文件: cache: paths: - my/files rspec: script: test cache: key: rspec paths: - binaries/
如果你不同的jobs缓存不同的文件路径,必须设置不同的cache:key,否则缓存 内容将被重写。 缓存key指令允许我们定义缓存的作用域(亲和性),可以是所有jobs的单个缓存,也可以是每个job,也可以是每个分支或 者是任何你认为合适的地方,并且cache:key 可以使用任何的预定义变量。 默认key是默认设置的这个项目缓存,因此默认情况下,每个pipelines和jobs中可以共享一切,从GitLab 9.0开始。
#缓存每个job: cache: key: "$CI_JOB_NAME" untracked: true #缓存每个分支: cache: key: "$CI_COMMIT_REF_NAME" untracked: true #缓存每个job且每个分支: cache: key: "$CI_JOB_NAME/$CI_COMMIT_REF_NAME" untracked: true #缓存每个分支且每个stage: cache: key: "$CI_JOB_STAGE/$CI_COMMIT_REF_NAME" untracked: true #如果使用的Windows Batch(windows批处理)来跑脚本需要用 % 替代 $ : cache: key: "%CI_JOB_STAGE%/%CI_COMMIT_REF_NAME%" untracked: true
_注意_:缓存是在jobs之前进行共享的。缓存只是尽力而为之,所以别期望缓存会一直存在。查看更多详细内容,请查阅GitLab Runner。
Jobs .gitlab-ci.yml 允许指定无限量jobs。每个jobs必须有一个唯一的名字,而且不能是上面提到的关键字。job由一列 参数来定义jobs的行为。
job_name: script: - rake spec - coverage stage: test only: - master except: - develop tags: - ruby - postgres allow_failure: true #指令说明 script yes #Runner执行的命令或脚本 image no #所使用的docker镜像,查阅使用docker镜像 services no #所使用的docker服务,查阅使用docker镜像 stage no #定义job stage(默认: test ) type no #stage 的别名(已弃用) variables #no 定义job级别的变量 only no #定义一列git分支,并为其创建job except no #定义一列git分支,不创建job tags no #定义一列tags用来指定选择哪个Gitlab-Runner(同时Runner也要设置tags) allow_failure no #允许job失败。失败的job不影响commit状态 when no #定义何时开始job 可以是 on_success , on_failure , always 或者 manual dependencies no #定义job依赖关系,这样他们就可以互相传递artifacts cache no #定义应在后续运行之间缓存的文件列表 before_script no #重写一组在作业前执行的命令 after_script no #重写一组在作业后执行的命令 environment no #定义此作业完成部署的环境名称 coverage no #定义给定作业的代码覆盖率设置
script 是Runner执行的脚本,该参数也可以用数组包含多个命令:
job: script: - uname -a - bundle exec rspec
有时候 script 命令需要被单引号或者是双引号包裹起来。举个例子,当命令中包含冒号( : )时,script需要被包 在双引号中,这样YAML解析器才可以正确解析为一个字符串而不是一个键值对(key:value)。使用这些特殊字符的时候一定 要注意:: , { , } , [ , ] , , , & , * , # , ? , | , - , < , > , = , !。
stage stage 允许一组jobs进入不同的stages。jobs在相同的 stage 时会 parallel 同时进行。查阅 stages 更多的用法请查看stages。
only and except only 和 except是两个参数用分支策略来限制jobs构建:
1.only 定义哪些分支和标签的git项目将会被job执行。
2.except 定义哪些分支和标签的git项目将不会被job执行。 下面是refs策略的使用规则:
only 和 except 可同时使用,如果 only 和 except 在一个job配置中同时存在,则以 only 为准,跳过except (从下面示例中得出)。
only 和 except 可以使用正则表达式。
only 和 except 允许使用特殊的关键字:branches , tags 和 triggers 。
only 和 except 允许使用指定仓库地址但不是forks的仓库(查看示例3)。
#(1)在下面这个例子中, job 将只会运行以 issue- 开始的refs(分支),然而except中设置将被跳过。 job: # use regexp only: - /^issue-.*$/ # use special keyword except: - branches #(2)在下面这个例子中, job 将只会执行有tags的refs,或者通过API触发器明确地请求构建。 job: # use special keywords only: - tags - triggers #(3)仓库路径只能用于父级仓库执行jobs而不是forks,将会为所有的分支执行 job ,但master分支除外。 job: only: - branches@gitlab-org/gitlab-ce except: - master@gitlab-org/gitlab-ce
Job variables 在job中是可以使用关键字 variables 来定义job变量。它的运行原理跟global-level是一样的,但是它允许设置特殊的job变量, Job变量的优先级关系可查看附录的variables文档说明。 当设置了job级别的关键字 variables ,它会覆盖全局YAML和预定义中的job变量。想要关闭全局变量可以在job中设置一个空数组:
job_name: variables: []
tags tags 可以从允许运行分配给此项目的所有Gitlab-Runners中选择特定的Runners来执行jobs,tags 可通过tags来指定特殊的Runners来运行jobs: 在注册Runner的过程中,我们可以设置Runner的标签,比如 ruby , postgres , development 。
job: tags: - ruby - postgres
上面这个示例中,需要确保构建此 job 的Runner必须定义了 ruby 和 postgres 这两个tags,否则报错此作业被卡住,因为没有任何该项目指定标签的 runner 在线。
allow_failure allow_failure 可以用于当你想设置一个job失败的之后并不影响后续的CI组件的时候。失败的jobs不会影响到 commit状态。 当开启了允许job失败,所有的intents和purposes里的pipeline都是成功/绿色,但是也会有一个"CI build passed with warnings"信息显示在merge request或commit或job page。这被允许失败的作业使用,但是如果失败表示其他地方应采取其他(手动)步骤。 下面的这个例子中:job1 和 job2 将会并列进行,如果 job1 失败了,它也不会影响进行中的下一个stage,因为 这里有设置了 allow_failure: true 。
job1: stage: test script: - execute_script_that_will_fail allow_failure: true job2: stage: test script: - execute_script_that_will_succeed job3: stage: deploy script: - deploy_to_staging
when when 用于实现在发生故障或尽管发生故障仍在运行的作业,可以设置以下值:
1.on_success - 只有前面stages的所有工作成功时才执行(默认值)
2.on_failure - 当前面stages中任意一个jobs失败后执行。
3.always - 无论前面stages中jobs状态如何都执行。
4.manual - 手动执行(GitLab8.10增加)。更多请查看手动操作。
stages: - build - cleanup_build - test - deploy - cleanup build_job: stage: build script: - make build cleanup_build_job: stage: cleanup_build script: - cleanup build when failed when: on_failure # test_job: stage: test script: - make test deploy_job: stage: deploy script: - make deploy when: manual #手动执行 cleanup_job: stage: cleanup script: - cleanup after jobs when: always #始终执行
脚本说明: 1.只有当build_job失败的时候才会执行 cleanup_build_job 。 2.不管前一个job执行失败还是成功都会执行 cleanup_job 。 3.可以从GitLab界面中手动执行 deploy_jobs 。
补充说明:Manual actions手动操作指令是不自动执行的特殊类型的job, 它们必须要人为启动。手动操作指令可以从pipeline,build,environment和deployment视图中启动。部署到生产环境是手动操作指令的一个很好示例。
手动操作指令可以是可选的或阻塞。在定义了手动执行的那个stage中,手动操作指令将会停止pipline中的自动执行指令。当有人通过点击play按钮来执行需要手动执行的job时,可以来恢复pipeline的执行。 当pipeline被阻塞时,即使是pipeline是成功状态也不会merge。被阻塞的pipelines也有一个特殊的状态,叫 manual 。 手动操作指令默认是不阻塞的。如果你想要手动操作指令产生阻塞,首先需要在job的配置文件 .gitlab-ci.yml 中添加 allow_failure:false ,可选的手动操作指令默认设置allow_failure:true 。可选动作的状态不影响整个pipeline的状态,手动操作指令被认为是写操作,所以当前用户触发操作时,必须拥有操作保护分支的权限。换句话说,为了触发一个手动操作指令到pipeline中正在运行的指定分支,当前用户必须拥有推送到这分支的权限。0x02 仓库相关
Git Strategy 你可以通过设置 GIT_STRATEGY 用于获取最新的代码,可以再全局 variables 或者是在单个job的 variables 模块中设置。如果没有设置,将从项目中使用默认值。 可以设置的值有: clone , fetch ,和 none 。
variables: #clone 是最慢的选项。它会从头开始克隆整个仓库,包含每一个job,以确保项目工作区是最原始的。 GIT_STRATEGY: clone #当它重新使用项目工作区是, fetch 是更快(如果不存在则返回克隆)。 git clean 用于撤销上一个job做的任何改变, git fetch 用于获取上一个job到现在的的commit。 GIT_STRATEGY: fetch #none 也是重新使用项目工作区,但是它会跳过所有的Git操作(包括GitLab Runner前的克隆脚本,如果存在的话)。它主要用在操作job的artifacts(例如: deploy )。 #Git数据仓库肯定是存在的,但是他肯定不是最新的,所以你只能依赖于从项目工作区的缓存或者是artifacts带来的文件。 GIT_STRATEGY: none
Git Checout 当 GIT_STRATEGY 设置为 clone 或 fetch 时,可以使用 GIT_CHECKOUT 变量来指定是否应该运行 git checkout 。如果没有指定,它默认为true。就像 GIT_STRATEGY 一样,它可以设置在全局 variables 或者是单个job的 variables 中设置。如果设置为 false时Runner就会:
fetch - 更新仓库并在当前版本中保留工作副本,
clone - 克隆仓库并在默认分支中保留工作副本。 【如果设置这个为 true 将意味着 clone 和 fetch 策略都会让Runner执行项目工作区更新到最新:】
variables: GIT_STRATEGY: clone GIT_CHECKOUT: false script: - git checkout master - git merge $CI_BUILD_REF_NAME
Git Submodule Strategy GIT_SUBMODULE_STRATEGY 变量用于在构建之前拉取代码时,Git子模块是否或者如何被引入。就像 GIT_STRATEGY 一样,它可在全局 variables 或者是单个job的 variables 模块中设置。 它的可用值有: none , normal 和 recursive :
none 意味着在拉取项目代码时,子模块将不会被引入。这个是默认值,与v1.10之前相同的。 normal 意味着在只有顶级子模块会被引入。它相当于: git submodule sync git submodule update --init recursive 意味着所有的子模块(包括子模块的子模块)都会被引入,他相当于: git submodule sync --recursive git submodule update --init --recursive
注意:如果想要此功能正常工作,子模块必须配置(在 .gitmodules )下面中任意一个:
可访问的公共仓库http(s)地址,在同一个GitLab服务器上有一个可访问到另外的仓库的真实地址。更多查看Git 子模块文档。Job stages attempts 正在执行的job将会按照你设置尝试次数依次执行下面的stages(默认是一次尝试):
GET_SOURCES_ATTEMPTS 获取job源的尝试次数 ARTIFACT_DOWNLOAD_ATTEMPTS 下载artifacts的尝试次数 RESTORE_CACHE_ATTEMPTS 重建缓存的尝试次数 #基础实例 variables: GET_SOURCES_ATTEMPTS: 3
你可以在全局 variables 模块中设置,也可以在单个job的 variables 模块中设置。
Shallow cloning 你可以通过 GIT_DEPTH 来指定抓取或克隆的深度。它可浅层的克隆仓库,这可以显著加速具有大量提交和旧的大型二进制文件的仓库的克隆。这个设置的值会传递给 git fetch 和 git clone 。
注意:如果设置depth=1,并且有一个jobs队列或者是重试jobs,则jobs可能会失败。
由于Git抓取和克隆是基于一个REF,例如分支的名称,所以Runner不能指定克隆一个commit SHA。如果队列中有多个jobs,或者您正在重试旧的job,则需要测试的提交应该在克隆的Git历史记录中存在。设置 GIT_DEPTH 太小的值可能会导致无法运行哪些旧的commits。在job日志中可以查看 unresolved reference 。你应该考虑设置 GIT_DEPTH 为一个更大的值。 当 GIT_DEPTH 只置了部分存在的记录时,哪些依赖于 git describe 的jobs也许不能正确的工作。只抓取或克隆最后的3次commits:
variables: GIT_DEPTH: "3"
Hidden keys Key 是以 . 开始的,GitLab CI 将不会处理它。你可以使用这个功能来忽略jobs,或者用Special YAML features 转换隐藏键为模版。在下面这个例子中 .key_name 将会被忽略:
.key_name: script: - rake spec
Hidden keys 可以是像普通CI jobs一样的哈希值,但你也可以利用special YAMLfeatures来使用不同类型的结构。使用special YAML features 像anchors( & ),aliases( * )和map merging( << ),这将使您可以大大降低 .gitlabci.yml 的复杂性。
Anchors YAML有个方便的功能称为”锚”,它可以让你轻松的在文档中复制内容。Anchors可用于复制/继承属性,并且是使用hidden keys来提供模版的完美示例。 下面这个例子使用了anchors和map merging。它将会创建两个jobs, test1 和 test2 ,该jobs将集成 .job_template 的参数,每个job都自定义脚本
.job_template: &job_definition # Hidden key that defines an anchor named 'job_definition' image: ruby:2.1 services: - postgres - redis test1: <<: *job_definition # Merge the contents of the 'job_definition' alias script: - test1 project test2: <<: *job_definition # Merge the contents of the 'job_definition' alias script: - test2 project
& 在anchor的名称( job_definition )前设置, << 表示"merge the given hash into the current one", * 包括命名的anchor( job_definition )。扩展版本如下:
.job_template: image: ruby:2.1 services: - postgres - redis test1: #'job_definition' alias (别名效果如下) image: ruby:2.1 services: - postgres - redis script: - test1 project test2: image: ruby:2.1 services: - postgres - redis script: - test2 project
让我们来看另外一个例子。这一次我们将用anchors来定义两个服务。两个服务会创建两个job, test:postgres 和 test:mysql ,他们会在 .job_template 中共享定义的 script 指令,以及分别在 postgres_services 和 .mysql_services 中定义的 service 指令:
.job_template: &job_definition script: - test project .postgres_services: services: &postgres_definition - postgres - ruby test:postgres: <<: *job_definition services: *postgres_definition #扩展版本如下: .job_template: script: - test project .postgres_services: services: - postgres - ruby test:postgres: script: - test project services: - postgres - ruby
Triggers:可用于强制使用API调用重建特定分支,tag或commits。
pages:是一个特殊的job,用于将静态的内容上传到GitLab,可用于为您的网站提供服务。它有特殊的语法,因此必须满足以下两个要求:
1.任何静态内容必须放在 public/ 目录下
2.artifacts 必须定义在 public/ 目录下 下面的这个例子是将所有文件从项目根目录移动到 public/ 目录。.public 工作流是 cp ,并且它不会循环复制public/ 本身。
pages: stage: deploy script: - mkdir .public - cp -r * .public - mv .public public artifacts: paths: - public only: - masterSkipping jobs:如果你的commit信息中包含 [ci skip] 或者 [skip ci],不论大小写,那么这个commit将会创建但是jobs也会跳过;
0x03 管道介绍
管道是持续集成、交付和部署的顶级组件是一组分阶段(批处理)执行的工作。同一个阶段中的所有工作都是并行执行的(如果有足够的并发Runners),如果它们全部成功,管道就进入下一个阶段。如果其中一个jobs失败,则下一个阶段不(通常)执行。您可以访问项目的Pipeline选项卡中的管道页面。 在下图中,您可以看到管道由4个阶段组成(build(构建) , test(测试) , staging(分级) , production(生产) ),每个阶段都有一个或多个工作。
1.管道类型
描述:管道分三种,但是通常都使用单一的“管道”来代替所有。人们经常谈论他们,就好像每个都是“管道”一样,但实际上他们只是综合管道的一部分。
CI Pipeline: 在 gitlab-ci.yml 中定义的构建和测试阶段。Deploy Pipeline: 在 .gitlab-ci.yml 中定义的部署阶段,用来通过各种各样的方式将代码部署到服务器: 例如,将代码发布到生成环境Project Pipeline:通过API触发跨项目CI依赖关系,尤其是针对微服务,但也适用于复杂的构建依赖关系: 例如,api-> front-end,ce / ee-> omnibus。开发工作流程:
1. Branch Flow(例如,dev,qa,分期,生产等不同分支) 2. Trunk-based Flow (例如,功能分支、单一的主分支和可能带有标签的发布) 3. 基于分叉的流程(例如,来自fork的合并请求)
2.名词介绍
工作:可以在 .gitlab-ci.yml 文件中定义。不要与 build 工作或 build 阶段混淆。
定义管道:在 .gitlab-ci.yml 中通过指定阶段运行的作业来定义管道。
查看管道状态: 您可以在项目的 Pipeline选项卡下找到当前和历史运行的管道 。点击管道将显示为该管道运行的作业。
查看工作状态: 当您访问单个管道时,您可以看到该管道的相关作业。点击单个作业会显示该作业运行历史,并允许您取消作业,重试作业或清除作业运行日志。
查看工作失败的原因: 当管道发生故障或允许失败时,有几个地方可以快速检查失败的原因:
在管道图中 出现在管道图中。在管道小部件中 出现在合并请求和提交页面中。在工作视图中 出现在全局和详细的工作视图中。管道图:管道可以是复杂的结构,具有许多顺序和平行的作业。为了让您更容易看到发生了什么,它可以查看单个管道及其状态。
管道图可以通过两种不同的方式显示,具体取决于您所处的页面。当您在单个管道页面上时,可以找到显示每个阶段作业名称的常规管道图。其次有管道迷你图,占用更少的空间,并且可以快速浏览所有作业是成果还是失败。管道迷你图可以在您访问以下,页面时找到: 管道索引页面 / 提交页面 /合并请求页面将相似的工作分组: 如果你有许多类似的工作,你的管道图会变得很长,很难阅读。出于这个原因,类似的工作可以自动组合在一起。如果作业名称以某种格式命名,则它们将在常规管线图(非迷你图)中折叠为一个组。如果您没有看到重试或取消按钮,您就知道管道将作业已经合并分组了。将鼠标悬停在上面会显示分组作业的数量。可以点击展开它们。
基本要求是需使用以下方式的一种将两个数字分隔开(可以互换使用)(查看下面的示例):空间 / 斜线( / ) / 冒号( : ) 注意: 更准确地说,它使用这个正则表达式: d+[s:/]+d+s* 。
#这些工作将通过从左到右比较这两个数字来进行排序。通常第一个是索引,第二个是总数。 #例如,以下作业将被分组在一个名为的作业下 test : test 0 3 => test test 1 3 => test test 2 3 => test #以下作业将被分组在下列作业中 test ruby : test 1:2 ruby => test ruby test 2:2 ruby => test ruby #下列作业也将被归类在一个作业中 test ruby : 1/3 test ruby => test ruby 2/3 test ruby => test ruby 3/3 test ruby => test ruby
手动操作:手动操作允许您在使用CI中的指定作业之前需要手动操作。整个管道可以自动运行,但实际部署到生产需要点击。(在GitLab 8.15中引入)
作业排序:常规管道图在单个管道页面中,作业按名称排序。
多项目管道图:可在GitLab Premium 、GitLab Sliver或更高级版本中使用。
徽章:管道状态和测试范围内报告徽章可用。您可以在管道设置页面找到它们各自的链接。
受保护分行的安全:管道在受保护的分支上执行时,将执行严格的安全模型,只有在允许用户合并或推送 特定分支时,才允许在受保护的分支上执行以下操作 :
运行手动管道(使用Web UI或Pipelines API)运行预定的管道使用触发器运行管道在现有管线上触发手动操作重试/取消现有作业(使用Web UI或Pipelines API)标记为受保护的变量仅适用于在受保护分支上运行的作业,从而避免不受信任的用户无意中访问敏感信息,如部署凭证和令牌。标记为受保护的Runners只能保护分支机构运行的作业,避免不受信任的代码要在保护runner和保存部署键被意外地触发或其他凭证执行。为了确保打算在受保护的跑步者上执行的工作不会使用常规runner,必须对其进行相应标记。Q:如何计算管道持续时间?
管道的总运行时间将排除重试和待处理(排队)时间。我们可以将这个问题缩减为寻找周期的联合。 所以每个工作都会被表示为 Period ,其中包括 Period#first 工作开始 Period#last 时和工作完成时。一个简单的例子是: A(1,3) B(2,4) C(6,7)
这里A从1开始,到3结束。B从2开始,并到4结束。C从6开始,到7结束。视觉上它可以被看作:
0 1 2 3 4 5 6 7 AAAAAAA BBBBBBB CCCC #A,B和C的联合将是(1,4)和(6,7),因此总运行时间应该是: (4 - 1) + (7 - 6) => 4
0x04 Variables
描述:当GitLab CI 中接受到一个job后,Runner就开始准备构建环境。开始设置预定义的变量(环境变量)和用户自定义的变量。 官方文档:https://docs.gitlab.com/ce/ci/variables/README.html
variables 的执行顺序
变量可以被重写,并且是按照下面的顺序进行执行:
1.触发变量或计划管道变量。2.项目级变量或受保护变量。3.组级变量或受保护变量。4.YAML 定义的作业级变量。5.YAML 定义的全局变量。6.部署变量。7.预定义的环境变量。举个例子,如果你定义了私有变量 API_TOKEN=secure ,并且在 .gitlab-ci.yml 中定义了 API_TOKEN=yaml,那么私有变量 API_TOKEN 的值将是 secure ,因为secret variables的优先级较高。
Predefined variables(Environment variables): 有部分预定义的环境变量仅仅只能在最小版本的GitLab Runner中使用。
注意:从GitLab 9.0 开始,部分变量已经不提倡使用。请查看9.0 Renaming部分来查找他们的替代变量。强烈建议使用新的变量,我们也会在将来的GitLab版本中将他们移除。
Variable GitLab Runner Description CI all 0.4 标识该job是在CI环境中执行 CI_COMMIT_REF_NAME 9.0 all 用于构建项目的分支或tag名称 CI_COMMIT_REF_SLUG 9.0 all 先将 $CI_COMMIT_REF_NAME 的值转换成小写,最 大不能超过63个字节,然后把除了 0-9 和 a-z 的其他字符转换成 - 。在URLs和域名名称中使用。 CI_COMMIT_SHA 9.0 all commit的版本号 CI_COMMIT_TAG 9.0 0.5 commit的tag名称。只有创建了tags才会出现。 CI_DEBUG_TRACE 9.0 1.7 debug tracing开启时才生效 CI_ENVIRONMENT_NAME 8.15 all job的环境名称 CI_ENVIRONMENT_SLUG 8.15 all 环境名称的简化版本,适用于DNS,URLs, Kubernetes labels等 CI_JOB_ID 9.0 all GItLab CI内部调用job的一个唯一ID CI_JOB_MANUAL 8.12 all 表示job启用的标识 CI_JOB_NAME 9.0 0.5 .gitlab-ci.yml 中定义的job的名称 CI_JOB_STAGE 9.0 0.5 .gitlab-ci.yml 中定义的stage的名称 CI_JOB_TOKEN 9.0 1.2 用于同GitLab容器仓库验证的token CI_REPOSITORY_URL 9.0 all git仓库地址,用于克隆 CI_RUNNER_DESCRIPTION 8.10 0.5 GitLab中存储的Runner描述 CI_RUNNER_ID 8.10 0.5 Runner所使用的唯一ID CI_RUNNER_TAGS 8.10 0.5 Runner定义的tags CI_PIPELINE_ID 8.10 0.5 GitLab CI 在内部使用的当前pipeline的唯一ID CI_PIPELINE_TRIGGERED all all 用于指示该job被触发的标识 CI_PROJECT_DIR all all 仓库克隆的完整地址和job允许的完整地址 CI_PROJECT_ID all all GitLab CI在内部使用的当前项目的唯一ID CI_PROJECT_NAME 8.10 0.5 当前正在构建的项目名称(事实上是项目文件夹 名称) CI_PROJECT_NAMESPACE 8.10 0.5 当前正在构建的项目命名空间(用户名或者是组 名称) CI_PROJECT_PATH 8.10 0.5 命名空间加项目名称 CI_PROJECT_PATH_SLUG 9.3 all $CI_PROJECT_PATH 小写字母、除了 0-9 和 a-z的其他字母都替换成 - 。用于地址和域名名称。 CI_PROJECT_URL 8.10 0.5 项目的访问地址(http形式) CI_REGISTRY 8.10 0.5 如果启用了Container Registry,则返回GitLab的Container Registry的地址 CI_REGISTRY_IMAGE 8.10 0.5 如果为项目启用了Container Registry,它将返回与特定项目相关联的注册表的地址 CI_REGISTRY_PASSWORD 9.0 all 用于push containers到GitLab的Container Registry 的密码 CI_REGISTRY_USER 9.0 all用于push containers到GItLab的Container Registry 的用户名 CI_SERVER all all 标记该job是在CI环境中执行 CI_SERVER_NAME all all 用于协调job的CI服务器名称 CI_SERVER_REVisioN all all 用于调度job的GitLab修订版 CI_SERVER_VERSION all all 用于调度job的GItLab版本 ARTIFACT_DOWNLOAD_ATTEMPTS 8.15 1.9 尝试运行下载artifacts的job的次数 GET_SOURCES_ATTEMPTS 8.15 1.9 尝试运行获取源的job次数 GITLAB_CI all all 用于指示该job是在GItLab CI环境中运行 GITLAB_USER_ID 8.12 all 开启该job的用户ID GITLAB_USER_EMAIL 8.12 all 开启该job的用户邮箱 RESTORE_CACHE_ATTEMPTS 8.15 1.9 尝试运行存储缓存的job的次数
作业脚本中环境变量的语法:所有变量都设置为生成环境中的环境变量,并且它们可通过用于访问此类变量的正常方法访问。在大多数情况下,或用于执行作业脚本。
job_name: script: #bash 中访问环境变量,使用 () 前缀变量名称:$ - echo $CI_JOB_ID #Windows 批处理中的环境变量,可以使用 () 环绕变量:% - echo %CI_JOB_ID% #命令列出所有环境变量 jobs: script: - echo "#Gitlab Variable:" - export
比如上面内置的预定义变量以及Runner主机环境变量默认值如下:
$ echo "#Gitlab Variable:" #Gitlab Variable: $ export declare -x CATALINA_HOME="/app/tomcat-9.0.22" declare -x CI="true" declare -x CI_API_V4_URL="http://gitlab.weiyigeek.top/api/v4" declare -x CI_BUILDS_DIR="/home/gitlab-runner/builds" declare -x CI_BUILD_BEFORE_SHA="5bd0b719c43f196c26e3563948834cc863410950" declare -x CI_BUILD_ID="86" declare -x CI_BUILD_NAME="jobs" declare -x CI_BUILD_REF="b022716f52d7905d392bb090acafa358adde2bd6" declare -x CI_BUILD_REF_NAME="master" declare -x CI_BUILD_REF_SLUG="master" declare -x CI_BUILD_STAGE="test" declare -x CI_BUILD_TOKEN="[MASKED]" declare -x CI_COMMIT_BEFORE_SHA="5bd0b719c43f196c26e3563948834cc863410950" declare -x CI_COMMIT_BRANCH="master" declare -x CI_COMMIT_DESCRIPTION="" declare -x CI_COMMIT_MESSAGE="更新 .gitlab-ci.yml" declare -x CI_COMMIT_REF_NAME="master" declare -x CI_COMMIT_REF_PROTECTED="true" declare -x CI_COMMIT_REF_SLUG="master" declare -x CI_COMMIT_SHA="b022716f52d7905d392bb090acafa358adde2bd6" declare -x CI_COMMIT_SHORT_SHA="b022716f" declare -x CI_COMMIT_TITLE="更新 .gitlab-ci.yml" declare -x CI_CONCURRENT_ID="0" declare -x CI_CONCURRENT_PROJECT_ID="0" declare -x CI_CONFIG_PATH=".gitlab-ci.yml" declare -x CI_DEFAULT_BRANCH="master" declare -x CI_JOB_ID="86" declare -x CI_JOB_NAME="jobs" declare -x CI_JOB_STAGE="test" declare -x CI_JOB_TOKEN="[MASKED]" declare -x CI_JOB_URL="http://gitlab.weiyigeek.top/newproject/secopsdev/-/jobs/86" declare -x CI_node_TOTAL="1" declare -x CI_PAGES_DOMAIN="example.com" declare -x CI_PAGES_URL="http://newproject.example.com/secopsdev" declare -x CI_PIPELINE_ID="32" declare -x CI_PIPELINE_IID="11" declare -x CI_PIPELINE_SOURCE="push" declare -x CI_PIPELINE_URL="http://gitlab.weiyigeek.top/newproject/secopsdev/pipelines/32" declare -x CI_PROJECT_DIR="/home/gitlab-runner/builds/5UmJ5uEC/0/newproject/secopsdev" declare -x CI_PROJECT_ID="1" declare -x CI_PROJECT_NAME="secopsdev" declare -x CI_PROJECT_NAMESPACE="newproject" declare -x CI_PROJECT_PATH="newproject/secopsdev" declare -x CI_PROJECT_PATH_SLUG="newproject-secopsdev" declare -x CI_PROJECT_REPOSITORY_LANGUAGES="" declare -x CI_PROJECT_TITLE="SecOpsDev" declare -x CI_PROJECT_URL="http://gitlab.weiyigeek.top/newproject/secopsdev" declare -x CI_PROJECT_VISIBILITY="private" declare -x CI_REGISTRY_PASSWORD="[MASKED]" declare -x CI_REGISTRY_USER="gitlab-ci-token" declare -x CI_REPOSITORY_URL="http://gitlab-ci-token:[MASKED]@gitlab.weiyigeek.top/newproject/secopsdev.git" declare -x CI_RUNNER_DESCRIPTION="TestRunner" declare -x CI_RUNNER_EXECUTABLE_ARCH="linux/amd64" declare -x CI_RUNNER_ID="1" declare -x CI_RUNNER_REVISION="4c96e5ad" declare -x CI_RUNNER_SHORT_TOKEN="5UmJ5uEC" declare -x CI_RUNNER_TAGS="TestRunner" declare -x CI_RUNNER_VERSION="12.9.0" declare -x CI_SERVER="yes" declare -x CI_SERVER_HOST="gitlab.weiyigeek.top" declare -x CI_SERVER_NAME="GitLab" declare -x CI_SERVER_PORT="80" declare -x CI_SERVER_PROTOCOL="http" declare -x CI_SERVER_REVISION="ac5568eb5d8" declare -x CI_SERVER_URL="http://gitlab.weiyigeek.top" declare -x CI_SERVER_VERSION="12.9.2" declare -x CI_SERVER_VERSION_MAJOR="12" declare -x CI_SERVER_VERSION_MINOR="9" declare -x CI_SERVER_VERSION_PATCH="2" declare -x CI_SHARED_ENVIRONMENT="true" declare -x CLASSPATH=".:/usr/local/jdk1.8.0_211/lib/dt.jar:/usr/local/jdk1.8.0_211/lib/tools.jar:%CATALINA_HOME%/lib/servlet-api.jar" declare -x CONFIG_FILE="/etc/gitlab-runner/config.toml" declare -x CVS_RSH="ssh" declare -x FF_CMD_DISABLE_DELAYED_ERROR_LEVEL_EXPANSION="false" declare -x FF_NETWORK_PER_BUILD="false" declare -x FF_USE_LEGACY_BUILDS_DIR_FOR_DOCKER="false" declare -x FF_USE_LEGACY_KUBERNETES_EXECUTION_STRATEGY="true" declare -x FF_USE_LEGACY_VOLUMES_MOUNTING_ORDER="false" declare -x GITLAB_CI="true" declare -x GITLAB_FEATURES="" declare -x GITLAB_USER_EMAIL="admin@example.com" declare -x GITLAB_USER_ID="1" declare -x GITLAB_USER_LOGIN="root" declare -x GITLAB_USER_NAME="Administrator" declare -x HISTCONTROL="ignoredups" declare -x HISTSIZE="1000" declare -x HOME="/home/gitlab-runner" declare -x HOSTNAME="initiator" declare -x JAVA_HOME="/usr/local/jdk1.8.0_211" declare -x JRE_HOME="/usr/local/jdk1.8.0_211/jre" declare -x LANG="zh_CN.UTF-8" declare -x LESSOPEN="||/usr/bin/lesspipe.sh %s" declare -x LOGNAME="gitlab-runner" declare -x MAIL="/var/spool/mail/gitlab-runner" declare -x MYSQL_HOME="/usr/local/mysql-5.7.24" declare -x OLDPWD="/home/gitlab-runner" declare -x PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/local/jdk1.8.0_211/bin:/usr/local/mysql-5.7.24/bin:/home/gitlab-runner/.local/bin:/home/gitlab-runner/bin" declare -x PWD="/home/gitlab-runner/builds/5UmJ5uEC/0/newproject/secopsdev" declare -x SHELL="/bin/bash" declare -x SHLVL="2" declare -x TOMCAT_HOME="/app/tomcat-9.0.22" declare -x USER="gitlab-runner" declare -x XDG_RUNTIME_DIR="/run/user/996" declare -x XDG_SESSION_ID="c383" declare -x url="blog.wieyigeek.top"
9.0 Renaming:根据GitLab的命名规则,在9.0以后将从 build 术语转到 job CI变量中,并且已经被重命名。
8.x name 9.0+ name CI_BUILD_ID -> CI_JOB_ID CI_BUILD_REF -> CI_COMMIT_SHA CI_BUILD_TAG -> CI_COMMIT_TAG CI_BUILD_REF_NAME -> CI_COMMIT_REF_NAME CI_BUILD_REF_SLUG -> CI_COMMIT_REF_SLUG CI_BUILD_NAME -> CI_JOB_NAME CI_BUILD_STAGE -> CI_JOB_STAGE CI_BUILD_REPO -> CI_REPOSITORY_URL CI_BUILD_TRIGGERED -> CI_PIPELINE_TRIGGERED CI_BUILD_MANUAL -> CI_JOB_MANUAL CI_BUILD_TOKEN -> CI_JOB_TOKEN
gitlab-ci.yaml defined variables:注意:此功能要求GitLab Runner 0.5或者更高版本,并且GitLab CI 7.14或者更高版本;
GitLab CI允许你向 .gitlab-ci.yml 中添加变量,这个变量在构建环境中设置。因此,变量将保存在存储中,他们用于存储非敏感的项目配置,例如: RAILS_ENV 或者 DATABASE_URL 。
YAML中定义的变量也将应用到所有创建的服务容器中,因此可以对它进行微调。
#举个例子,如果将变量设置为全局以下(不是在一个作业中),则它将用于所有执行的命令脚本中: variables: DATABASE_URL: "postgres://postgres@postgres/my_database" #变量可以定义为全局,同时也可以定义为job级别。若要关闭作业中的全局定义变量,请定义一个空hash: job_name: variables: {} #您可以在变量定义中使用其他变量(或使用$$将其转义): variables: LS_CMD: 'ls $FLAGS $$TMP_DIR' FLAGS: '-al' script: - 'eval $LS_CMD' # will execute 'ls -al $TMP_DIR'
执行结果:
jobs: variables: LS_CMD: 'whoami' USERNAME: 'weiyigeek' script: - "echo -e"# $LS_CMD $USERNAME"" # will execute 'ls -al $TMP_DIR' - 'eval $LS_CMD' $ echo -e "> $LS_CMD # collapsed multi-line command # whoami weiyigeek $ eval $LS_CMD gitlab-runner
Secret variables:安全变量
GitLab CI允许你在构建环境过程中设置项目的私有变量。私有变量存储在仓库(.gitlab-ci.yml)中,并被安全的传递给GitLab Runner,使其在构建环境中可用。建议使用该方法存储诸如密码、秘钥和凭据之类的东西。可用通过Settings ➔ Pipelines来增加私有变量,通过Settings ➔ Pipelines找到的模块称之为私有变量。一次设置,所有的后续pipeline是都可以使用它们。Protected secret variables
私有变量可以被保护。每当一个私有变量被保护时,它只会安全的传递到在受保护的分支或受保护的标签上运行的pipeline。其他的pipeline将不会得到受保护的变量可用通过Settings ➔ Pipelines来增加私有变量,通过Settings ➔ Pipelines找到的模块称之为私有变量,然后点击Protected。Deploment variables
负责部署配置的项目服务可以定义在构建环境中设置自己的变量。这些变量只定义用于部署job。请参考您正在使用的项目服务的文档,以了解他们定义的变量。Debug tracing:启用调试跟踪
默认情况下,GitLab Runner会隐藏了处理job时正在做的大部分细节。这种行为使job跟踪很短,并且防止秘密泄露到跟踪中,除非您的脚本将他们输出到屏幕中。
如果job没有按照预期的运行,这也会让问题查找变得更加困难;在这种情况下,你可以在 .gitlab-ci.yml 中开启调试记录。它需要GitLab Runner v1.7版本以上,此功能可启用shell的执行记录,从而产生详细的job记录,列出所有执行的命令,设置变量等。
#设置 CI_DEBUG_TRACE 变量的值为 true 来开启调试记录。 job_name: variables: CI_DEBUG_TRACE: "true"
WeiyiGeek.Debug
警告:启用调试跟踪可能会严重的安全隐患。输出内容将包含所有的私有变量和其他的隐私!输出的内容将被上传到GitLab服务器并且将会在job记录中明显体现。
加载全部内容