【轉】gitlab CI流水線配置文件.gitlab-ci.yml詳解


目錄

本文講解在 GitLab的漢化與CI持續集成gitlab-runner的配置 的基礎上,對GitLab CI流水線配置文件 .gitlab-ci.yml 進行詳細的介紹。

實驗環境

  • server服務端: 操作系統為CentOS 7.6,IP:192.168.56.14, git:2.16.5。

查看server服務端信息:

[root@server ~]# cat /etc/centos-release CentOS Linux release 7.6.1810 (Core) [root@server ~]# ip a show|grep 192 inet 192.168.56.14/24 brd 192.168.56.255 scope global noprefixroute enp0s3 [root@server ~]# git --version git version 2.16.5 

GitLab用戶信息:

賬號            密碼 root 1234567890 meizhaohui 1234567890 

GitLab WEB網站地址: http://192.168.56.14

之前我們配置的 bluelog 的4#流水線已經 已通過 了:

_images/gitlab_cicd-pipeline_detail.png

可以發現其 build 、Test 、Deploy 三個階段的任務都執行成功!

而流水線執行的具體過程都是由 .gitlab-ci.yml 配置文件定義的,本文詳細講解 .gitlab-ci.yml 配置文件的使用。

GitLab CI介紹

  • GitLab提交持續集成服務,當你在項目根目錄中添加 .gitlab-ci.yml 文件,並配置項目的運行器( GitLab Runner ),那么后續的每次提交都會觸發CI流水線( pipeline )的執行。
  • .gitlab-ci.yml 文件告訴運行器需要做哪些事情,默認情況下,流水線有 build 、test 、deploy 三個階段,即 構建 、測試 、部署 ,未被使用的階段將會被自動忽略。
  • 如果一切運行正常(沒有非零返回值),您將獲得與提交相關聯的漂亮綠色復選標記(如下圖所示)。這樣可以在查看代碼之前輕松查看提交是否導致任何測試失敗。
_images/gitlab_cicd_green_checkmark.png
  • 大多數項目使用GitLab的CI服務來運行測試套件,以便開發人員在破壞某些內容時可以立即獲得反饋。使用持續交付和持續部署將測試代碼自動部署到模擬環境和生產環境的趨勢越來越明顯。
  • 由於將 .gitlab-ci.yml 文件存放在倉庫中進行版本控制,使用單一的配置文件來控制流水線,具有讀訪問權限的每個人都可以查看內容,從而使其更有吸引力地改進和查看構建腳本。舊的版本也能構建成功,forks項目也容易使用CI,分支可以有不同的流水線和作業。
  • .gitlab-ci.yml 定義每個項目的流水線的結構和順序,由以下兩個因素決定:
  • GiTlab Runner運行器使用的執行器( executor ),執行器常用的 Shell 、 Docker 、Kubernets , 我們當前僅使用 Shell 執行器,后續再使用其他執行器。
  • 遇到進程成功或失敗時等條件時做出的決定。
  • 可以在 Getting started with GitLab CI/CD 查看到流水線的簡單示例。
  • 可以在 GitLab CI/CD Examples 查看更多的流水線示例。
  • 在流水線腳本中可以使用預定義的全局變量,詳細可查看 GitLab CI/CD Variables 。
  • 企業級的 .gitlab-ci.yml 示例可查看 https://gitlab.com/gitlab-org/gitlab-ce/blob/master/.gitlab-ci.yml 。
  • Job作業是 .gitlab-ci.yml 文件的基本元素,每個作業至少有 script 子句,在流水線中可以定義任意多個作業。
  • 每個作業必須具有唯一的名稱,但有一些保留的關鍵字不能用作作業名稱,保留關鍵字( reserved keywords )有 image 、 services 、 stages 、 types 、 before_script 、 after_script 、 variables 、 cache 。

.gitlab-ci.yml 配置參數

關鍵字 描述
script 必須參數,運行器需要執行的腳本
image 使用Docker image鏡像
services 使用Docker services鏡像
before_script 作業執行前需要執行的命令
after_script 作業執行后需要執行的命令
stages 定義流水線所有的階段
stage 定義作業所處流水線的階段(默認test階段)
only 限制作業在什么時候創建
except 限制作業在什么時候不創建
tags 作用使用的Runner運行器的標簽列表
allow_failure 允許作業失敗,失敗的作業不影響提交的狀態
when 什么時候運行作業
environment 作用部署的環境名稱
cache 指定需要在job之間緩存的文件或目錄
artifacts 歸檔文件列表,指定成功后應附加到job的文件和目錄的列表
dependencies 當前作業依賴的其他作業,你可以使用依賴作業的歸檔文件
coverage 作業的代碼覆蓋率
retry 作業失敗時,可以自動執行多少次
parallel 指定並行運行的作業實例
trigger 定義下游流水線的觸發器
include 作業加載其他YAML文件
extends 控制實體從哪里繼承
pages 上傳GitLab Pages的結果
retry 作業失敗時,可以自動執行多少次
variables 定義環境變量

參數詳解

script

script 是作業中唯一必須的關鍵字參數,是運行器需要執行的腳本,如:

build1: script: - echo "Do your build here" - uname -a 

表示build1作業需要執行的命令是輸出”Do your build here”。

Warning

Sometimes, script commands will need to be wrapped in single or double quotes. For example, commands that contain a colon (:) need to be wrapped in quotes so that the YAML parser knows to interpret the whole thing as a string rather than a “key: value” pair. Be careful when using special characters: :, {, }, [, ], ,, &, *, #, ?, |, -, <, >, =, !, %, @, `. 即使用冒號時應使用引號包裹起來,使用特殊字符時需要特別注意!!!注意如果要輸出冒號字符,冒號后面不能緊接空格!!!

image

image 指定使用Docker鏡像。如 iamge:name ,暫時忽略。

services

services 指定使用Docker鏡像服務。如 services:name ,暫時忽略。

before_script

before_script 用於定義在所有作業之前需要執行的命令,比如更新代碼、安裝依賴、打印調試信息之類的事情。

示例:

before_script: - echo "Before script section" - echo "For example you might run an update here or install a build dependency" - echo "Or perhaps you might print out some debugging details" 

after_script

after_script 用於定義在所有作業(即使失敗)之后需要執行的命令,比如清空工作空間。

示例:

after_script: - echo "After script section" - echo "For example you might do some cleanup here" 

Important

  • before_script和script在一個上下文中是串行執行的,after_script是獨立執行的,即after_script與before_script/script的上下文環境不同。

  • after_script會將當前工作目錄設置為默認值。

  • 由於after_script是分離的上下文,在after_script中無法看到在before_script和script中所做的修改:

    • 在before_script和script中的命名別名、導出變量,對after_script不可見;
    • before_script和script在工作樹之外安裝的軟件,對after_script不可見。
  • 你可以在作業中定義before_script,after_script,也可以將其定義為頂級元素,定義為頂級元素將為每一個任務都執行相應階段的腳本或命令。作業級會覆蓋全局級的定義。

示例:

before_script: - echo "Before script section" - echo "For example you might run an update here or install a build dependency" - echo "Or perhaps you might print out some debugging details" after_script: - echo "After script section" - echo "For example you might do some cleanup here" build1: stage: build before_script: - echo "Before script in build stage that overwrited the globally defined before_script" - echo "Install cloc:A tool to count lines of code in various languages from a given directory." - yum install cloc -y after_script: - echo "After script in build stage that overwrited the globally defined after_script" - cloc --version - cloc . script: - echo "Do your build here" - cloc --version - cloc . tags: - bluelog 

將修改上傳提交,查看作業build1的控制台輸出:

_images/job_before_script_overwrited_global_before_script.png  _images/job_after_script_overwrited_global_after_script.png

可以發現build1作業的 before_script 和 after_script 將全局的 before_script 和 after_script 覆蓋了。

stages

stages 定義流水線全局可使用的階段,階段允許有靈活的多級管道,階段元素的排序定義了作業執行的順序。

  • 相同 stage 階段的作業並行運行。
  • 默認情況下,上一階段的作業全部運行成功后才執行下一階段的作業。
  • 默認有三個階段, build 、test 、deploy 三個階段,即 構建 、測試 、部署 。
  • 如果一個作業未定義 stage 階段,則作業使用 test 測試階段。
  • 默認情況下,任何一個前置的作業失敗了,commit提交會標記為failed並且下一個stages的作業都不會執行。

stage

stage 定義流水線中每個作業所處的階段,處於相同階段的作業並行執行。

示例:

# This file is a template, and might need editing before it works on your project.
# see https://docs.gitlab.com/ce/ci/yaml/README.html for all available options before_script: - echo "Before script section" - echo "For example you might run an update here or install a build dependency" - echo "Or perhaps you might print out some debugging details" after_script: - echo "After script section" - echo "For example you might do some cleanup here" stages: - build - code_check - test - deploy build1: stage: build before_script: - echo "Before script in build stage that overwrited the globally defined before_script" - echo "Install cloc:A tool to count lines of code in various languages from a given directory." - yum install cloc -y after_script: - echo "After script in build stage that overwrited the globally defined after_script" - cloc --version - cloc . script: - echo "Do your build here" - cloc --version - cloc . tags: - bluelog find Bugs: stage: code_check script: - echo "Use Flake8 to check python code" - pip install flake8 - flake8 --version - flake8 . tags: - bluelog test1: stage: test script: - echo "Do a test here" - echo "For example run a test suite" tags: - bluelog test2: stage: test script: - echo "Do another parallel test here" - echo "For example run a lint test" tags: - bluelog 

我們增加一個 code_check 階段,該階段有一個作業 find Bugs ,該作業主要是先安裝Flake8,然后使用Flake8對Python代碼進行規范檢查。

_images/job_code_check_failed.png

由於Flake8檢查到了Python代碼中的缺陷,導致find Bugs作業失敗!這樣可以控制開發人員提交有壞味道的代碼到倉庫中。

另外,在上一個流水線中,Test階段的作業test1和test2是並行執行的,如下圖所示:

_images/test_jobs_are_executed_in_parallel.png

本次(pipeline #7)流水線由於在作業 find Bugs 檢查不通過,導致整個流水線運行失敗,后續的作業不會執行:

_images/code_check_failed_no_jobs_of_further_stage_are_executed.png

Attention

默認情況下,GitLab Runner運行器每次只執行一個作業,只有當滿足以下條件之一時,才會真正的並行執行:

  • 作業運行在不同的運行器上;
  • 你修改了運行器的 concurrent 設置,默認情況下 concurrent 1 。

only 和 except

only 和 except 用於在創建作業時對作業的限制策略。

  • only 定義了哪些分支或標簽(branches and tags)的作業會運行
  • except 定義了哪些分支或標簽(branches and tags)的作業不會運行

下面是策略規則:

  • only 和 except 可同時使用,如果在一個作業中同時定義了 only 和 except ,則同時 only except 進行過濾(注意,不是忽略 except 條件) 。
  • only 和 except 可以使用正則表達式。
  • only 和 except 允許指定用於過濾forks作業的存儲庫路徑。
  • only 和 except 中可以使用特殊的關鍵字,如 branches 、 tags 、 api 、 external 、 pipelines 、 pushes 、 schedules 、 triggers 、 web 、 merge_requests 、 chats 等。

only 和 except 中可以使用特殊的關鍵字:

關鍵字 描述釋義
branches 當一個分支被push上來
tags 當一個打了tag標記的Release被提交時
api 當一個pipline被第二個piplines api所觸發調起(不是觸發器API)
external 當使用了GitLab以外的外部CI服務,如Jenkins
pipelines 針對多項目觸發器而言,當使用CI_JOB_TOKEN, 並使用gitlab所提供的api創建多個pipelines的時候
pushes 當pipeline被用戶的git push操作所觸發的時候
schedules 針對預定好的pipline計划而言(每日構建一類)
triggers 用觸發器token創建piplines的時候
web 在GitLab WEB頁面上Pipelines標簽頁下,按下run pipline的時候
merge_requests 當合並請求創建或更新的時候
chats 當使用GitLab ChatOps 創建作業的時候

在下面這個例子中,job將只會運行以 issue- 開始的refs(分支),然而except中指定分支不能執行,所以這個job將不會執行:

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

匹配模式默認是大小寫敏感的(case-sensitive),使用 i 標志,如 /pattern/i 可以使匹配模式大小寫不敏感:

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

下面這個示例,僅當指定標記的tags的refs引用,或者通過API觸發器的構建、或者流水線計划調度的構建才會運行:

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

倉庫的路徑(repository path)只能用於父級倉庫執行作業,不能用於forks:

job:
  only:
    - branches@gitlab-org/gitlab-ce
  except:
    - master@gitlab-org/gitlab-ce
    - /^release/.*$/@gitlab-org/gitlab-ce

上面這個例子,將會在所有分支執行,但 不會在 master主干以及以release/開頭的分支上執行。

  • 當一個作業沒有定義 only 規則時,其默認為 only: ['branches', 'tags'] 。
  • 如果一個作業沒有定義 except 規則時,則默認 except 規則為空。

下面這個兩個例子是等價的:

job: script: echo 'test' 

轉換后:

job: script: echo 'test' only: ['branches', 'tags'] 

Attention

關於正則表達式使用的說明:

  • 因為 @ 用於表示ref的存儲庫路徑的開頭,所以在正則表達式中匹配包含 @ 字符的ref名稱需要使用十六進制字符代碼 \x40 。
  • 僅標簽和分支名稱才能使用正則表達式匹配,倉庫路徑按字面意義匹配。
  • 如果使用正則表達式匹配標簽或分支名稱,則匹配模式的整個引用部分都是正則表達式。
  • 正則表達式必須以 / 開頭和結尾,即 /regular expressions/ ,因此, issue-/.*/ 不會匹配以 issue- 開頭的標簽或分支。
  • 可以在正則表達式中使用錨點 ^$ ,用來匹配開頭或結尾,如 /^issue-.*$/ 與 /^issue-/ 等價, 但 /issue/ 卻可以匹配名稱為 severe-issues 的分支,所以正則表達式的使用要謹慎!

only 和 except 高級用法

  • only 和 except 支持高級策略,refs 、 variables 、 changes 、 kubernetes 四個關鍵字可以使用。
  • 如果同時使用多個關鍵字,中間的邏輯是 邏輯與AND 。

only:refs/except:refs

  • refs 策略可以使用 only 和 except 基本用法中的關鍵字。

下面這個例子中,deploy作業僅當流水線是計划作業或者在master主干運行:

deploy: only: refs: - master - schedules 

only:kubernetes/except:kubernetes

  • kubernetes 策略僅支持 active 關鍵字。

下面這個例子中,deploy作業僅當kubernetes服務啟動后才會運行:

deploy: only: kubernetes: active 

only:variables/except:variables

  • variables 關鍵字用來定義變量表達式,你可以使用預定義變量、項目、組、環境變量來評估一個作業是否需要創建或運行。

下面這個例子使用了變量表達式:

deploy:
  script: cap staging deploy
  only:
    refs:
      - branches
    variables:
      - $RELEASE == "staging"
      - $STAGING

下面這個例子,會根據提交日志信息來排除某些作業:

end-to-end:
  script: rake test:end-to-end
  except:
    variables:
      - $CI_COMMIT_MESSAGE =~ /skip-end-to-end-tests/

only:changes/except:changes

  • changes 策略表明一個作業只有在使用 git push 事件使文件發生變化時執行。

下面這個例子中,deploy作業僅當流水線是計划作業或者在master主干運行:

docker build:
  script: docker build -t my-image:$CI_COMMIT_REF_SLUG .
  only:
    changes:
      - Dockerfile
      - docker/scripts/*
      - dockerfiles/**/*
      - more_scripts/*.{rb,py,sh}

上面這個例子中,一旦 Dockerfile 文件發生變化,或者 docker/scripts/ 目錄下的文件發生變化,或者 dockerfiles/ 目錄下的文件或目錄發生變化,或者 more_scripts/ 目錄下 rb,py,sh 等腳本文件發生變化時,就會觸發Docker構建。

  • 也可以使用 glob模式匹配 來匹配根目錄下的文件,或者任何目錄下的文件。

如下示例:

test: script: npm run test only: changes: - "*.json" - "**/*.sql" 

Attention

在上面的示例中,glob模式匹配 的字符串需要使用雙引號包裹起來,否則會導致 .gitlab-ci.yml 解析錯誤。

下面這個例子,當md文件發生變化時,會忽略CI作業:

build: script: npm run build except: changes: - "*.md" 

Warning

記錄一下官網說明中使用 change 時需要注意的兩點:

  • Using changes with new branches and tags:When pushing a new branch or a new tag to GitLab, the policy always evaluates to true and GitLab will create a job. This feature is not connected with merge requests yet and, because GitLab is creating pipelines before a user can create a merge request, it is unknown what the target branch is at this point.
  • Using changes with merge_requests:With pipelines for merge requests, it is possible to define a job to be created based on files modified in a merge request.

在合並請求中使用 change 策略:

docker build service one:
  script: docker build -t my-service-one-image:$CI_COMMIT_REF_SLUG .
  only:
    refs:
      - merge_requests
    changes:
      - Dockerfile
      - service-one/**/*

上面這個例子中,一旦合並請求中修改了 Dockerfile 文件或者修改了 service 目錄下的文件,都會觸發Docker構建。

only 和 except 綜合示例

我們將 bluelog 項目的描述和主題進行修改:

_images/project_description_tags.png

並創建三個分支 issue-pylint 、Issue-flake8 和 severe-issues :

_images/project_three_branches.png

剛新增的三個分支,自動繼承了master主干的CI RUNNER,因為Flake8檢查代碼質量沒通過,流水線都失敗了:

_images/project_three_branches_pipeline_failed.png

為了便於測試,將”meizhaohui”賬號設置為 bluelog 項目的主程序員!

現在朝 .gitlab-ci.yml 文件中增加 only 和 except 策略。

匹配 issue- 開頭的分支

創建僅匹配 issue- 開頭的分支:

_images/only_match_startwith_issue.png

可以發現master主干沒有執行 find Bugs 作業:

_images/master_no_find_bugs.png

為了快速測試,我們對對個作業都使用 only 和 except 策略:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# This file is a template, and might need editing before it works on your project.
# see https://docs.gitlab.com/ce/ci/yaml/README.html for all available options before_script: - echo "Before script section" - echo "For example you might run an update here or install a build dependency" - echo "Or perhaps you might print out some debugging details" after_script: - echo "After script section" - echo "For example you might do some cleanup here" stages: - build - code_check - test - deploy build1: stage: build before_script: - echo "Before script in build stage that overwrited the globally defined before_script" - echo "Install cloc:A tool to count lines of code in various languages from a given directory." - yum install cloc -y after_script: - echo "After script in build stage that overwrited the globally defined after_script" - cloc --version # cloc . only:  - /^issue-.*$/ except: - master script: - echo "Do your build here" - cloc --version # - cloc . tags: - bluelog find Bugs: stage: code_check only:  - /^issue-.*$/ except: - branches script: - echo "Use Flake8 to check python code" - pip install flake8 - flake8 --version # - flake8 . tags: - bluelog test1: stage: test only:  - /^issue-.*$/ except: - /issue-pylint/ script: - echo "Do a test here" - echo "For example run a test suite" tags: - bluelog test2: stage: test only:  - /^issue-.*$/ except: - /Issue-flake8/ script: - echo "Do another parallel test here" - echo "For example run a lint test" tags: - bluelog deploy1: stage: deploy only:  - /^issue-.*$/ except: - /severe-issues/ script: - echo "Do your deploy here" tags: - bluelog 

提交后,直接入庫,檢查master主干,並沒有觸發流水線作業。

統計作業流水線作業情況:

分支 流水線 build1 find Bugs test1 test2 deploy1
master 未觸發          
issue-pylint #22 Yes No No Yes Yes
Issue-flake8 未觸發          
severe-issues 未觸發          
_images/gitlab_only_except_pipeline_22.png

解釋上面的流水作業策略:

作業 規則定義 規則解釋
build1 only: /^issue-.*$/ except: master 只在以issue-開頭的分支執行,不在master主干執行
find Bugs only: /^issue-.*$/ except: branches 只在以issue-開頭的分支執行,不在 branches 分支執行, 由於issue-pylint也是分支,所以在issue-pylint中也不會執行find Bugs作業
test1 only: /^issue-.*$/ except: /issue-pylint/ 只在以issue-開頭的分支執行,不在issue-pylint分支執行, 即會在除了issue-pylint分支以外的issue-開頭的分支執行,也即沒有分支執行
test2 only: /^issue-.*$/ except: /Issue-flake8/ 只在以issue-開頭的分支執行,不在Issue-flake8分支執行, 因此可以issue-pylint分支執行
deploy1 only: /^issue-.*$/ except: /severe-issues/ 只在以issue-開頭的分支執行,不在severe-issues分支執行 因此可以issue-pylint分支執行

大小寫不敏感匹配

好,我們再將 only 語法中加入語法大小寫不敏感的 i 標志!再來做一次實驗,看看最終的效果。

加入語法大小寫不敏感的 i 標志:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# This file is a template, and might need editing before it works on your project.
# see https://docs.gitlab.com/ce/ci/yaml/README.html for all available options before_script: - echo "Before script section" - echo "For example you might run an update here or install a build dependency" - echo "Or perhaps you might print out some debugging details" after_script: - echo "After script section" - echo "For example you might do some cleanup here" stages: - build - code_check - test - deploy build1: stage: build before_script: - echo "Before script in build stage that overwrited the globally defined before_script" - echo "Install cloc:A tool to count lines of code in various languages from a given directory." - yum install cloc -y after_script: - echo "After script in build stage that overwrited the globally defined after_script" - cloc --version # cloc . only:  - /^issue-.*$/i except: - master script: - echo "Do your build here" - cloc --version # - cloc . tags: - bluelog find Bugs: stage: code_check only:  - /^issue-.*$/i except: - branches script: - echo "Use Flake8 to check python code" - pip install flake8 - flake8 --version # - flake8 . tags: - bluelog test1: stage: test only:  - /^issue-.*$/i except: - /issue-pylint/ script: - echo "Do a test here" - echo "For example run a test suite" tags: - bluelog test2: stage: test only:  - /^issue-.*$/i except: - /Issue-flake8/ script: - echo "Do another parallel test here" - echo "For example run a lint test" tags: - bluelog deploy1: stage: deploy only:  - /^issue-.*$/i except: - /severe-issues/ script: - echo "Do your deploy here" tags: - bluelog 

預期效果: issue-pylint 和 Issue-flake8 分支會觸發流水線執行,master 主干和 severe-issues 分支不會觸發流水線執行。

統計作業流水線作業情況:

分支 流水線 build1 find Bugs test1 test2 deploy1
master 未觸發          
issue-pylint #23 Yes No No Yes Yes
Issue-flake8 #24 Yes No Yes No Yes
severe-issues 未觸發          

正如我們預期的一樣,issue-pylint 和 Issue-flake8 分支會觸發流水線執行,master 主干和 severe-issues 分支不會觸發流水線執行:

_images/gitlab_only_except_pipeline_23.png  _images/gitlab_only_except_pipeline_24.png

解釋上面的流水作業策略:

作業 規則定義 規則解釋
build1 only: /^issue-.*$/i except: master 只在以issue(不區分大小寫)-開頭的分支執行,不在master主干執行 可以在issue-pylint和Issue-flake8分支執行
find Bugs only: /^issue-.*$/i except: branches 只在以issue(不區分大小寫)-開頭的分支執行,不在 branches 分支執行, 由於issue-pylint也是分支,所以在issue-pylint中也不會執行find Bugs作業
test1 only: /^issue-.*$/i except: /issue-pylint/ 只在以issue(不區分大小寫)-開頭的分支執行,不在issue-pylint分支執行, 即會在除了issue-pylint分支以外的issue-(不區分大小寫)開頭的分支執行, 可以在Issue-flake8分支執行
test2 only: /^issue-.*$/i except: /Issue-flake8/ 只在以issue(不區分大小寫)-開頭的分支執行,不在Issue-flake8分支執行, 因此可以issue-pylint分支執行
deploy1 only: /^issue-.*$/i except: /severe-issues/ 只在以issue(不區分大小寫)-開頭的分支執行,不在severe-issues分支執行 可以在issue-pylint和Issue-flake8分支執行

我們再將 only 語法中將 /^issue-.*$/ 改為 /issue/i !再來做一次實驗,看看最終的效果。

不區分大小寫匹配issue字符:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# This file is a template, and might need editing before it works on your project.
# see https://docs.gitlab.com/ce/ci/yaml/README.html for all available options before_script: - echo "Before script section" - echo "For example you might run an update here or install a build dependency" - echo "Or perhaps you might print out some debugging details" after_script: - echo "After script section" - echo "For example you might do some cleanup here" stages: - build - code_check - test - deploy build1: stage: build before_script: - echo "Before script in build stage that overwrited the globally defined before_script" - echo "Install cloc:A tool to count lines of code in various languages from a given directory." - yum install cloc -y after_script: - echo "After script in build stage that overwrited the globally defined after_script" - cloc --version # cloc . only:  - /issue/i except: - master script: - echo "Do your build here" - cloc --version # - cloc . tags: - bluelog find Bugs: stage: code_check only:  - /issue/i except: - branches script: - echo "Use Flake8 to check python code" - pip install flake8 - flake8 --version # - flake8 . tags: - bluelog test1: stage: test only:  - /issue/i except: - /issue-pylint/ script: - echo "Do a test here" - echo "For example run a test suite" tags: - bluelog test2: stage: test only:  - /issue/i except: - /Issue-flake8/ script: - echo "Do another parallel test here" - echo "For example run a lint test" tags: - bluelog deploy1: stage: deploy only:  - /issue/i except: - /severe-issues/ script: - echo "Do your deploy here" tags: - bluelog 

預期效果:不區分大小寫,issue-pylint 、 Issue-flake8 和 severe-issues 分支分支會觸發流水線執行,master 主干不會觸發流水線執行。

統計作業流水線作業情況:

分支 流水線 build1 find Bugs test1 test2 deploy1
master 未觸發          
issue-pylint #25 Yes No No Yes Yes
Issue-flake8 #26 Yes No Yes No Yes
severe-issues #27 Yes No Yes Yes No

正如我們預期的一樣,issue-pylint 、 Issue-flake8 和 severe-issues 分支會觸發流水線執行,master 主干不會觸發流水線執行:

_images/gitlab_only_except_pipeline_25.png  _images/gitlab_only_except_pipeline_26.png  _images/gitlab_only_except_pipeline_27.png

解釋上面的流水作業策略:

作業 規則定義 規則解釋
build1 only: /issue/i except: master 只在包含issue(不區分大小寫)字符的分支執行,不在master主干執行 因此在issue-pylint、Issue-flake8、severe-issues分支執行
find Bugs only: /issue/i except: branches 只在包含issue(不區分大小寫)字符的分支執行,不在 branches 分支執行, 所以find Bugs作業一直不會執行
test1 only: /issue/i except: /issue-pylint/ 只在包含issue(不區分大小寫)字符的分支執行,不在包含issue-pylint字符的分支 執行,即會在除了issue-pylint分支以外包含issue(不區分大小寫)字符的分支執行, 所以可以在Issue-flake8和severe-issues分支執行
test2 only: /issue/i except: /Issue-flake8/ 只在包含issue(不區分大小寫)字符的分支執行,不在包含issue-flake8字符的分支 執行,即會在除了issue-flake8分支以外包含issue(不區分大小寫)字符的分支執行, 所以可以在issue-pylint和severe-issues分支執行
deploy1 only: /issue/i except: /severe-issues/ 只在包含issue(不區分大小寫)字符的分支執行,不在包含severe-issues字符的分支 執行,即會在除了severe-issues分支以外包含issue(不區分大小寫)字符的分支執行, 所以可以在issue-pylint和Issue-flake8分支執行

git tag打標簽的使用

使用標簽,可以標記提交歷史上的特定點為重要提交。

  • 新建tag

git tag -a v1.0 -m"Release v1.0"

上面的命令我們成功創建了本地一個版本 V1.0 ,並且添加了附注信息 ‘Release 1.0’。

  • 查看tag

git tag

  • 顯示tag附注信息

git show v1.0

  • 提交本地tag到遠程倉庫

git push origin v1.0

  • 提交本地所有tag到遠程倉庫

git push origin --tags

  • 刪除本地tag

git tag -d v1.0

  • 刪除遠程tag

git tag push origin :refs/tags/v1.0`

  • 獲取遠程版本

git fetch origin tag v1.0

僅當tag標簽提交時,才觸發流水線執行

使用標簽,可以標記提交歷史上的特定點為重要提交,可以標記重要版本,如下圖,是GitLab官方的Tag標簽列表:

_images/gitlab_office_tags_list.png

我們將流水線配置文件 .gitlab-ci.yml 修改為以下內容:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# This file is a template, and might need editing before it works on your project.
# see https://docs.gitlab.com/ce/ci/yaml/README.html for all available options before_script: - echo "Before script section" - echo "For example you might run an update here or install a build dependency" - echo "Or perhaps you might print out some debugging details" after_script: - echo "After script section" - echo "For example you might do some cleanup here" stages: - build - code_check - test - deploy build1: stage: build before_script: - echo "Before script in build stage that overwrited the globally defined before_script" - echo "Install cloc:A tool to count lines of code in various languages from a given directory." - yum install cloc -y after_script: - echo "After script in build stage that overwrited the globally defined after_script" - cloc --version # cloc . only:  - tags except: - master script: - echo "Do your build here" - cloc --version # - cloc . tags: - bluelog find Bugs: stage: code_check only:  - tags except: - branches script: - echo "Use Flake8 to check python code" - pip install flake8 - flake8 --version # - flake8 . tags: - bluelog test1: stage: test only:  - tags except: - /issue-pylint/ script: - echo "Do a test here" - echo "For example run a test suite" tags: - bluelog test2: stage: test only:  - tags except: - /Issue-flake8/ script: - echo "Do another parallel test here" - echo "For example run a lint test" tags: - bluelog deploy1: stage: deploy only:  - tags except: - /severe-issues/ script: - echo "Do your deploy here" tags: - bluelog 

查看差異:

$ git diff
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 7f16137..8315eb0 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -28,7 +28,7 @@ build1:
     - cloc --version
     # cloc .
   only:
-    - /^issue-.*$/
+    - tags
   except:
     - master
   script:
@@ -41,7 +41,7 @@ build1:
 find Bugs:
   stage: code_check
   only:
-    - /^issue-.*$/
+    - tags
   except:
     - branches
   script:
@@ -55,7 +55,7 @@ find Bugs:
 test1:
   stage: test
   only:
-    - /^issue-.*$/
+    - tags
   except:
     - /issue-pylint/
   script:
@@ -67,7 +67,7 @@ test1:
 test2:
   stage: test
   only:
-    - /^issue-.*$/
+    - tags
   except:
     - /Issue-flake8/
   script:
@@ -79,7 +79,7 @@ test2:
 deploy1:
   stage: deploy
   only:
-    - /^issue-.*$/
+    - tags
   except:
     - /severe-issues/
   script:

提交:

D:\data\github_tmp\higit\bluelog (master -> origin)
$ git add -A

D:\data\github_tmp\higit\bluelog (master -> origin)
$ git commit -m"測試tag標簽觸發流水線執行"
[master eb9b468] 測試tag標簽觸發流水線執行
 1 file changed, 7 insertions(+), 5 deletions(-)

D:\data\github_tmp\higit\bluelog (master -> origin)
$ git push origin master:master
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 12 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 365 bytes | 365.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0)
To 192.168.56.14:higit/bluelog.git
   1bd46f2..eb9b468  master -> master

查看是否觸發流水線,可以發現沒有觸發流水線執行:

_images/gitlab_submit_tags_no_trigger_pipeline.png

我們給 bluelog 打個 tag 標簽,標簽名稱V0.1:

D:\data\github_tmp\higit\bluelog (master -> origin)
$ git tag v0.1 -m"Release v0.1"

D:\data\github_tmp\higit\bluelog (master -> origin)
$ git tag
v0.1

D:\data\github_tmp\higit\bluelog (master -> origin)
$ git push origin v0.1
Enumerating objects: 1, done.
Counting objects: 100% (1/1), done.
Writing objects: 100% (1/1), 165 bytes | 165.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To 192.168.56.14:higit/bluelog.git
 * [new tag]         v0.1 -> v0.1

可以發現 bluelog 已經生成了一個tag版本:

_images/gitlab_bluelog_tag_v0.1.png

在流水線列表中,也可以看#31號流水線被觸發了,並且標簽是v0.1:

_images/gitlab_bluelog_pipeline_31_with_tag_v0.1.png

使用流水線觸發器觸發流水線執行

我們給 bluelog 項目創建一個流水線觸發器( Trigger ),在項目的 設置 –> CI/CD –> 流水線觸發器 處增加流水線觸發器:

_images/gitlab_bluelog_add_pipeline_trigger_page.png

在”觸發器描述”處填寫”bluelog trigger”,然后點擊”增加觸發器”按鈕,則會新增一個觸發器:

_images/gitlab_bluelog_trigger.png

我們修改 .gitlab-ci.yml 配置文件,將 build1 和 find Bugs 作業設置為僅 triggers 觸發器能夠觸發執行:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# This file is a template, and might need editing before it works on your project.
# see https://docs.gitlab.com/ce/ci/yaml/README.html for all available options before_script: - echo "Before script section" - echo "For example you might run an update here or install a build dependency" - echo "Or perhaps you might print out some debugging details" after_script: - echo "After script section" - echo "For example you might do some cleanup here" stages: - build - code_check - test - deploy build1: stage: build before_script: - echo "Before script in build stage that overwrited the globally defined before_script" - echo "Install cloc:A tool to count lines of code in various languages from a given directory." - yum install cloc -y after_script: - echo "After script in build stage that overwrited the globally defined after_script" - cloc --version # cloc . only:  - triggers script: - echo "Do your build here" - cloc --version # - cloc . tags: - bluelog find Bugs: stage: code_check only:  - triggers script: - echo "Use Flake8 to check python code" - pip install flake8 - flake8 --version # - flake8 . tags: - bluelog test1: stage: test only: - tags except: - /issue-pylint/ script: - echo "Do a test here" - echo "For example run a test suite" tags: - bluelog test2: stage: test only: - tags except: - /Issue-flake8/ script: - echo "Do another parallel test here" - echo "For example run a lint test" tags: - bluelog deploy1: stage: deploy only: - tags except: - /severe-issues/ script: - echo "Do your deploy here" tags: - bluelog 

提交修改:

D:\data\github_tmp\higit\bluelog (master -> origin)
$ git diff
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 657dc5e..921f93e 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -28,9 +28,7 @@ build1:
     - cloc --version
     # cloc .
   only:
-    - tags
-  except:
-    - master
+    - triggers
   script:
     - echo "Do your build here"
     - cloc --version
@@ -41,9 +39,7 @@ build1:
 find Bugs:
   stage: code_check
   only:
-    - tags
-  except:
-    - branches
+    - triggers
   script:
     - echo "Use Flake8 to check python code"
     - pip install flake8

D:\data\github_tmp\higit\bluelog (master -> origin)
$ git add -A

D:\data\github_tmp\higit\bluelog (master -> origin)
$ git commit -m"使用觸發器trigger觸發流水線執行"
[master 57f64a3] 使用觸發器trigger觸發流水線執行
 1 file changed, 2 insertions(+), 6 deletions(-)

D:\data\github_tmp\higit\bluelog (master -> origin)
$ git push origin master:master
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 12 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 361 bytes | 361.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0)
To 192.168.56.14:higit/bluelog.git
   eb9b468..57f64a3  master -> master

檢查發現並沒有觸發流水線的執行:

_images/gitlab_submit_triggers_no_trigger_pipeline.png

我們現在使用 curl 發送請求,觸發流水線觸發器執行:

[root@server ~]# curl -X POST -F token=cf8a32f6f8a583263f6d042e6362d2 -F ref=master http://192.168.56.14/api/v4/projects/2/trigger/pipeline {"id":33,"sha":"57f64a35cad6d069dc62ddc93f0747296383826e","ref":"master","status":"pending","web_url":"http://192.168.56.14/higit/bluelog/pipelines/33","before_sha":"0000000000000000000000000000000000000000","tag":false,"yaml_errors":null,"user":{"id":2,"name":"梅朝輝","username":"meizhaohui","state":"active","avatar_url":"http://192.168.56.14/uploads/-/system/user/avatar/2/avatar.png","web_url":"http://192.168.56.14/meizhaohui"},"created_at":"2019-07-06T22:08:52.761+08:00","updated_at":"2019-07-06T22:08:53.026+08:00","started_at":null,"finished_at":null,"committed_at":null,"duration":null,"coverage":null,"detailed_status":{"icon":"status_pending","text":"等待中","label":"等待中","group":"pending","tooltip":"等待中","has_details":false,"details_path":"/higit/bluelog/pipelines/33","illustration":null,"favicon":"/assets/ci_favicons/favicon_status_pending-5bdf338420e5221ca24353b6bff1c9367189588750632e9a871b7af09ff6a2ae.png"}} 
_images/use_curl_post_gitlab_pipeline_trigger.png

可以發現流水線已經被執行,#33號流水線執行了 build1 和 find Bugs 作業,其他作業並未執行,與我們預期的相同:

_images/use_curl_post_gitlab_pipeline_trigger_33.png

根據流水線觸發器( Trigger )創建處的提示,我們也可以在依賴項目中配置觸發器,依賴項目流水線結束時觸發此項目重新構建。

only 和 except 其他關鍵字的使用可參才官網文檔 https://docs.gitlab.com/ce/ci/yaml/README.html#onlyexcept-basic ,此處暫時不表。

tags

tags 關鍵字用於指定 GitLab Runner 運行器使用哪一個運行器來執行作業。

下面這個例子中,只有運行器注冊時定義了 ruby 和 postgres 兩個標簽的運行器才能執行作業:

job: tags: - ruby - postgres 

而我們的 bluelog 項目中,所有的作業都是使用的是標簽為 bluelog 的運行器:

find Bugs: stage: code_check only: - triggers script: - echo "Use Flake8 to check python code" - pip install flake8 - flake8 --version # - flake8 . tags: - bluelog 

運行器標簽可用於定義不同平台上運行的作業,如 Mac OS Runner 使用 osx 標簽, Windows Runner 使用 windows 標簽,而 Linux Runner 使用 linux 標簽:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
windows job: stage: - build tags:  - windows script: - echo Hello, %USERNAME%! osx job: stage: - build tags:  - osx script: - echo "Hello, $USER!" linux job: stage: - build tags:  - linux script: - echo "Hello, $USER!" 

allow_failure

  • allow_failure 可以用於當你想設置一個作業失敗的之后並不影響后續的CI組件的時候。失敗的作業不會影響到commit提交狀態。
  • 如果允許失敗的作業失敗了,則相應的作業會顯示一個黃色的警告,但對流水線成功與否不產生影響。

下面的這個例子中,job1和job2將會並列進行,如果job1失敗了,它也不會影響進行中的下一個階段,因為這里有設置了 allow_failure: true :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
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 

但是如果上面的job2執行失敗,那么job3則會受到影響而不會執行。

when

when 關鍵字用於實現在作業失敗時或發生故障時運行的作業 (when is used to implement jobs that are run in case of failure or despite the failure.)。

when 可以設置以下值:

  • on_success :只有前面的階段的所有作業都成功時才執行,這是默認值。
  • on_failure :當前面階段的作業至少有一個失敗時才執行。
  • always : 無論前面的作業是否成功,一直執行本作業。
  • manual :手動執行作業,作業不會自動執行,需要人工手動點擊啟動作業。
  • delayed : 延遲執行作業,配合 start_in 關鍵字一起作用, start_in 設置的值必須小於或等於1小時,start_in 設置的值示例: 10 seconds 、 30 minutes 、 hour ,前面的作業結束時計時器馬上開始計時。

示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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 

說明:

  • 只有在 build_job 構建作業失敗時,才會執行 cleanup_build_job 作業。
  • 需要在GitLab Web界面手動點擊,才能執行 deploy_job 部署作業。
  • 無論之前的作業是否成功還是失敗,cleanup_job 清理作業一直會執行。

延時處理的示例:

1
2
3
4
5
timed rollout 10%: stage: deploy script: echo 'Rolling out 10% ...'  when: delayed  start_in: 30 minutes 

上面的例子創建了一個”timed rollout 10%”作業,會在上一個作業完成后30分鍾后才開始執行。

如果你點擊”Unschedule”按鈕可以取消一個激活的計時器,你也可以點擊”Play”按鈕,立即執行延時作業。

environment

environment 用於定義作業部署到特殊的環境中。如果指定了 environment ,並且在 運維 –> 環境 界面的環境列表中沒有該名稱下的環境,則會自動創建新環境。

在最簡單的格式中,環境關鍵字可以定義為:

1
2
3
4
5
deploy to production: stage: deploy script: git push production HEAD:master  environment:  name: production 

上面的示例中,”deploy to production”作業將會部署代碼到”production”生產環境中去。

environment:name

  • 在GitLab 8.11之前,環境的名稱可以使用 environment: production 方式定義,現在推薦使用 name 關鍵字來定義環境的名稱,就像上面的示例一樣。
  • name 關鍵字的參數可以使用任何定義的CI變量,包括預定義的變量、安全變量、以及 .gitlab-ci.yml 配置文件中定義的變量,但不能使用 script 中定義的變量(因為這里面的變量是局部變量)。
  • environment 環境的名稱可以包含:英文字母(letters)、數字(digits)、空格(space)、_、/、$、{、}等。常用的名稱有: qa、 staging 、production 。

Attention

  • 軟件應用開發的經典模型有這樣幾個環境:開發環境(development)、集成環境(integration)、測試環境(testing)、QA驗證,模擬環境(staging)、生產環境(production)。
  • 通常一個web項目都需要一個staging環境,一來給客戶做演示,二來可以作為production server的一個”預演”,正式發布新功能前能及早發現問題(特別是gem的依賴問題,環境問題等)。
  • staging server可以理解為production環境的鏡像,QA在staging server上對新版本做最后一輪verification, 通過后才能deploy到產品線上。staging環境 盡最大可能來模擬產品線上的環境(硬件,網絡拓撲結構,數據庫數據)。

environment:url

  • environment:url 是可選的,用於設置環境的URL地址的按鈕,通過點擊按鈕可以訪問環境相應的URL地址。
  • 下面這個例子中,如果作業都成功完成,那么會在 評審請求 和 環境部署 頁面創建一個Button按鈕,你點擊 打開運行中的環境 按鈕就可以訪問環境對應的URL地址 https://prod.example.com 。

示例:

1
2
3
4
5
6
deploy to production: stage: deploy script: git push production HEAD:master  environment:  name: production  url: https://prod.example.com 

environment:on_stop 與 environment:action

  • environment:on_stop 與 environment:action 配合使用。
  • 可以通過 environment:on_stop 關鍵字定義一個關閉(停止)環境的作業。
  • action 關鍵字在關閉環境的作業中定義。

下面的例子聯合使用 environment:on_stop 與 environment:action 來關閉環境:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
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 中指定了 stop_review_app 作業。一旦 review_app 作業成功執行,就會觸發 when 關鍵字定義的 stop_review_app 作業。通過設置為 manual 手動,需要在GitLab WEB界面點擊來允許 manual action 。

stop_review_app 作業必須配合定義以下關鍵字:

  • when : 何時執行刪除或停止環境作業
  • environment:name : 環境名稱需要與上面的 review_app 作業保持一致,即 review 評審環境
  • environment:action :執行何種執行,stop 停止環境
  • stage :與 review_app 作業的階段保持一致,都是 deploy

運行完成后,在 stop_review_app 作業界面需要手動點擊 停止當前環境 才能啟動 stop_review_app 作業的執行。 stop_review_app 作業執行完成后,會停止 review 評審環境,在 環境 –> 已停止 列表中可以看到 review 評審環境。

Dynamic environments 動態環境

正如前面講解的,可以在環境的名稱中使用變量,在 environment:name 和 environment:url 中使用變量,則可以達到動態環境的目的,動態環境需要底層應用的支持。

我們不詳細展開,下面是官方的一個示例的改版:

1
2
3
4
5
6
deploy as review app: stage: deploy script: make deploy  environment:  name: review/${CI_COMMIT_REF_NAME}  url: https://${CI_ENVIRONMENT_SLUG}.example.com/ 

上面示例中的 ${CI_COMMIT_REF_NAME} ${CI_ENVIRONMENT_SLUG} 就是兩個變量。

cache

  • GitLab Runner v0.7.0 引入 cache 緩存機制。
  • cache 緩存機制,可以在全局設置或者每個作業中設置。
  • 從 GitLab 9.0 開始, cache 緩存機制,可以在不同的的流水線或作業之間共享數據。
  • 從 GitLab 9.2 開始, 在 artifacts 工件之前恢復緩存。
  • cache 緩存機制用於指定一系列的文件或文件夾在不同的流水線或作業之間共享數據,僅能使用項目工作空間( project workspace )中的路徑作為緩存的路徑。
  • 如果 ``cache 配置的路徑是作業工作空間外部,則說明配置是全局的緩存,所有作業共享。
  • 訪問 Cache dependencies in GitLab CI/CD 文檔來獲取緩存是如何工作的以及好的實踐實例的例子。
  • cache 緩存機制的其他介紹請參考 https://docs.gitlab.com/ce/ci/yaml/README.html#cache 。

artifacts

  • artifacts 用於指定在作業成功、失敗、或者一直等狀態下時,一系列的文件或文件夾附加到作業中。artifacts 可以稱為 工件``或者 ``歸檔文件 。
  • 作業完成后,工件被發送到GitLab,可以在GitLab Web界面下載。
  • 默認情況下,只有成功的作業才會生成工件。
  • 並不是所有的 executor 執行器都支持工件。
  • 工件的詳細介紹可參考 Introduction to job artifacts

artifacts:paths

  • artifacts:paths 用於指定哪些文件或文件夾會被打包成工件,僅僅項目工作空間( project workspace )的路徑可以使用。
  • 要在不同作業間傳遞工作,請參數 dependencies

下面示例,將目錄 binaries/ 和文件 .config 打包成工件:

1
2
3
4
artifacts: paths: - binaries/ - .config 

要禁用工件傳遞,請使用空依賴關系定義作業:

1
2
3
4
job: stage: build script: make build  dependencies: [] 

你可以僅為打標記的release發布版本創建工作,這樣可以避免臨時構建產生大量的存儲需求:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
default-job: script: - mvn test -U  except:  - tags release-job: script: - mvn package -U  artifacts:  paths:  - target/*.war  only:  - tags 

上面的示例中,default-job 作業不會在打標記的release發布版本中執行,而 release-job 只會在打標記的release發布版本執行,並且將 target/*.war 打包成工件以供下載。

artifacts:name

  • 工件的默認名稱是 artifacts ,當下載時名稱是 artifacts.zip 。
  • 通過 artifacts:name 關鍵字可以自定義工件的歸檔名稱,這樣你可以為每個工件設置獨一無二的名稱,歸檔名稱可以使用預定義的變量。
  • 如果分支名稱中包含斜杠(比如 feature/my-feature ),推薦使用 $CI_COMMIT_REF_SLUG 代替 $CI_COMMIT_REF_NAME 作為工件名稱。

使用作業名稱使用工件名稱:

1
2
3
4
5
job: artifacts:  name: "$CI_JOB_NAME" paths: - binaries/ 

使用當前分支或tag版本標簽名作為工件名稱:

1
2
3
4
5
job: artifacts:  name: "$CI_COMMIT_REF_NAME" paths: - binaries/ 

同時使用當前作業名稱以及當前分支或tag版本標簽名作為工件名稱:

1
2
3
4
5
job: artifacts:  name: "$CI_JOB_NAME-$CI_COMMIT_REF_NAME" paths: - binaries/ 

同時使用當前作業階段名稱以及當前分支名稱作為工件名稱:

1
2
3
4
5
job: artifacts:  name: "$CI_JOB_STAGE-$CI_COMMIT_REF_NAME" paths: - binaries/ 

如果你使用的 Windows系統的Batch批處理腳本 ,則需要把 $ 替換成 %

1
2
3
4
5
job: artifacts:  name: "%CI_JOB_STAGE%-%CI_COMMIT_REF_NAME%" paths: - binaries/ 

如果你使用的 Windows系統的PowerShell腳本 ,則需要把 $ 替換成 $env:

1
2
3
4
5
job: artifacts:  name: "$env:CI_JOB_STAGE-$env:CI_COMMIT_REF_NAME" paths: - binaries/ 

artifacts:untracked

  • artifacts:untracked 用於將git未加入版本庫的文件作為工件文件。
  • artifacts:untracked 將會忽略配置文件 .gitignore

將所有的未跟蹤文件打包成工件:

1
2
artifacts: untracked: true 

將所有的未跟蹤文件以及目錄 binaries 中文件打包成工件:

1
2
3
4
artifacts: untracked: true paths: - binaries/ 

artifacts:when

  • artifacts:when 用於在作業失敗時或者忽略失敗時上傳工件。

artifacts:when 可以設置以下值:

  • on_success ,默認值,當作業成功上傳工件。
  • on_failure ,當作業失敗上傳工件。
  • always ,無論作業是否成功一直上傳工件。

當作業失敗時,上傳工件:

1
2
3
job: artifacts: when: on_failure 

artifacts:expire_in

  • artifacts:expire_in 用於設置工件的過期時間。

  • 你可以點擊界面上的 Keep 保持按鈕,永久保存工件。

  • 工件到期后,默認情況下每小時刪除一次工件(通過cron作業),並且后續不能再訪問該工件。

  • 工件默認有效期是30天,可以通過 Admin area –> Settings –> Continuous Integration and Deployment 設置默認的有效性時間。

  • 如果你不提供時間單位的話,工作有效性的時間是以秒為單位的時間,下面是一些示例:

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

下面示例中工件有效期為一周:

1
2
3
job: artifacts: expire_in: 1 week 

artifacts:reports

  • artifacts:reports 用於收集測試報告(report),並在GitLab UI界面中顯示出來。
  • 無論作業是否成功,都會收集測試報告。
  • 可以通過設置工件的打包路徑 artifacts:paths 添加測試的報告輸出文件。
  • artifacts:reports:junit 可以用來收集單元測試的報告,查看 JUnit test reports 獲取更詳細的信息和示例。

下面是從Ruby的RSpec測試工具中收集JUnit XML文件的示例:

1
2
3
4
5
6
7
8
rspec: stage: test script: - bundle install  - rspec --format RspecJunitFormatter --out rspec.xml  artifacts:  reports:  junit: rspec.xml 

Note

如果你的測試報告是多個XML文件,你可以在一個作業中指定多個單元測試報告,GitLab會自動將他們轉換成一個文件,可以像下面這樣表示報告的路徑:

  • 文件匹配模式: junit: rspec-*.xml
  • 文件列表: junit: [rspec-1.xml, rspec-2.xml, rspec-3.xml]
  • 混合模式:junit: [rspec.xml, test-results/TEST-*.xml]

下面是Go語言收集JUnit XML文件的示例:

1
2
3
4
5
6
7
8
9
## Use https://github.com/jstemmer/go-junit-report to generate a JUnit report with go
golang: stage: test script:  - go get -u github.com/jstemmer/go-junit-report  - go test -v 2>&1 | go-junit-report > report.xml  artifacts:  reports:  junit: report.xml 

下面是C/C++語言使用GoogleTest進行單元測試,收集JUnit XML文件的示例:

1
2
3
4
5
6
7
cpp: stage: test script:  - gtest.exe --gtest_output="xml:report.xml"  artifacts:  reports:  junit: report.xml 

Attention

如果GoogleTest需要運行在多個平台(如 x86 、 x64 、arm ),需要為每種平台設置唯一的報告名稱,最后將結果匯總起來。

還有一些其他的報告關鍵字,但社區版不可用,忽略不提。

dependencies

  • dependencies 依賴關鍵字應該與 artifacts 工件關鍵字聯合使用,允許你在不同作業間傳遞工件。
  • 默認情況下,會傳遞所有本作業之前階段的所有工件。
  • 需要在作業上下文中定義 dependencies 依賴關鍵字,並指出所有需要使用的前序工件的作業名稱列表。 作業列表中不能使用該作業后的作業名稱 。
  • 定義空的依賴項,將下不會下載任何工件。
  • 使用依賴項不會考慮前面作業的運行狀態。

示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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 

上面示例中, build:osx 和 build:linux 兩個作業定義了工件, test:osx 作業執行時,將會下載並解壓 build:osx 的工件內容。相應的, test:linux 也會獲取 build:linux 的工件。 deploy 作業會下載全部工件。

Attention

如果作為依賴的作業的工件過期或者被刪除,那么依賴這個作業的作業將會失敗。

coverage

  • coverage 可以從作業的輸出log中提取代碼覆蓋率。
  • 僅支持正則表達式方式獲取覆蓋率。
  • 字符串的前后必須使用/包含來表明一個正確的正則表達式規則。特殊字符串需要轉義。

下面是一個簡單的例子:

1
2
job1:  coverage: '/Code coverage:\d+\.\d+%/' 

如在作業日志中輸出了”Code coverage:80.2%”,我們使用上面的正則表達式就可以獲取到代碼的覆蓋率。然后在作業的右上角處就會顯示 Coverage:80.2% 。

retry

  • retry 重試關鍵字用於配置當作業失敗時可以重新執行的次數。
  • 當作業失敗時,如果配置了 retry ,那么該作業就會重試,直到允許的最大次數。
  • 如果 retry 設置值為2,如果第一次重試運行成功了,那么就不會進行第二次重試。
  • retry 設置值只能是0、1、2三個整數。

下面是一個簡單的例子:

1
2
3
test: script: rspec  retry: 2 
  • 為了更好的控制重試次數,retry 可以設置以下兩個關鍵字:

    • max : 最大重試次數
    • when : 何時重試

下面這個例子只有當運行器系統出現故障時才能最多重試兩次:

1
2
3
4
5
test: script: rspec  retry:  max: 2  when: runner_system_failure 

如果上面例子中出現的是其他故障,那么作業不會重試。

為了針對多種重試情形,我們可以使用矩陣形式羅列出錯誤情形,如下示例:

1
2
3
4
5
6
7
test: script: rspec  retry:  max: 2  when:  - runner_system_failure  - stuck_or_timeout_failure 

when 可以是以下值:

  • always : 一直重試,默認值。
  • unknown_failure :當錯誤未知時重試。
  • script_failure : 腳本錯誤時重試。
  • api_failure : API調用錯誤時重試。
  • stuck_or_timeout_failure : 作業卡信或超時錯誤時重試。
  • runner_system_failure : 運行器系統錯誤(如設置工作失敗)時重試。
  • missing_dependency_failure : 依賴工件丟失錯誤時重試。
  • runner_unsupported : 運行器不支持錯誤時重試。

trigger

  • trigger 關鍵字用於多項目流水線時,定義下游的流水線工程,由於社區版本不支持此功能,不詳細介紹。具體可參考 trigger

include

  • include 包含關鍵字可以將其他yaml文件載入到當前的 .gitlab-ci.yml 配置文件中,詳情請查看官網指導 include

extends

  • extends 擴展用於定義當前作業從哪里繼承。
  • 它是使用YAML錨點的替代方案,更加靈活、可讀性強。詳情請查看官網指導 extends

pages

  • pages 是一項特殊工作,用於將靜態內容上傳到GitLab,可用於為您的網站提供服務。詳情請查看官網指導 GitLab Pages

variables

  • 在 .gitlab-ci.yml 配置文件中可以通過 variables 關鍵字配置全局變量或者作業級的局部變量。
  • 當 variables 關鍵字使用在作業層級時,它會覆蓋全局變量或預定義變量。
  • 可以在 variables 關鍵字中定義非敏感性配置。
  • 全局變量可以在各個作業中作業,而作業級別的局部變量只能在該作業中使用。
  • 可以在GitLab WEB界面定義一些敏感性配置變量,或者可能變動的變量。
  • 在 script 中使用 export 可以導出當前可用的變量信息。
  • 作業內部修改全局變量只對當前作用生效,不會影響其他作業。
  • 可以使用賦值語句對全局變量或局部變量進行重新賦值。

下面這個示例定義一個全局數據庫的URL地址:

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

下面修改 bluelog 項目的配置文件為如下內容:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# This file is a template, and might need editing before it works on your project.
# see https://docs.gitlab.com/ce/ci/yaml/README.html for all available options # 定義全局變量 variables:  # 數據庫信息  SQLALCHEMY_DATABASE_URI: 'mysql+pymysql://root:root@localhost:3306/bluelog?charset=utf8mb4'  # 不發送警告通知  SQLALCHEMY_TRACK_MODIFICATIONS: "False"  # 顯示執行SQL  SQLALCHEMY_ECHO: "True" stages: - build - code_check - test - deploy build1: stage: build  variables:  # 數據庫信息  SQLALCHEMY_DATABASE_URI: 'mysql+pymysql://root:123456@localhost:3306/bluelog?charset=utf8mb4'  # 不顯示執行SQL  SQLALCHEMY_ECHO: "False" script: - export - echo "Do your build here" - cloc --version - echo -e "SQLALCHEMY_DATABASE_URI:${SQLALCHEMY_DATABASE_URI}" - echo -e "SQLALCHEMY_TRACK_MODIFICATIONS:${SQLALCHEMY_TRACK_MODIFICATIONS}" - echo -e "SQLALCHEMY_ECHO:${SQLALCHEMY_ECHO}" tags: - bluelog find Bugs: stage: code_check script: - echo -e "SQLALCHEMY_DATABASE_URI:${SQLALCHEMY_DATABASE_URI}" - echo -e "SQLALCHEMY_TRACK_MODIFICATIONS:${SQLALCHEMY_TRACK_MODIFICATIONS}" - echo -e "SQLALCHEMY_ECHO:${SQLALCHEMY_ECHO}" - SQLALCHEMY_ECHO="Nothing" - echo -e "SQLALCHEMY_ECHO:${SQLALCHEMY_ECHO}" tags: - bluelog test1: stage: test  variables:  # CKEditor富文本設置  CKEDITOR_SERVE_LOCAL: "True" script: - echo -e "SQLALCHEMY_DATABASE_URI:${SQLALCHEMY_DATABASE_URI}" - echo -e "SQLALCHEMY_TRACK_MODIFICATIONS:${SQLALCHEMY_TRACK_MODIFICATIONS}" - echo -e "SQLALCHEMY_ECHO:${SQLALCHEMY_ECHO}" - echo -e "CKEDITOR_SERVE_LOCAL:${CKEDITOR_SERVE_LOCAL}" tags: - bluelog test2: stage: test script: - echo "Do another parallel test here" - echo "For example run a lint test" tags: - bluelog deploy1: stage: deploy script: - echo "Do your deploy here" tags: - bluelog 

查看各階段的輸出內容。

_images/gitlab_bluelog_variables_job_build1.png

可以看到 build1 作業中:

  • SQLALCHEMY_DATABASE_URI 已經覆蓋了全局定義的 SQLALCHEMY_DATABASE_URI ,看差異數據庫URL中全局是”root:root”,而作業中是”root:123456”。
  • 由於作業中並沒有定義 SQLALCHEMY_TRACK_MODIFICATIONS 變量,所以使用的是全局的 SQLALCHEMY_TRACK_MODIFICATIONS 變量,輸出結果是”False”。
  • 作業中定義的 SQLALCHEMY_ECHO: "False" 將全局的 SQLALCHEMY_ECHO: "True" 覆蓋,最后顯示的是”False”。

再看 find Bugs 作業:

_images/gitlab_bluelog_variables_job_find_Bugs.png
  • 因為沒有定義 variables 關鍵字,這個作用將使用全局變量。
  • 39、40、41三行輸出的結果都是全局變量定義的值。
  • 42行的 SQLALCHEMY_ECHO="Nothing" 對 SQLALCHEMY_ECHO 全局變量進行的重新賦值,43行打印出了賦值后的新值是”Nothing”。
  • 上面兩個作業說明,作業內部修改全局變量只對當前作用生效,不會影響其他作業。
  • 可以使用賦值語句對全局變量或局部變量進行重新賦值。

再看 test1 作業:

_images/gitlab_bluelog_variables_job_test1.png
  • 該作業定義 variables 關鍵字,增加了一個 CKEDITOR_SERVE_LOCAL 變量。
  • 上一個作業的修改 SQLALCHEMY_ECHO="Nothing" 對本作業顯示 SQLALCHEMY_ECHO 變量沒有影響,仍然會顯示全局變量定義的值”True”。再一次證明了作業內部修改全局變量只對當前作用生效,不會影響其他作業。

variables 變量的優先級

variables 變量的優先級參考 Priority of environment variables

原文:

Variables of different types can take precedence over other variables, depending on where they are defined. The order of precedence for variables is (from highest to lowest): Trigger variables or scheduled pipeline variables. Project-level variables or protected variables. Group-level variables or protected variables. YAML-defined job-level variables. YAML-defined global variables. Deployment variables. Predefined environment variables. 

翻譯過來,是這樣的:

不同類型的變量可以優先於其他變量,具體取決於它們的定義位置。

變量的優先順序是(從最高到最低):

     觸發變量或預定的流水線變量。
     項目級別變量或受保護變量。
     組級別變量或受保護變量。
     YAML定義的作業級變量。
     YAML定義的全局變量。
     部署環境變量。
     預定義的環境變量。

變量中有一些關於git策略的特殊變量,如后續幾個小節,當前僅列出,后續詳細補充。

使用export導出的變量示例

export的導出示例:

$ export
declare -x CI="true"
declare -x CI_API_V4_URL="http://192.168.56.14/api/v4"
declare -x CI_BUILDS_DIR="/root/gitlab-runner/builds"
declare -x CI_BUILD_BEFORE_SHA="84f1f0e417d7e340770a4bb05076bf74f3231991"
declare -x CI_BUILD_ID="128"
declare -x CI_BUILD_NAME="build1"
declare -x CI_BUILD_REF="a6554ffa0d2ae67c675fe9768f702f0b1bb65f5a"
declare -x CI_BUILD_REF_NAME="master"
declare -x CI_BUILD_REF_SLUG="master"
declare -x CI_BUILD_STAGE="build"
declare -x CI_BUILD_TOKEN="[MASKED]"
declare -x CI_COMMIT_BEFORE_SHA="84f1f0e417d7e340770a4bb05076bf74f3231991"
declare -x CI_COMMIT_DESCRIPTION=""
declare -x CI_COMMIT_MESSAGE="全局變量與局部變量的使用
"
declare -x CI_COMMIT_REF_NAME="master"
declare -x CI_COMMIT_REF_SLUG="master"
declare -x CI_COMMIT_SHA="a6554ffa0d2ae67c675fe9768f702f0b1bb65f5a"
declare -x CI_COMMIT_SHORT_SHA="a6554ffa"
declare -x CI_COMMIT_TITLE="全局變量與局部變量的使用"
declare -x CI_CONCURRENT_ID="0"
declare -x CI_CONCURRENT_PROJECT_ID="0"
declare -x CI_CONFIG_PATH=".gitlab-ci.yml"
declare -x CI_JOB_ID="128"
declare -x CI_JOB_NAME="build1"
declare -x CI_JOB_STAGE="build"
declare -x CI_JOB_TOKEN="[MASKED]"
declare -x CI_JOB_URL="http://192.168.56.14/higit/bluelog/-/jobs/128"
declare -x CI_NODE_TOTAL="1"
declare -x CI_PAGES_DOMAIN="example.com"
declare -x CI_PAGES_URL="http://higit.example.com/bluelog"
declare -x CI_PIPELINE_ID="45"
declare -x CI_PIPELINE_IID="48"
declare -x CI_PIPELINE_SOURCE="push"
declare -x CI_PIPELINE_URL="http://192.168.56.14/higit/bluelog/pipelines/45"
declare -x CI_PROJECT_DIR="/root/gitlab-runner/builds/1aXYZ5H9/0/higit/bluelog"
declare -x CI_PROJECT_ID="2"
declare -x CI_PROJECT_NAME="bluelog"
declare -x CI_PROJECT_NAMESPACE="higit"
declare -x CI_PROJECT_PATH="higit/bluelog"
declare -x CI_PROJECT_PATH_SLUG="higit-bluelog"
declare -x CI_PROJECT_URL="http://192.168.56.14/higit/bluelog"
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]@192.168.56.14/higit/bluelog.git"
declare -x CI_RUNNER_DESCRIPTION="bluelog runner"
declare -x CI_RUNNER_EXECUTABLE_ARCH="linux/amd64"
declare -x CI_RUNNER_ID="1"
declare -x CI_RUNNER_REVISION="3001a600"
declare -x CI_RUNNER_TAGS="bluelog"
declare -x CI_RUNNER_VERSION="11.10.0"
declare -x CI_SERVER="yes"
declare -x CI_SERVER_NAME="GitLab"
declare -x CI_SERVER_REVISION="8a802d1c6b7"
declare -x CI_SERVER_VERSION="11.10.6"
declare -x CI_SERVER_VERSION_MAJOR="11"
declare -x CI_SERVER_VERSION_MINOR="10"
declare -x CI_SERVER_VERSION_PATCH="6"
declare -x CI_SHARED_ENVIRONMENT="true"
declare -x CONFIG_FILE="/etc/gitlab-runner/config.toml"
declare -x FF_K8S_USE_ENTRYPOINT_OVER_COMMAND="true"
declare -x FF_USE_LEGACY_GIT_CLEAN_STRATEGY="false"
declare -x GITLAB_CI="true"
declare -x GITLAB_FEATURES=""
declare -x GITLAB_USER_EMAIL="mzh.whut@gmail.com"
declare -x GITLAB_USER_ID="2"
declare -x GITLAB_USER_LOGIN="meizhaohui"
declare -x GITLAB_USER_NAME="梅朝輝"
declare -x HISTCONTROL="ignoredups"
declare -x HISTSIZE="1000"
declare -x HOME="/root"
declare -x HOSTNAME="server.hopewait"
declare -x LANG="en_US.utf8"
declare -x LC_ALL="en_US.utf8"
declare -x LESSOPEN="||/usr/bin/lesspipe.sh %s"
declare -x LOGNAME="root"
declare -x LS_COLORS="rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:"
declare -x MAIL="/var/spool/mail/root"
declare -x OLDPWD="/root/gitlab-runner"
declare -x PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/root/bin"
declare -x PIPENV_PYPI_MIRROR="https://mirrors.aliyun.com/pypi/simple"
declare -x PIPENV_VENV_IN_PROJECT="1"
declare -x PWD="/root/gitlab-runner/builds/1aXYZ5H9/0/higit/bluelog"
declare -x SHELL="/bin/bash"
declare -x SHLVL="3"
declare -x SQLALCHEMY_DATABASE_URI="mysql+pymysql://root:123456@localhost:3306/bluelog?charset=utf8mb4"
declare -x SQLALCHEMY_ECHO="False"
declare -x SQLALCHEMY_TRACK_MODIFICATIONS="False"
declare -x SSH_CLIENT="192.168.56.1 51472 22"
declare -x SSH_CONNECTION="192.168.56.1 51472 192.168.56.14 22"
declare -x SSH_TTY="/dev/pts/0"
declare -x TERM="linux"
declare -x USER="root"
declare -x XDG_RUNTIME_DIR="/run/user/0"
declare -x XDG_SESSION_ID="41"

Attention

  • 不要將敏感信息,如用戶密碼、Token等信息放在 .gitlab-ci.yml 配置文件中定義變量。
  • 敏感信息可以WEB配置界面添加變量,並將變量設置為 Protected受保護 或者 Masked ,設置為 Masked 的變量不會直接顯示在作業日志信息中。

關閉全局層級定義的變量

  • 如果你要在作業層級關閉全局層級定義的變量,可以給 variables 關鍵字定義一個空的 hash 。

如下示例:

1
2
job_name:  variables: {} 

變量定義時使用其他變量

  • 可以在變量定義時,使用其他的變量,需要使用 $$ 進行轉義。

看下面的示例:

1
2
3
4
5
variables:  LS_CMD: 'ls $FLAGS $$TMP_DIR' FLAGS: '-al' script: - 'eval $LS_CMD' # will execute 'ls -al $TMP_DIR' 

克隆策略Git strategy GIT_STRATEGY

  • 你可以通過設置 GIT_STRATEGY 變量來指定GitLab Runner運行作業時使用什么樣的方式來獲取最新的代碼,可以在全局級或作業級進行設置。
  • GIT_STRATEGY 變量可以設置為 fetch 、clone 、none 。
  • clone 是最慢的方式,這種方式會從頭開始克隆倉庫。
  • fetch 相對來說更快一點,如果本地項目空間中存在遠程倉庫的克隆,只用從遠程獲取最新到本地,而不用從頭開始克隆整個倉庫(如果本地項目空間不存在遠程倉庫的克隆的話,則此時等同於clone,從頭開始克隆遠程倉庫)。
  • none 也是利用本地項目空間中的文件,但不會從遠程獲取到最新的修改數據,本地數據不是最新的。

下面我們通過修改 .gitlab-ci.yml 配置文件來查看這個現象:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# This file is a template, and might need editing before it works on your project.
# see https://docs.gitlab.com/ce/ci/yaml/README.html for all available options stages: - build - code_check - test - deploy build1: stage: build script: - pwd - export - echo "Do your build here"  - echo "GIT_STRATEGY:${GIT_STRATEGY}" tags: - bluelog find Bugs: stage: code_check variables:  GIT_STRATEGY: "fetch" script: - pwd  - echo "GIT_STRATEGY:${GIT_STRATEGY}" tags: - bluelog test1: stage: test variables:  GIT_STRATEGY: "clone" script: - pwd  - echo "GIT_STRATEGY:${GIT_STRATEGY}" tags: - bluelog test2: stage: test variables:  GIT_STRATEGY: "none" script:  - echo "GIT_STRATEGY:${GIT_STRATEGY}" tags: - bluelog deploy1: stage: deploy script: - echo "Do your deploy here" tags: - bluelog 

提交后,流水線觸發了:

_images/gitlab_bluelog_git_strategy_pipeline.png

我們檢查一下每個作業的log日志信息:

先看build1作業:

_images/gitlab_bluelog_git_strategy_pipeline_build1_job_top.png  _images/gitlab_bluelog_git_strategy_pipeline_build1_job_bottom.png

可以看到默認情況下,會使用 git fetch 方式來獲取最新的修改,並且 echo "GIT_STRATEGY:${GIT_STRATEGY}" 打印 ${GIT_STRATEGY} 變量為空,也就是默認情況下GitLab並不會設置 GIT_STRATEGY 變量。

再看一下find Bugs作業:

_images/gitlab_bluelog_git_strategy_find_Bugs.png

此處也是直接使用現有項目空間里面的本地倉庫,使用 git fetch 方式來獲取最新的修改,由於在作業級中設置了 GIT_STRATEGY 變量,最后打印出打印 ${GIT_STRATEGY} 變量的值為 fetch 。

再看一下test1作業:

_images/gitlab_bluelog_git_strategy_test1.png

因為設置了 GIT_STRATEGY: "clone" ,這個時候GitLab Runner會從頭開始克隆遠程倉庫,最后打印出打印 ${GIT_STRATEGY} 變量的值為 clone 。

再看一下test2作業:

_images/gitlab_bluelog_git_strategy_test2.png

因為設置了 GIT_STRATEGY: "none" ,這個時候GitLab Runner什么也不做,不會獲取最新的修改,最后打印出打印 ${GIT_STRATEGY} 變量的值為 none 。

我們再修改一下配置文件為下面的內容:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# This file is a template, and might need editing before it works on your project.
# see https://docs.gitlab.com/ce/ci/yaml/README.html for all available options stages: - build - code_check - test - deploy build1: stage: build script: - pwd - export - echo "Do your build here" - echo "GIT_STRATEGY:${GIT_STRATEGY}" - du -sh - ls -lah README.md tags: - bluelog find Bugs: stage: code_check variables: GIT_STRATEGY: "fetch" script: - pwd - echo "GIT_STRATEGY:${GIT_STRATEGY}" - du -sh - ls -lah README.md when: manual tags: - bluelog test1: stage: test variables: GIT_STRATEGY: "clone" script: - pwd - echo "GIT_STRATEGY:${GIT_STRATEGY}" - du -sh - ls -lah README.md when: manual tags: - bluelog test2: stage: test variables: GIT_STRATEGY: "none" script: - echo "GIT_STRATEGY:${GIT_STRATEGY}" - du -sh - ls -lah README.md when: manual tags: - bluelog deploy1: stage: deploy script: - echo "Do your deploy here" - du -sh - ls -lah README.md when: manual tags: - bluelog 

提交后,流水線觸發了,但有build1作業后面的作業需要手動執行:

_images/gitlab_bluelog_git_strategy_manual_pipeline.png

我們檢查build1作業:

_images/gitlab_bluelog_git_strategy_manual_pipeline_build1_job_bottom.png

可以獲取到整個倉庫的大小,也可以讀取到倉庫中”README.md”文件。

假設我們此時在服務器端將 /root/gitlab-runner/builds/1aXYZ5H9/0/higit/bluelog 和 /root/gitlab-runner/builds/1aXYZ5H9/0/higit/bluelog.tmp 目錄刪除,並觸發find Bugs作業運行:

_images/gitlab_bluelog_git_strategy_manual_pipeline_delete_project_workspace.png

因為設置了 GIT_STRATEGY: "fetch" ,但因為我把項目空間里面的本地倉庫內容都刪除了,這個時候GitLab Runner發現本地並沒有遠程倉庫的文件,只能從頭開始克隆遠程倉庫,最后打印出打印 ${GIT_STRATEGY} 變量的值為 fetch 。

_images/gitlab_bluelog_git_strategy_manual_pipeline_find_bugs_job.png

再觸發test1作業運行,還是從頭開始下載遠程倉庫:

_images/gitlab_bluelog_git_strategy_manual_pipeline_test1_job.png

關鍵一步,我們再次刪除工作空間中的 /root/gitlab-runner/builds/1aXYZ5H9/0/higit/bluelog 和 /root/gitlab-runner/builds/1aXYZ5H9/0/higit/bluelog.tmp 目錄:

_images/gitlab_bluelog_git_strategy_manual_pipeline_delete_project_workspace_again.png

再觸發test2作業運行:

_images/gitlab_bluelog_git_strategy_manual_pipeline_test2_job_failed.png

此時發現,GitLab Runner僅僅創建了一個目錄 bluelog ,但不從遠程獲取數據,這個時候我們獲取倉庫目錄數據大小為0,也查看不到README.md文件的詳情,由於沒有README.md文件,執行命令就報錯。

  • 可以看出設置 GIT_STRATEGY: "none" 可能會遇到意想不到的情況!
  • 為了加快流水線工程的執行,建議使用 fetch 模式。
  • 流水線的Git策略默認是 git fetch 模式。

流水線的默認Git策略,可以在項目的流水線通用設置中查看:

_images/gitlab_bluelog_default_git_strategy.png

子模塊策略Git submodule strategy GIT_SUBMODULE_STRATEGY

  • GIT_SUBMODULE_STRATEGY 類似於 GIT_STRATEGY ,當你的項目需要包含別的項目代碼時,可以將別的項目作為你的項目的子模塊,這個時候就可以使用 GIT_SUBMODULE_STRATEGY 。
  • GIT_SUBMODULE_STRATEGY 默認取值 none ,即拉取代碼時,子模塊不會被引入。
  • GIT_SUBMODULE_STRATEGY 可取值 normal ,意味着在只有頂級子模塊會被引入。
  • GIT_SUBMODULE_STRATEGY 可取值 recursive ,遞歸的意思,意味着所有級子模塊會被引入。

子模塊需要配置在 .gitmodules 配置文件中,下面是兩個示例:

場景:

  • 你的項目地址: https://gitlab.com/secret-group/my-project ,你可以使用 git clone git@gitlab.com:secret-group/my-project.git 檢出代碼。
  • 你的項目依賴 https://gitlab.com/group/project ,你可以將這個模塊作為項目的子模塊。

子模塊與本項目在同一個服務上,可以使用相對引用:

1
2
3
[submodule "project"]  path = project  url = ../../group/project.git 

子模塊與本項目不在同一個服務上,使用相對絕對URL:

1
2
3
[submodule "project-x"]  path = project-x  url = https://gitserver.com/group/project-x.git 

詳細可參考 Using Git submodules with GitLab CI

檢出分支設置Git checkout GIT_CHECKOUT

  • 當 GIT_STRATEGY 設置為 fetch 或者 clone 時,可以通過 GIT_CHECKOUT 變量設置是否需要做 git checkout 操作,如果未指定該參數,默認值為 true ,即需要做 git checkout 操作。

  • 可以在全局級或作業級進行設置。

  • 如果 GIT_CHECKOUT 變量設置為 true ,GitLab Runner都會將本地工作副本檢出並切換到當前流水線相關的修訂版本分支上。

  • 如果 GIT_CHECKOUT 變量設置為 false ,那么運行器操作如下:

    • fetch 操作時,更新倉庫並在當前版本上保留工作副本。
    • clone 操作時,克隆倉庫並在默認分支中保留工作副本。

下面示例不進行自動切換到分支:

1
2
3
4
5
6
variables:  GIT_STRATEGY: clone  GIT_CHECKOUT: "false" script: - git checkout -B master origin/master - git merge $CI_COMMIT_SHA 

清理工作Git clean flags GIT_CLEAN_FLAGS

  • 可以使用 GIT_CLEAN_FLAGS 變量來控制在檢出源碼后 git clean 的默認行為,可以在全局級或作業級進行設置。
  • GIT_CLEAN_FLAGS 變量接受 git clean 命令的所有參數。
  • 如果指定了 GIT_CHECKOUT: "false" ,那么 git clean 將不可用。
  • git-clean : Remove untracked files from the working tree,即刪除未跟蹤的文件。
  • git clean 命令用來從你的工作目錄中刪除所有沒有tracked過的文件, git reset --hard 用於刪除跟蹤文件的修改記錄。
  • git clean -n 命令列出將被刪除的文件。
  • git clean -f 命令刪除當前目錄下所有沒有跟蹤過的文件。
  • git clean -d 命令刪除當前目錄下所有沒有跟蹤過的目錄。
  • git clean -e <pattern> 命令排除( --exclude=<pattern> ) 某文件或目錄,即不刪除模式匹配的文件。
  • git clean -ffxd 命令刪除當前目錄(包括由其他git倉庫管理的子目錄)下所有沒有跟蹤過的目錄和文件。
  • GIT_CLEAN_FLAGS 變量未指定時, git clean 命令的參數是 -ffxd 。
  • GIT_CLEAN_FLAGS 變量指定為 none 時, git clean 命令不會執行。

下面示例用於刪除未被跟蹤文件和目錄,但排除cache目錄及目錄下的文件:

1
2
3
4
variables:  GIT_CLEAN_FLAGS: -ffdx -e cache/ script: - ls -al cache/ 

作業重試次數 Job stages attempts

  • 您可以設置正在運行的作業嘗試執行以下每個階段的嘗試次數。可以在全局級或作業級進行設置。
  • 涉及三個變量 GET_SOURCES_ATTEMPTS 、 ARTIFACT_DOWNLOAD_ATTEMPTS 、 RESTORE_CACHE_ATTEMPTS 。
  • GET_SOURCES_ATTEMPTS 變量設置獲取源碼的嘗試次數。
  • ARTIFACT_DOWNLOAD_ATTEMPTS 變量設置下載歸檔文件的嘗試次數。
  • RESTORE_CACHE_ATTEMPTS 變量設置重建緩存的嘗試次數。
  • 默認是1次嘗試。

示例:

1
2
variables:  GET_SOURCES_ATTEMPTS: 3 

淺克隆 Shallow cloning GIT_DEPTH

  • GitLab 8.9中引入了試驗性的特征 淺克隆 ,在將來的版本中有可能改變或者完全移除。
  • 可以通過設置 GIT_DEPTH 克隆深度,不詳細介紹,可參考 Shallow cloning

廢棄的關鍵字 types 和 type

  • 關鍵字 types 和 type 已經廢棄。
  • 使用 stages 階段定義關鍵字代替 types 。
  • 使用 stage 作業所處階段關鍵字代替 type 。

使用 GIT_CLONE_PATH 自定義構建目錄

  • 在默認情況下,自定義構建目錄只有在GitLab Runner運行器配置文件中定義了 custom_build_dir 為 enabled 開啟狀態時才可使用。
  • docker 、 kubernetes 運行器默認開啟了此功能,而其他運行器默認不會開啟此功能。
  • 默認情況下,GitLab Runner運行器將倉庫克隆到 $CI_BUILDS_DIR 目錄下的一個名稱唯一的子目錄中,但有時候你的項目可能需要指定一個特殊的路徑用來保存下載的倉庫,這個時候就可以使用 GIT_CLONE_PATH 變量來指定克隆文件的存放目錄。
  • GIT_CLONE_PATH 必須是 $CI_BUILDS_DIR 的子目錄, $CI_BUILDS_DIR 目錄各個運行器可能不同。

我們嘗試在我們的SHELL運行器上去設置 GIT_CLONE_PATH 目錄。

下面是官方給出的一個示例:

1
2
3
4
5
6
variables:  GIT_CLONE_PATH: $CI_BUILDS_DIR/project-name test: script: - pwd 

我們仿照這個示例修改 .gitlab-ci.yml 配置文件,並進行提交,修改后的內容如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# This file is a template, and might need editing before it works on your project.
# see https://docs.gitlab.com/ce/ci/yaml/README.html for all available options # 定義全局變量 variables: # 數據庫信息 SQLALCHEMY_DATABASE_URI: 'mysql+pymysql://root:root@localhost:3306/bluelog?charset=utf8mb4' # 不發送警告通知 SQLALCHEMY_TRACK_MODIFICATIONS: "False" # 顯示執行SQL SQLALCHEMY_ECHO: "True" # 設置全局構建目錄  GIT_CLONE_PATH: $CI_BUILDS_DIR/global_folder stages: - build - code_check - test - deploy build1: stage: build variables: # 數據庫信息 SQLALCHEMY_DATABASE_URI: 'mysql+pymysql://root:123456@localhost:3306/bluelog?charset=utf8mb4' # 不顯示執行SQL SQLALCHEMY_ECHO: "False" # 設置全局構建目錄  GIT_CLONE_PATH: $CI_BUILDS_DIR/sub_folder script: - pwd - export - echo "Do your build here" - cloc --version - echo -e "SQLALCHEMY_DATABASE_URI:${SQLALCHEMY_DATABASE_URI}" - echo -e "SQLALCHEMY_TRACK_MODIFICATIONS:${SQLALCHEMY_TRACK_MODIFICATIONS}" - echo -e "SQLALCHEMY_ECHO:${SQLALCHEMY_ECHO}" tags: - bluelog find Bugs: stage: code_check script: - pwd - echo -e "SQLALCHEMY_DATABASE_URI:${SQLALCHEMY_DATABASE_URI}" - echo -e "SQLALCHEMY_TRACK_MODIFICATIONS:${SQLALCHEMY_TRACK_MODIFICATIONS}" - echo -e "SQLALCHEMY_ECHO:${SQLALCHEMY_ECHO}" - SQLALCHEMY_ECHO="Nothing" - echo -e "SQLALCHEMY_ECHO:${SQLALCHEMY_ECHO}" tags: - bluelog test1: stage: test variables: # CKEditor富文本設置 CKEDITOR_SERVE_LOCAL: "True" script: - pwd - echo -e "SQLALCHEMY_DATABASE_URI:${SQLALCHEMY_DATABASE_URI}" - echo -e "SQLALCHEMY_TRACK_MODIFICATIONS:${SQLALCHEMY_TRACK_MODIFICATIONS}" - echo -e "SQLALCHEMY_ECHO:${SQLALCHEMY_ECHO}" - echo -e "CKEDITOR_SERVE_LOCAL:${CKEDITOR_SERVE_LOCAL}" tags: - bluelog test2: stage: test script: - echo "Do another parallel test here" - echo "For example run a lint test" tags: - bluelog deploy1: stage: deploy script: - echo "Do your deploy here" tags: - bluelog 

提交修改構建目錄后,流水線執行失敗:

_images/gitlab_bluelog_custom_build_directory_failure.png

查看作業詳情:

_images/gitlab_bluelog_custom_build_directory_failure_job_details.png

可以看到提示 ERROR: Job failed: setting GIT_CLONE_PATH is not allowed, enable `custom_build_dir` feature

意思是說不允許設置 GIT_CLONE_PATH 變量,需要設置 custom_build_dir 屬性。

我們參考 The [runners.custom_build_dir] section 來設置 custom_build_dir 屬性。

我們查看一下GitLab Runner的配置文件內容:

[root@server ~]# cat /etc/gitlab-runner/config.toml concurrent = 1 check_interval = 0 [session_server] session_timeout = 1800 [[runners]] name = "bluelog runner" url = "http://192.168.56.14/" token = "1aXYZ5H9n2y8oauWkz7D" executor = "shell" [runners.custom_build_dir] [runners.cache] [runners.cache.s3] [runners.cache.gcs] 

我們參考示例:

[runners.custom_build_dir] enabled = true 

開啟 custom_build_dir 屬性,修改后配置文件內容如下:

[root@server ~]# cat /etc/gitlab-runner/config.toml concurrent = 1 check_interval = 0 [session_server] session_timeout = 1800 [[runners]] name = "bluelog runner" url = "http://192.168.56.14/" token = "1aXYZ5H9n2y8oauWkz7D" executor = "shell" [runners.custom_build_dir] enabled = true [runners.cache] [runners.cache.s3] [runners.cache.gcs] 

重新觸發”build1”作業,看看效果。

此時可以看到,作業開始運行了,並且在 /root/gitlab-runner/builds 目錄下生成了四個folder相關的目錄:

[root@server builds]# pwd /root/gitlab-runner/builds [root@server builds]# ls -ld *folder* drwxr-xr-x 5 root root 193 Jul 12 23:08 global_folder drwxr-xr-x 3 root root 26 Jul 12 23:08 global_folder.tmp drwxr-xr-x 5 root root 193 Jul 12 23:08 sub_folder drwxr-xr-x 3 root root 26 Jul 12 23:08 sub_folder.tmp 

查看”build1”和”find Bugs”作業的詳情:

_images/gitlab_bluelog_custom_build_directory_success_build1_job_details.png

可以看到”build1”作業使用作業級定義的 GIT_CLONE_PATH: $CI_BUILDS_DIR/sub_folder ,倉庫會被下載到 /root/gitlab-runner/builds/sub_folder 目錄下。

_images/gitlab_bluelog_custom_build_directory_success_find_bugs_job_details.png

可以看到”build1”作業使用全局級定義的 GIT_CLONE_PATH: $CI_BUILDS_DIR/global_folder ,倉庫會被下載到 /root/gitlab-runner/builds/global_folder 目錄下。

處理並發(Handling concurrency)

  • 當執行器配置並發數 concurrent 大於1時,有可能導致作業運行失敗,因為有可能多個作業都運行在相同的目錄上,GitLab Runner運行器並不會去阻止這種情形,管理員和開發人員必須遵守Runner配置的要求。

  • 要避免這種情況,您可以在 $CI_BUILDS_DIR 中使用唯一路徑,因為Runner公開了另外兩個提供唯一並發ID的變量:

    • $CI_CONCURRENT_ID :給定執行程序中運行的所有作業的唯一ID。
    • $CI_CONCURRENT_PROJECT_ID :在給定執行程序和項目中運行的所有作業的唯一ID。
  • 在任何場景和任何執行器中都應該運行良好的最穩定的配置是在 GIT_CLONE_PATH 中使用 $CI_CONCURRENT_ID 。

例如:

1
2
3
4
5
6
variables:  GIT_CLONE_PATH: $CI_BUILDS_DIR/$CI_CONCURRENT_ID/project-name test: script: - pwd 

嵌套路徑(Nested paths)

  • GIT_CLONE_PATH 變量最多只能擴展一次,不支持嵌套的變量路徑。

下面定義了兩個變量:

1
2
3
variables:  GOPATH: $CI_BUILDS_DIR/go  GIT_CLONE_PATH: $GOPATH/src/namespace/project 

GIT_CLONE_PATH 變量擴展一次后,變量成了 $CI_BUILDS_DIR/go/src/namespace/project ,這個時候在路徑中有一個變量,而 GIT_CLONE_PATH 變量不會再次擴展 $CI_BUILDS_DIR 導致作業運行失敗。

特殊的YAML功能

可以使用特殊的YAML功能,如錨點(  ),別名( * )和合並( << ),這將使您大大降低 .gitlab-ci.yml 的復雜性。

隱藏關鍵字或作業

如果我們想暫時禁用某個作業,我們可以將該作業的所有行都注釋掉,如下示例:

1
2
3
#hidden_job: # script: # - run test 

更好的方法是,我們在作業名稱前面增加一個點號( . ), 這樣GitLab CI流水線就會自動處理忽略掉 .hidden_job 作業。

改成下面這樣:

1
2
3
.hidden_job: script: - run test 

錨點(Anchors)

  • 錨點可以讓你容易復制文檔內容,錨點可以用來復制或繼承某些屬性,錨點與隱藏作業一起使用可提供作業模板。

下面的例子使用錨點和合並創建了兩個作業,test1 和 test2 ,兩個作業都是繼承自隱藏作業 .job_template ,並且都有他們自己獨有的工作腳本定義:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
.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 ,也就是給隱藏作業設置一個錨點 job_definition 。
  • << 合並,將錨點定義的模板內容復制到當前作業的當前位置來。
  • * 包含錨點的名稱 job_definition

擴展后的配置文件變成下面這樣:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
.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 

再看另外一個示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
.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 

擴展后是這樣的:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
.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觸發器

忽略CI檢查

  • 當你提交的commit日志信息中包含 [ci skip] 或者 [skip ci] (忽略大小寫),提交可以成功但是會忽略流水線的執行。
  • 或者,在 git push 時添加推送選項,如 git push -o ci.skip 。

我們第一次修改配置文件,commit日志為”移除自定義構建目錄,測試忽略ci構建 ci skip”,包含有 ci skip 關鍵字,但是沒有左右中括號,進行提交:

_images/gitlab_bluelog_git_commit_with_ci_skip.png

但是發現流水線被觸發了,正常運行了:

_images/gitlab_bluelog_git_commit_with_ci_skip_trigger_success_pipeline.png

我們第二次修改配置文件,commit日志為”移除自定義構建目錄,測試忽略ci構建 [CI Skip]”,包含有 [CI Skip] 關鍵字,進行提交:

_images/gitlab_bluelog_git_commit_with_CI_Skip_Capitalization.png

可以發現流水線沒有被觸發,但是提交已經創建成功了:

_images/gitlab_bluelog_git_commit_with_ci_skip_trigger_skipped_pipeline.png  _images/gitlab_bluelog_git_commit_with_ci_skip_trigger_skipped_pipeline1.png

我們第三次修改配置文件,commit日志為”測試使用git push添加推送選項”,進行提交:

_images/gitlab_bluelog_git_commit_with_git_push_ci_skip_option.png

可以發現流水線沒有被觸發,但是提交已經創建成功了:

_images/gitlab_bluelog_git_commit_with_git_push_ci_skip_option_trigger_skipped_pipeline.png

.gitlab-ci.yml 配置文件各個關鍵字的使用就介紹到這里。

參考:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM