gitlab-ci.yml 语法

发布于 2020-11-08  836 次阅读


综述

详细内容

job

job 是 yml 的基础组件
job 是在指定条件的 stage 中的执行任务
顶层的 job 可以是任意名称,但是必须至少包含一个 script 条目
job 的数量无限制

job 名称不能够是一下保留词:

image
services
stages
types
before_script
after_script
variables
cache
include

job配置参数

job 由一下参数的行为组成

script - runner 执行的脚本
after_script - job 之后需要执行的脚本
allow_failure - 允许job失败,失败的job 不会对 commit status 造成影响
artifacts - job 成功后需要添加的文件和目录
artifacts:paths, artifacts:exclude, artifacts:expose_as, artifacts:name, artifacts:untracked, artifacts:when, artifacts:expire_in, artifacts:reports

before_script - job 开始之前的脚本

cache - 在随后job执行前需要缓存的文件和目录
cache:paths, cache:key, cache:untracked, and cache:policy

coverage - 给定job的代码覆盖率设置

dependencies - 限制将哪些arrifact传给job

environment - job deploy 的名称
environment:name, environment:url, environment:on_stop, environment:auto_stop_in and environment:action

except - jobs 为创建时的限制
except:refs, except:kubernetes, except:variables, and except:changes.

extends - job 继承的配置条目

image - docker image
image:name and image:entrypoint

include - job 包含的 external yaml
include:local, include:file, include:template, and include:remote.

interruptible - 当有新的run时,本次run 可以取消

only - jobs创建的限制
only:refs, only:kubernetes, only:variables, and only:changes.

pages - 当使用 GitLab Pages 时上传 job 结果

parallel - 可以并行的job个数

release - 指定runner生成 release 对象

resource_group - 限制job并发

retry - 运行job失败重复运行次数

rules - 评估和决定job选择属性的条件列表,在有only/except时可以不设

services - 使用docker services images
services:name, services:alias, services:entrypoint, and services:command.

stage - 定义job阶段
tags - job使用的runner
timeout - job 的超时
trigger - 定义流水线trigger
variables - job级的变量定义

when - 何时运行job
when:manual and when:delayed.

全局参数

以下参数可以在全局区(default block)定义

image - 
service - 
before_script -
after_script -
tags -
cache -
artifacts -
retry -
timeout -
interruptible -

全局定义的参数仅在job内未定义该参数时生效

inherit

inherit 在 gitlab 12.9 引入
可以用来设置job 内对全局default以及varibles的继承

inherit:
  default: [parameter1, parameter2]
  variables: [VARIABLE1, VARIABLE2]

inherit:
  default:
    - parameter1
    - parameter2
  variables:
    - VARIABLE1
    - VARIABLE2 

stages

stages 用于定义job 的阶段,即job属于全局的哪个阶段

stages:
  - build
  - test
  - deploy

stages:
  - build
  - test
  - deploy

job 0:
  stage: .pre
  script: make something useful before build stage

job 1:
  stage: build
  script: make build dependencies

job 2:
  stage: build
  script: make build artifacts

job 3:
  stage: test
  script: make test

job 4:
  stage: deploy
  script: make deploy

job 5:
  stage: .post
  script: make something useful at the end of pipeline

workflow

workflow 从 gitlab 12.5 引入
顶层关键词 workflow 关系到管线的创建,它接受单一 rules
rules 关键词类似于 在jobs内定义的rules
这是管线早期创建的动态配置

workflow:
  rules:
    - if: CI_COMMIT_MESSAGE =~ /-wip/
      when: never
    - if: 'CI_PIPELINE_SOURCE == "push"'


workflow:
  rules:
    - if: 'CI_PIPELINE_SOURCE == "schedule"'
      when: never
    - if: '$CI_PIPELINE_SOURCE == "push"'
      when: never
    - when: always

在 gitlab 13.0 开始提供了 workflow:rules 模板,可以通过 include 包含

include:
  - template: 'Workflows/Branch-Pipelines.gitlab-ci.yml'

include:
  - template: 'Workflows/MergeRequest-Pipelines.gitlab-ci.yml'

include

include 可以用于包含其他yaml文件,包括 local , file , remote ,template

include:
  - local: '/templates/.gitlab-ci-template.yml'

include: '.gitlab-ci-production.yml'

include:
  - project: 'my-group/my-project'
    file: '/templates/.gitlab-ci-template.yml'

include:
  - project: 'my-group/my-project'
    ref: master
    file: '/templates/.gitlab-ci-template.yml'

  - project: 'my-group/my-project'
    ref: v1.0.0
    file: '/templates/.gitlab-ci-template.yml'

  - project: 'my-group/my-project'
    ref: 787123b47f14b552955ca2786bc9542ae66fee5b  # Git SHA
    file: '/templates/.gitlab-ci-template.yml'

include:
  - remote: 'https://gitlab.com/awesome-project/raw/master/.gitlab-ci-template.yml'

include:
  - template: Auto-DevOps.gitlab-ci.yml

include:
  - template: Android-Fastlane.gitlab-ci.yml
  - template: Auto-DevOps.gitlab-ci.yml

image

docker image

script

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

job:
  script: "bundle exec rspec"

job:
  script:
    - false || exit_code=?
    - if [exit_code -ne 0 ]; then echo "Previous command failed"; fi;

default:
  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

extends

在gitlab 11.3 引入,用于继承job

.tests:
  script: rake test
  stage: test
  only:
    refs:
      - branches

rspec:
  extends: .tests
  script: rake rspec
  only:
    variables:
      - $RSPEC

rules

docker build:
  script: docker build -t my-image:CI_COMMIT_REF_SLUG .
  rules:
    - if: 'CI_COMMIT_BRANCH == "master"'
      when: delayed
      start_in: '3 hours'
      allow_failure: true

job:
  script: "echo Hello, Rules!"
  rules:
    - if: 'CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ /^feature/ &&CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"'
      when: always
    - if: 'CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ /^feature/'
      when: manual
      allow_failure: true
    - if: 'CI_MERGE_REQUEST_SOURCE_BRANCH_NAME'  # Checking for the presence 

only/except

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

test:
  script: npm run test
  only:
    refs:
      - master
      - schedules
    variables:
      - $CI_COMMIT_MESSAGE =~ /run-end-to-end-tests/
    kubernetes: active

needs

gitlab 12.6引入
artifact 通过 artifact:true 控制下载与否
dependencies 依然有效

通过needs 可以跨项目下载artifact,从12.7 开始

build_job:
  stage: build
  script:
    - ls -lhR
  needs:
    - project: namespace/group/project-name
      job: build-1
      ref: master
      artifacts: true

needs 也可以同管线下载

tags

windows job:
  stage:
    - build
  tags:
    - windows
  script:
    - echo Hello, %USERNAME%!

osx job:
  stage:
    - build
  tags:
    - osx
  script:
    - echo "Hello, $USER!"

allow_failure

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 用于在job特定状态时执行判断

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

environment

enviroment 用于job部署到指定环境

deploy_prod:
  stage: deploy
  script:
    - echo "Deploy to production server"
  environment:
    name: production
    url: https://example.com
  when: manual
  only:
    - master

cache

rspec:
  script: test
  cache:
    paths:
      - binaries/*.apk
      - .config

artifacts

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

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

artifacts:
  paths:
    - binaries/
  exclude:
    - binaries/**/*.o

test:
  script: ["echo 'test' > file.txt"]
  artifacts:
    expose_as: 'artifact 1'
    paths: ['file.txt']

job:
  artifacts:
    name: "$CI_JOB_NAME"
    paths:
      - binaries/

artifacts:
  untracked: true
  exclude:
    - "*.txt"

job:
  artifacts:
    when: on_failure

job:
  artifacts:
    expire_in: 1 week

depencies

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

coverage

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

retry

test:
  script: rspec
  retry: 2

timeout

build:
  script: build.sh
  timeout: 3 hours 30 minutes

test:
  script: rspec
  timeout: 3h 30m

parallel

test:
  script: rspec
  parallel: 5

deploystacks:
  stage: deploy
  script:
    - bin/deploy
  parallel:
    matrix:
      - PROVIDER: aws
        STACK:
          - monitoring
          - app1
          - app2
      - PROVIDER: ovh
        STACK: [monitoring, backup, app]
      - PROVIDER: [gcp, vultr]
        STACK: [data, processing]

deploystacks: [aws, monitoring]
deploystacks: [aws, app1]
deploystacks: [aws, app2]
deploystacks: [ovh, monitoring]
deploystacks: [ovh, backup]
deploystacks: [ovh, app]
deploystacks: [gcp, data]
deploystacks: [gcp, processing]
deploystacks: [vultr, data]
deploystacks: [vultr, processing]

triigger

rspec:
  stage: test
  script: bundle exec rspec

staging:
  stage: deploy
  trigger:
    project: my/deployment
    branch: stable

interruptible

stages:
  - stage1
  - stage2
  - stage3

step-1:
  stage: stage1
  script:
    - echo "Can be canceled."
  interruptible: true

step-2:
  stage: stage2
  script:
    - echo "Can not be canceled."

step-3:
  stage: stage3
  script:
    - echo "Because step-2 can not be canceled, this step will never be canceled, even though set as interruptible."
  interruptible: true

resource_group

deploy-to-production:
  script: deploy
  resource_group: production

release

13.2

release_job:
  stage: release
  image: registry.gitlab.com/gitlab-org/release-cli:latest
  rules:
    - if: CI_COMMIT_TAG                  # Run this job when a tag is created manually
  script:
    - echo 'running release_job'
  release:
    name: 'ReleaseCI_COMMIT_TAG'
    description: 'Created using the release-cli EXTRA_DESCRIPTION'  #EXTRA_DESCRIPTION must be defined
    tag_name: 'CI_COMMIT_TAG'                                       # elsewhere in the pipeline.
    ref: 'CI_COMMIT_TAG'
    milestones:
      - 'm1'
      - 'm2'
      - 'm3'
    released_at: '2020-07-15T08:00:00Z'  # Optional, will auto generate if not defined, or can use a variable.

prepare_job:
  stage: prepare                                              # This stage must run before the release stage
  rules:
    - if: CI_COMMIT_TAG
      when: never                                             # Do not run this job when a tag is created manually
    - if:CI_COMMIT_BRANCH == CI_DEFAULT_BRANCH             # Run this job when commits are pushed or merged to the default branch
  script:
    - echo "EXTRA_DESCRIPTION=some message" >> variables.env  # Generate the EXTRA_DESCRIPTION and TAG environment variables
    - echo "TAG=v(cat VERSION)" >> variables.env             # and append to the variables.env file
  artifacts:
    reports:
      dotenv: variables.env                                   # Use artifacts:reports:dotenv to expose the variables to other jobs

release_job:
  stage: release
  image: registry.gitlab.com/gitlab-org/release-cli:latest
  needs:
    - job: prepare_job
      artifacts: true
  rules:
    - if: CI_COMMIT_TAG
      when: never                                  # Do not run this job when a tag is created manually
    - if:CI_COMMIT_BRANCH == CI_DEFAULT_BRANCH  # Run this job when commits are pushed or merged to the default branch
  script:
    - echo 'running release_job forTAG'
  release:
    name: 'Release TAG'
    description: 'Created using the release-cliEXTRA_DESCRIPTION'  # EXTRA_DESCRIPTION and theTAG
    tag_name: 'TAG'                                                 # variables must be defined elsewhere
    ref: 'CI_COMMIT_SHA'                                            # in the pipeline. For example, in the
    milestones:                                                      # prepare_job
      - 'm1'
      - 'm2'
      - 'm3'
    released_at: '2020-07-15T08:00:00Z'  # Optional, will auto generate if not defined, or can use a variable.

secrets

pages

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

varibles

variables:
  DATABASE_URL: "postgres://postgres@postgres/my_database"

variables:
  GIT_STRATEGY: clone

variables:
  GIT_STRATEGY: fetch

variables:
  GIT_STRATEGY: clone
  GIT_CHECKOUT: "false"
script:
  - git checkout -B master origin/master
  - git merge $CI_COMMIT_SHA

variables:
  GIT_CLEAN_FLAGS: -ffdx -e cache/
script:
  - ls -al cache/

variables:
  GIT_FETCH_EXTRA_FLAGS: --prune
script:
  - ls -al cache/

anchors

.job_template: &job_definition  # Hidden key that defines an anchor named 'job_definition'
  image: ruby:2.6
  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

.something_before: &something_before
  - echo 'something before'

.something_after: &something_after
  - echo 'something after'
  - echo 'another thing after'

job_name:
  before_script:
    - *something_before
  script:
    - echo 'this is the script'
  after_script:
    - *something_after

.something: &something
  - echo 'something'

job_name:
  script:
    - *something
    - echo 'this is the script'

# global variables
variables: &global-variables
  SAMPLE_VARIABLE: sample_variable_value
  ANOTHER_SAMPLE_VARIABLE: another_sample_variable_value

# a job that must set the GIT_STRATEGY variable, yet depend on global variables
job_no_git_strategy:
  stage: cleanup
  variables:
    <<: *global-variables
    GIT_STRATEGY: none
  script: echo $SAMPLE_VARIABLE

朝闻道,夕死可矣