gitlab-ci配置详解(二)

27

jobs(任务)

.gitlab-ci.yml允许用户创建无数多个任务.但是每个任务必须有一个独一无二的名字,但不能是以下保留字.一个任务是由一列参数定义的,来决定任务的工作内容和行为.

job_name:
  # 要跑的脚本或命令列表
  script:
    - rake spec
    - coverage
  # pipelines阶段
  stage: test
  # 只针对哪个分支
  only:
    - master
  # 除了哪个分支以外
  except:
    - develop
  # 指定哪些runner适用该job
  tags:
    - ruby
    - postgres
  # 是否容错
  allow_failure: true
关键字 是否必须 描述
script 必须 定义Runner需要执行的脚本或命令
image 非必须 需要使用的docker镜像,请查阅该文档
services 非必须 定义了所需的docker服务,请查阅该文档
stage 非必须 定义了工作的场景阶段,默认是test
type 非必须 stage的别名,不赞成使用
variables 非必须 在job级别上定义的变量
only 非必须 定义哪些git引用(分支)适用该job
except 非必须 定义了哪些git引用(分支)不适用该job
tags 非必须 定义了哪些runner适用该job(runner在创建时会要求用户输入标签名来代表该runner)
allow_failure 非必须 允许任务失败,但是如果失败,将不会改变提交状态
when 非必须 定义job什么时候能被执行,可以是on_success,on_failure,always或者manual
dependencies 非必须 定义了该job依赖哪一个job,如果设置该项,你可以通过artifacts设置
artifacts 非必须 所谓工件。。就是在依赖项之间传递的东西,类似cache,但原理与cache不同
cache 非必须 定义需要被缓存的文件、文件夹列表
before_script 非必须 覆盖在根元素上定义的before_script
after_script 非必须 覆盖在根元素上定义的after_script
environment 非必须 定义让job完成部署的环境名称
retry 非必须 定义job失败后的自动重试次数

script

script是一段由Runner执行的shell脚本,例如:

job:
  script: "bundle exec rspec"

这个参数也可以使用数组包涵好几条命令:

job:
  script:
    - uname -a
    - bundle exec rspec

有些时候,script命令需要被单引号或者双引号所包裹。举个例子,命令中包涵冒号的时候,该命令需要被引号所包裹,这样YAML解析器才知道该命令语句不是“key: value”语法的一部分。当命令中包涵以下字符时需要注意打引号:: { } [ ] , & * # ? | - < > = ! % @ `

stage

stage指定一组job在不同场景阶段执行。在相同stage下的job(任务)将会被并行的执行。关于stage更多用法的描述,请查看stages

only and except(简易说明)

onlyexcept两个参数说明了job什么时候将会被创建:

  1. only定义了job需要执行的所在分支或者标签
  2. except定义了job不会执行的所在分支或者标签

以下是这两个参数的几条用法规则:

  1. onlyexcept如果都存在在一个job声明中,则所需引用将会被onlyexcept所定义的分支过滤.
  2. onlyexcept允许使用正则
  3. onlyexcept允许使用指定仓库地址,但是不forks仓库

此外,onlyexcept允许使用以下一些特殊关键字:

描述
branches 当一个分支被push上来
tags 当一个打了tag的分支被push上来
api 当一个pipline被piplines api所触发调起,详见piplines api
external 当使用了GitLab以外的CI服务
pipelines 针对多项目触发器而言,当使用CI_JOB_TOKEN并使用gitlab所提供的api创建多个pipelines的时候
pushes 当pipeline被用户的git push操作所触发的时候
schedules 针对预定好的pipline而言(每日构建一类~,具体请看链接
triggers 用token创建piplines的时候
web 在GitLab页面上Pipelines标签页下,你按了run pipline的时候

下面的例子,job将会只在issue-开头的refs下执行,反之则其他所有分支被跳过:

job:
  # use regexp
  only:
    - /^issue-.*$/
  # use special keyword
  except:
    - branches

在这个例子中,job只会在打了tag的分支,或者被api所触发,或者每日构建任务上运行,

job:
  # use special keywords
  only:
    - tags
    - triggers
    - schedules

如果指定了仓库路径,该任务将会在指定仓库路径被push或者其他操作的时候被运行,但是不会forks,(注,仓库路径只能是父仓库,也就是你指定了仓库里远程仓库的那个仓库地址~)

job:
  only:
    - branches@gitlab-org/gitlab-ce
  except:
    - master@gitlab-org/gitlab-ce

上面这个例子的job将会在父仓库gitlab-org/gitlab-ce的非master分支有提交时运行.有点拗口

only and except(复杂版本)

从GitLab10引入的
这是个测试特性,可能在没有通知的情况下更改该特性

自从GitLab10.0以后,我们可以配置更加复杂的job策略。

GitLab现在同时支持简单和复杂的job策略定义。现在我们甚至可以使用数组或者对象的配置方案来配置我们的job策略。

在复杂的定义下,现在有两个参数可用,refskubernetes.refs的策略等同于设置一般的only/except配置,但是kubernetes只有一个可选值,active.

请看下面的例子,该job只会在计划被触发时或者master分支被push时触发,并且先决条件是kubernetes服务是活跃的(你启用了kubernetes服务作为执行器,相关请看gitlab ci runner的文档,ce用户一般用求不到)。

job:
  only:
    refs:
      - master
      - schedules
    kubernetes: active

variables

在job级别允许用户定义变量,他的工作方式和全局级别的变量定义相同,不过该变量作用域仅限于当前job。

当您再job级别使用了variables定义变量,它将会覆盖YAML设置的全局变量和预定义的变量,如果你要在job级别屏蔽全局定义的变量,你可以用空对象覆盖它:

job_name:
    variables: {}

job变量的优先级在variables文档中有所阐述

tags

tags这个参数是用来选择允许哪些runners来执行该jub的。

当你初始化Runner并注册一个Runner的时候,你被要求为Runner指定一个或多个标签,例如我的一个Runner被注册为test1

job:
    tags:
        - test1
        - ruby

上面的声明将会保证该job将会被标签上有test1ruby的runner所执行。如果没有就不执行

allow_failure

allow_failure被用于当你想允许job失败而不阻塞剩下的CI套件执行的时候,失败的job不会影响到commit状态(pipelines执行完会在commit上标记失败或成功状态,但是不会阻止commit提交)

当allow_failure为true,并且job失败了,pipline将会置绿或者置成功显示,但是你会在commit页面或者job页面看到一条“CI build passed with warnings”的警告信息哈。这样用户就能注意到失败并采取其他措施。

在下面的例子中,job1和job2将会并行执行(事实告诉我们其实还是顺序执行),不过如果job1失败了,整个pipeline不会停止,并且会流转到下一个场景阶段继续执行:

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

上面的例子实测,job1显示警告,job2通过,job3通过

when

when参数是确定该job在失败或者没失败的时候执行不执行的参数。

when支持以下几个值之一:

  1. on_success 只有在之前场景执行的所有作业成功的时候才执行当前job,这个就是默认值,我们用最小配置的时候他默认就是这个值,所以失败的时候pipeline会停止执行后续任务
  2. on_failure 只有在之前场景执行的任务中至少有一个失败的时候才执行
  3. always 不管之前场景阶段的状态,总是执行
  4. manual ~手动执行job的时候触发(webui上点的)。请阅读manual action

下面是例子:

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. 在pipeline最后一步,不管前面是失败或者成功,执行cleanup_job
  3. 允许你在GitLabUI上手动执行deploy_job

manual actions

自GitLab8.10引入,Blocking manual actions自GitLab9.0引入,Protected actions自GitLab9.2引入

手动操作是一类特殊的job类型,该类型不会自定执行;只有用户在gitlab ui上点击执行按钮的时候才会被触发。手动执行操作可以在pipeline页面,build场景,environment页面,和deployment页面上找到按钮按

其中一个场景就是,你在生产部署页面摁部署按钮。

阅读更多,请移步environments documentation.

手动操作可以是可选的或者是阻塞的。阻塞的手动操作将会阻塞定义了手动操作的场景步骤。这个时候你可以看到pipline页面上有个play按钮,如果你按play按钮,可以恢复pipeline的执行(一个类比,手动触发部署行为)。

当一个pipeline被阻塞了,那么即使pipeline commit状态为succeeds,你也不能执行merge操作(不懂先看下面一段话,当你设置不允许失败的时候,整个pipline被阻塞,在提交分支merge的时候,pipeline由于状态为manual,不能merge),被阻塞的pipelines也有一个特别的状态,叫做manual

手动操作默认是非阻塞的,如果你想让手动操作阻塞,你必须为job设置allow_failure:false(不设置默认为true,无法阻塞pipeline)

可选操作的状态是无法改变pipeline整体状态的,只有阻塞操作可以

手动操作被认为是白箱操作,所以当用户想要触发操作的时候,是有权限保护的。换句话说,用户如果想要触发手动操作,你必须有合并到当前分支的权限

environment

注意:

environment是用于定义一个job(作业)部署到某个具名的环境,如果environment被指定,但是没有叫该名的environment存在,一个新的environment将会被自动创建(实际上这个环境并不是指向真实环境,设置这条会将相应job显示在CI面板,environments视图上,然后可以反复操作相关job)

在下面这个最简单的表单里,environment关键字可以被设置为:

deploy_to_production:
  stage: deploy
  script: git push production HEAD:master
  environment:
    name: production

在上面这个例子中,deploy_to_production作业将会执行部署操作部署到production环境

environment:name

注意

  • 在GitLab8.11中引入
  • 8.11之前,你可以environment: environmentName这样设置环境名,但现在推荐你在name关键字下设置环境名
  • name参数可以使用任何已定义的CI变量,包括预定义变量,秘密变量和yaml文件定义的变量,但是你不能使用script脚本中定义的变量。

environmen名可以包括以下内容

  • letters字母
  • digits数字
  • spaces空格
  • -
  • _
  • /
  • $
  • {
  • }

通用的环境名是qa,staging和production,不过你也可以设置任何你喜欢的名字

除了直接在environment后面定义环境名,你也可以使用name关键字来定义环境名,将其当做一个分离的值来设置

deploy to production:
  stage: deploy
  script: git push production HEAD:master
  #environment: production
  environment:
    name: production

environment:url

注意:

  • 自GitLab8.11引入
  • 在8.11之前,这个url只能在GitLabUi上设置,现在推荐你在yaml文件中书写
  • url参数同样能使用任何CI的变量,除了script之中定义的以外

这是个可选选项,设置该选项,在gitLab ui上将会展示一个去往该url的链接按钮。

在下面的例子里,如果job做完了,gitlab将会在merge request页面或者environments或者deployments页面创建一个按钮,按钮指向https://prod.example.com

deploy to production:
  stage: deploy
  script: git push production HEAD:master
  environment:
    name: production
    url: https://prod.example.com

environment:on_stop

注意:

  • 在GitLab8.13中引入
  • 从8.14开始,当你在environment中设置了中断操作,gitlab将会在相关的分支被删除的时候自动触发中断对应行为

关闭environments可以通过在environment中定义关键字on_stop来实现。他指向了一个具名的job,该job的environment:action设置为stop

请参阅environment:action章节查看更多

environment:action

GitLab8.13引入

action关键字和on_stop关键字相关,定义在job的environment中,用于响应关闭环境的操作

下面是一个实例:

review_app:
  stage: deploy
  script: make deploy-app
  environment:
    name: review
    on_stop: stop_review_app

stop_review_app:
  stage: deploy
  script: make delete-app
  when: manual
  environment:
    name: review
    action: stop

在上面的例子中,我们建立了一个review_app并部署到review环境,并且我们在on_stop下同样定义了一个新的job名为stop_review_app。一旦review_app作业成功完成,ci将可以在手动操作的时候触发stop_review_app的任务,在这个例子中,我们使用when来达到手动触发停止review app的功能。

stop_review_app作业需要结合以下关键字去定义:

  1. when
  2. environment:name
  3. environment:action
  4. stage (必须和写on_stop那个job定义的相同)

dynamic environments

动态环境

注意:

  • 该特性自GitLab8.12和GITlAB Runner1.6被引入
  • $CI_ENVIRONMENT_SLUG变量自 GitLab8.15引入
  • name url参数可以是任何定义的CI变量,除了script里定义的以外
deploy as review app:
  stage: deploy
  script: make deploy
  environment:
    name: review/$CI_COMMIT_REF_NAME
    url: https://$CI_ENVIRONMENT_SLUG.example.com/

deploy as review app job会被标明为部署(deployment页面可见,10版里没有貌似)并且动态创建一个review/&dollar;CI_COMMIT_REF_NAME环境, &dollar;CI_COMMIT_REF_NAME是由Runner设置的环境变量(分支名). &dollar;CI_ENVIRONMENT_SLUG变量是基于enviroment:name的, 但是会做url安全处理. 在该例子中, 如果deploy as review app在分支pow下被执行, 凑出来的访问链接是这样的https://review-pow.example.com/.

你可以通过该访问链接来访问你的程序,这以为这个app的服务主机已经配置好了(???)

想了解更多可以查看review-apps-nginx该示例

artifacts

注意:

  • 自从gitlab Runner 0.7.0引入,并且windows平台不适用
  • windows平台的支持是从版本1.0.0开始的
  • 在Gitlab9.2之前,缓存将会在artifacts操作之后被重新储存
  • 在此之后,缓存将会在artifacts操作之前被重新储存
  • 目前来说,不是所有解析器(shell, docker什么的那些)都支持artifacts,所以乖乖用cache
  • 除非job作业成功完成,要不然artifacts默认不会被收集的

artifacts 被用于在job作业成功后将制定列表里的文件或文件夹附加到job上,传递给下一个job,如果要在两个job之间传递artifacts,你必须设置dependencies,下面有几个例子

传递所有binaries和.config:

artifacts:
  paths:
  - binaries/
  - .config

传递所有git没有追踪的文件

artifacts:
  untracked: true

传递binaries文件夹里所有内容和git没有追踪的文件

artifacts:
  untracked: true
  paths:
  - binaries/

禁止传递来的artifact:

job:
  stage: build
  script: make build
  dependencies: []

有时候用户可能只需要为打过标签的发行版创建artifacts去避免将临时构建的artifacts传递到生产服务器存储。

那么这时候我们可以只为打tags的行为创建artifacts:

default-job:
  script:
    - mvn test -U
  except:
    - tags

release-job:
  script:
    - mvn package -U
  artifacts:
    paths:
    - target/*.war
  only:
    - tags

最终artifacts将会在job执行完毕后送到GitLab ui前台来,你可以直接下载它(在tag页,在details页,在pipeline页的下载按钮上都会出现)。

artifacts:name

GitLab8.6 GitLab Runner1.1.0引入

name指令允许你对artifacts压缩包重命名,你可以为每个artifect压缩包都指定一个特别的名字,这样对你在gitlab上下载artifect的压缩包有用
.artifacts:name的值可以使用任何预定义的变量,它的默认值是artifacts,所以如果你不设置,在gitlab上就会看到artifacts.zip的下载名

示例

创建一个压缩包命名为当前job名

job:
  artifacts:
    name: "$CI_JOB_NAME"

创建一个压缩包,命名为分支或者标签名,并且只包含未追踪的文件

job:
   artifacts:
     name: "$CI_COMMIT_REF_NAME"
     untracked: true

创建一个压缩包,命名为“job名_分支名”

job:
  artifacts:
    name: "${CI_JOB_NAME}_${CI_COMMIT_REF_NAME}"
    untracked: true

创建一个压缩包,命名为“场景阶段名_分支名”

job:
  artifacts:
    name: "${CI_JOB_STAGE}_${CI_COMMIT_REF_NAME}"
    untracked: true

如果你用的是 Windows batch脚本,请用%替换$号

如果你用的是powershell跑脚本,你需要使用&dollar;env:替换$

artifacts:when

GitLab 8.9 and GitLab Runner v1.3.0引入

artifacts:when用于job失败或者未失败时使用

artifacts:when能设置以下值:

  1. on_success 这个值是默认的,当job成功时上传artifacts
  2. on_failure 当job执行失败时,上床artifacts
  3. always 不管失败与否,都上传

示例配置

当失败时上传artifacts

job:
  artifacts:
    when: on_failure

artifacts:expire_in

GitLab 8.9 and GitLab Runner v1.3.0中引入

artifacts:expire_in 用于设置artifacts上传包的失效时间. 如果不设置,artifacts的打包是永远存在于gitlab上的. expire_in 允许你指定artifacts过期时间, 在该期间内,artifacts包将储存在gitLab上.

如果设置了过期时间,你可以在job页面找到一个keep按钮,按了以后可以覆盖过期时间,让artifacts永远存在.

过期之后,用户将无法访问到artifacts包,artifacts将会在每小时执行的定时任务里被清除。

expire_in 的值要表示经过的时间. 下面是一些例子:

  • '3 mins 4 sec'
  • '2 hrs 20 min'
  • '2h20min'
  • '6 mos 1 day'
  • '47 yrs 6 mos and 4d'
  • '3 weeks and 2 days'

示例配置

设置artifacts一星期过期

job:
  artifacts:
    expire_in: 1 week

dependencies

GitLab 8.6 and GitLab Runner v1.1.1中引入

该特性需要和artifacts何用,是用于将artifacts在两个jobs之间(主要是两个不同stage的job之间)传递的(下面几段翻译的巨烂,因为自己没有使用过,不知道到底是啥意思)

注意所有之前的场景状态都是默认传递artifacts的

为了使用该特性,你需要在job上下文中定义dependencies并且列出所有运行本作业之前的作业(包涵artifacts下载设置的 )。你只能在需要传递的job的前一个job(上一个stage状态)里定义。如果你在定义了artifacts的job里或者该job后面的job里定义依赖,runner会扔出一个错误。如果你想阻止下载artifacts,你需要设置一个空数组来跳过下载,当使用dependencies的时候,前一个job不会因为job执行失败或者手动操作的阻塞而报错

在下面的例子里,我们定义了两个job有artifacts,其中一个是build:osx另一个是build:linux,当test:osx的作业被执行的时候,从build:osx来的artifacts会被下载并解压缩出来,同样的事情发生在test:linux和build:linux的artifacts上

deploy job会下载所有的artifacts从所有之前的jobs下,这是由于他所处的stage优先级

build:osx:
  stage: build
  script: make build:osx
  artifacts:
    paths:
    - binaries/

build:linux:
  stage: build
  script: make build:linux
  artifacts:
    paths:
    - binaries/

test:osx:
  stage: test
  script: make test:osx
  dependencies:
  - build:osx

test:linux:
  stage: test
  script: make test:linux
  dependencies:
  - build:linux

deploy:
  stage: deploy
  script: make deploy

在上面一个例子中由于没有使用stages设置pipline场景顺序,所以执行顺序是build - test - deploy按照你的书写顺序来,artifacts被上传到gitlab服务器,在下一个dependencies

before_script and after_script

会复写全局设置

before_script:
- global before script

job:
  # 会执行该句而不执行全局设置
  before_script:
  - execute this instead of global before script
  script:
  - my command
  after_script:
  - execute this after my script

coverage

GitLab 8.17引入

coverage 允许你设置代码覆盖率输出,其值从job的输出获取

其值只能设置正则,所以必须用//包裹来表示正则语句,你必须转移特殊字符.

A simple example:

job1:
  script: rspec
  coverage: '/Code coverage: \d+\.\d+/'

retry

GitLab 9.5引入

retry允许用户设置重试次数。

当job失败,并且配置了,retry,则会在重试次数内进行重试

test:
  script: rspec
  retry: 2

Git Strategy(git策略)

GitLab 8.9 作为实验特性引入,任何时候都可能完全移除该特性,慎用。
GIT_STRATEGY=none需要GitLab Runner 1.7以上版本支持

你可以通过在全局变量设置位置或者job局部变量设置位置来设置GIT_STRATEGY用以获取应用最近更新的代码。如果没有指定,默认的项目设置将会被使用。

该选项有三个可能的值:clone,fetch和none

clone是最慢的选项,如果设置该值,每个job将会都克隆一遍仓库,确保项目工作空间总是原始的正确的。

variables:
  GIT_STRATEGY: clone

fetch是更快的操作选项,因为他重用了项目的工作空间(如果没有的话,会去clone), git clean用于撤销上一个job的任何操作,git fetch是用来重新获取上一个job运行到当前job产生的commit

variables:
  GIT_STRATEGY: fetch

none也同样重用了项目空间(但是他会跳过所有git操作,包括如果存在的gitlab runner的预克隆脚本)。其主要用于只是为了操作artifacts的job上(例如depoly部署行为)。此时Git仓库的数据可能是存在的,但它一定不是最新的。所以在设置了none的job里你应该依赖从cache或者artifacts来的数据,而不是仓库数据。

variables:
  GIT_STRATEGY: none

Git Checkout

GitLab Runner 9.3引入

GIT_CHECKOUT变量是和GIT_STRATEGY:clone, GIT_STRATEGY:fetch合用的,用来指定git checkout命令是否需要被执行,如果没有设置GIT_CHECKOUT,那么runner任务将会使用默认值true,也就是每次checkout相应分支。GIT_CHECKOUT可以设置在全局variables上,也可以设置在job的variables上

但是如果这个值被设置为false,runner将会有以下行为:

  • 当做fetch操作的时候,更新仓库并保留当前版本的工作副本
  • 当做clone操作的时候,克隆仓库并保留默认分支的工作副本

如果设置这个值为true,这意味着,runner的clone和fetch策略都会让项目工作区的工作副本更新到最新版本

variables:
  GIT_STRATEGY: clone
  GIT_CHECKOUT: false
script:
  - git checkout master
  - git merge $CI_BUILD_REF_NAME

Git Submodule Strategy

Requires GitLab Runner v1.10+

GIT_SUBMODULE_STRATEGY用于在构建之前控制git子模块用,像GIT_STRATEGY一样,他可以在全局variables里设置,也能在jobs下的variables设置

有三个可选值 none,normal,recursive

  • none默认不引入子模块,和,Runner1.10以前的默认行为一样,也是默认值
  • normal默认只引入第一级子模块,跟下面相等

    git submodule sync
    git submodule update --init
  • recursive意味着递归下载所有子模块,和下面的操作相等

    git submodule sync --recursive
    git submodule update --init --recursive

git策略和git子模块策略只是一种配置糖,你完全可以执行自己的脚本完成相同的操作(git策略的其他选项可以加快作业执行速度什么的,那要看个人需求了。)所以如果你要配置子模块策略,你要保证你项目底下有.gitmodules文件,并配置了以下内容:

  • 公开的仓库http(s) url地址或者
  • 在同一个GitLab服务器上的相对仓库地址,查看git submodules文档

Shallow cloning (浅克隆)

该特性是gitLab8.9引入的实验特性,在未来任何时候都有可能被移除

你可以通过GIT_DEPTH来设置抓取或者克隆深度。这将使得仓库进行浅克隆, 如果你的仓库有特别大量的commits或者仓库好久没更新了,该设置将显著的提高克隆速度。该参数会发送给git fetch和git clone操作(其实就相当于git fetch --depth=xxx, git clone --depth=xxx。但是由于git fetch和git clone是runner在执行job时帮你做的,所以需要此配置。)

注意,如果你的克隆深度设置为1,并且此时你在执行一个队列的job或者重试一个job,你的job作业可能会失败的

由于git抓取和克隆操作是基于一个ref的(例如ref为一个分支名),所以Runners不能直接去克隆一个具体的commit(用sha哈希索引的)。如果在执行队列里有多个job,或者你正在重试执行某个job,那么此时要求你需要job测试的commit必须在克隆的仓库的git历史里可查,要不然会报错的。如果设置的GIT_DEPTH值太小,你可能克隆不到更早一些的commits。此时,你在job日志里会看到一条unresolved reference的日志。这个时候你可能考虑一下,把GIT_DEPTH值设置高一些.

当设置了GIT_DEPTH的时候,由于仓库只呈现一部分git历史,所以一些依赖于git describe的job(那些only: tags的那种)可能无法正常工作

抓取或者克隆最新三条commits:

variables:
  GIT_DEPTH: "3"

Hidden keys(jobs)(job隐藏键名)

自 GitLab 8.6 and GitLab Runner v1.1.1引入

如果你想暂时屏蔽某job作业,而不是直接注释该job定义:

#hidden_job:
#  script:
#    - run test

那么你大可不必全部用#注释掉,你可以在job key名钱加一个点,此时gitlab ci执行到这就不会执行该job了:

.hidden_job:
  script:
    - run test

你可以使用该特性来忽略job,也可以使用YAML的专有特性(语法)来替换隐藏件

Special YAML features (YAML专有特性)

你可以使用YAML的专有语法和特性来定义你的.gitlab-ci.yml,例如(锚点&,别名*,合并数据<<)。通过YAML语法特性可以减轻你的配置的复杂性

阅读更多

Anchors(锚点)

GitLab 8.6 and GitLab Runner v1.1.1引入

YAML有一个名叫‘锚点’的遍历特性,该特性可以让你在文档中方便的复制内容,锚点可以用来复制属性或者继承属性,这里有一个很好的例子,利用锚点和隐藏键来为你的job制作job模板

下面的例子使用了锚点的map数据合并,该例子将创建两个job,test1和test2,他们都会继承.job_template的参数,同时他们拥有自己的script定义:

.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

&锚点符号后跟的是设置的锚点名(job_definition),<<符号意思是“合并给与的hash map到当前map里来”,*表示索引被命名的锚点(job_definition),经过解析后,上面的例子将是这样的:

.job_template:
  image: ruby:2.1
  services:
    - postgres
    - redis

test1:
  image: ruby:2.1
  services:
    - postgres
    - redis
  script:
    - test1 project

test2:
  image: ruby:2.1
  services:
    - postgres
    - redis
  script:
    - test2 project

让我们来看看其他例子,这次我们使用锚点来定义两个服务设置的模板,该例子将创建两个job,test:postgres和test:mysql,他们将共享由.job_template定义的script指令,并分别适配由.postgre_services和.mysql_services磨边定义的services指令。

.job_template: &job_definition
  script:
    - test project

.postgres_services:
  services: &postgres_definition
    - postgres
    - ruby

.mysql_services:
  services: &mysql_definition
    - mysql
    - ruby

test:postgres:
  <<: *job_definition
  services: *postgres_definition

test:mysql:
  <<: *job_definition
  services: *mysql_definition

上面的例子展开等同于:

.job_template:
  script:
    - test project

.postgres_services:
  services:
    - postgres
    - ruby

.mysql_services:
  services:
    - mysql
    - ruby

test:postgres:
  script:
    - test project
  services:
    - postgres
    - ruby

test:mysql:
  script:
    - test project
  services:
    - mysql
    - ruby

Triggers(触发器)

Triggers被用于重建特定分支,tag或者commit,他是api触发的。

阅读更多关于Triggers的内容

pages

pages是一类特殊的job,他是设计被用来将你的静态内容(你的web服务需要用到的)上传到GitLab上(类似对应pages分支展示静态页面对吧)。它有指定的特殊语法,下面连个设置是必须的

  1. 任何静态内容都必须放在一个叫public/的文件夹下
  2. 你必须定义artifacts的上传路径为public/

下面的例子简单的将静态资源移动到public文件夹下,为了防止无限执行cp,我们创建一个文件夹为.public,最后将.public改名为public

pages:
  stage: deploy
  script:
  - mkdir .public
  - cp -r * .public
  - mv .public public
  artifacts:
    paths:
    - public
  only:
  - master

阅读更多GitLab Pages user documentation

验证.gitlab-ci.yml的合法性

gitlab都有一个Lint工具,你可以在gitlab实例的/ci/lint下找到链接(ci页面就有)

使用保留关键字

如果你发现你使用某些特定值(例如true或者false)但是发现验证合法性不通过,请尝试使用引号包住他们,或者在你runner下把他们移动到其他地方(例如/bin/true)

跳过job

如果你的commit信息包涵[ci skip]或者[skip ci],不论大消息,这个commit将会被创建,但是job会被跳过

官方例子

Visit the examples README to see a list of examples using GitLab CI with various languages.

gitlab-ci配置详解(一)
gitlab-ci配置详解(二)

资料

centos7简单安装gitlab-ce/ee(官网quick start)
GitLab简明安装指南
GitLab设置stmp发件
postfix mail command not find
gitLab修改默认端口
GitLab使用已有的nginx服务
GitLab-CI与GitLab-Runner
GitLab-Runner官方文档
基于Gitlab CI搭建持续集成环境
如何汉化GitLab
非GitLab集成包手装GitLab


如果觉得我的文章对你有用,请随意赞赏

你可能感兴趣的

木槿 · 2018-01-09

想请教下 runner 执行完一个 shell 脚本后如何判断运行结果是成功还是失败,我想在 runner 中对提交的代码进行代码风格检查,想在页面能看到检查是成功还是失败,谢谢。

回复

0

ci 在linux的runner是根据echo $?的命令返回码来确认的,如果script里面有命令的返回码为非0,则这个job就是失败的.不会再执行script的下一条命令.

逍遥91 · 2018-03-06
逍遥91 · 2018-03-06

dependencies 字段,我验证了一下,确认了以下2点:

  1. 如果job1 有artifacts , job2 执行在job1之后,默认会自动下载job1的artifacts ----这个特性可用于不同jobs传递文件;
  2. 如果想显示指定job2不希望自动下载job1的artifacts,则需要在job2 定义dependencies: [] 空数组来阻止下载. 并且job2 的阶段是在job1之后.

回复

0

对,这个说法是对的,官方也有说明,我写得并不是很详细

geeeger 作者 · 2018-03-14
逍遥91 · 2018-03-06

问个问题: anchors(锚点) ,这里能不能只引用一个字段一部分的值呢? 比如锚点定义script: ---xxx , 然后引用这个锚点时, 我自己也定义了一部分script内容,这样可以不? 我试了好几次,一直报错.

回复

0

这个我也不知道,我没有完整实验过锚点只引用一部分值,貌似官方也没说的样子,或者我看得不仔细?如果可以,我的思路是可以把复用部分写成更小的隐藏键,然后合并入需要的job。抱歉我的经验也不是很多

geeeger 作者 · 2018-03-14
tina鱼 · 2018-12-10

想请假一下 yml中配置了environment 怎么获取这个环境变量呢 我想在项目中引用这个变量作为参数

回复

载入中...