CI流水线配置文件参数详解(一)
文章目錄
- 4. 參數詳解(一)
- 4.1 ``script``
- 4.2 ``image`` 指定使用Docker鏡像。如 ``iamge:name`` ,暫時忽略。
- 4.3 ``before_script`` 用于定義在所有作業之前需要執行的命令,比如更新代碼、安裝依賴、打印調試信息之類的事情。
- 4.4 ``after_script``
- 4.5 ``stages`` 定義流水線全局可使用的階段,階段允許有靈活的多級管道,階段元素的排序定義了作業執行的順序。
- 4.6 ``stage``
- 4.7 ``only`` 和 ``except`` 用于在創建作業時對作業的限制策略。
- 4.8 ``only`` 和 ``except`` 高級用法
4. 參數詳解(一)
4.1 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``
4.2 image 指定使用Docker鏡像。如 iamge:name ,暫時忽略。
services
``services`` 指定使用Docker鏡像服務。如 ``services:name`` ,暫時忽略。``before_script``
4.3 before_script 用于定義在所有作業之前需要執行的命令,比如更新代碼、安裝依賴、打印調試信息之類的事情。
示例::
before_script:- echo "Before script section"- echo "運行更新或安裝構建依賴項"- echo "打印出一些調試細節"
4.4 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 "例如,您可以在這里運行更新或安裝構建依賴項"- echo "或者,您可能會打印出一些調試細節"after_script:- echo "After script section"- echo "例如,你可以在這里做一些清理"build1:stage: buildbefore_script:- echo "在構建階段重寫全局定義的before_script的Before腳本"- echo "安裝cloc:一個從給定目錄中計算不同語言的代碼行數的工具"- yum install cloc -yafter_script:- echo "在構建階段重寫全局定義的after_script的After腳本"- cloc --version- cloc .script:- echo "Do your build here"- cloc --version- cloc .tags:- bluelog將修改上傳提交,查看作業build1的控制臺輸出:可以發現build1作業的 ``before_script`` 和 ``after_script`` 將全局的 ``before_script`` 和 ``after_script`` 覆蓋了。``stages``
4.5 stages 定義流水線全局可使用的階段,階段允許有靈活的多級管道,階段元素的排序定義了作業執行的順序。
- 相同
stage階段的作業并行運行。 - 默認情況下,上一階段的作業全部運行成功后才執行下一階段的作業。
- 默認有三個階段,
build、test、deploy三個階段,即構建、測試、部署。 - 如果一個作業未定義
stage階段,則作業使用test測試階段。 - 默認情況下,任何一個前置的作業失敗了,commit提交會標記為failed并且下一個stages的作業都不會執行。
4.6 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 optionsbefore_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- deploybuild1:stage: buildbefore_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 -yafter_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:- bluelogfind Bugs:stage: code_checkscript:- echo "Use Flake8 to check python code"- pip install flake8- flake8 --version- flake8 .tags:- bluelogtest1:stage: testscript:- echo "Do a test here"- echo "For example run a test suite"tags:- bluelogtest2:stage: testscript:- echo "Do another parallel test here"- echo "For example run a lint test"tags:- bluelog我們增加一個 ``code_check`` 階段,該階段有一個作業 ``find Bugs`` ,該作業主要是**先安裝Flake8,然后使用Flake8對Python代碼進行規范檢查。**
因為筆者平時主要使用代碼為C++,因此這里可以選擇相應的C++靜態代碼檢測工具。由于Flake8檢查到了Python代碼中的缺陷,導致find Bugs作業失敗!這樣可以控制開發人員提交有壞味道的代碼到倉庫中。(C++同樣的道理)本次(pipeline #7)流水線由于在作業 ``find Bugs`` 檢查不通過,導致整個流水線運行失敗,后續的作業不會執行:默認情況下,GitLab Runner運行器每次只執行一個作業,只有當滿足以下條件之一時,才會真正的并行執行:- 作業運行在不同的運行器上;- 你修改了運行器的 ``concurrent`` 設置,默認情況下 ``concurrent = 1`` 。 ``only`` 和 ``except``
4.7 only 和 except 用于在創建作業時對作業的限制策略。
only定義了哪些分支或標簽(branches and tags)的作業會運行except定義了哪些分支或標簽(branches and tags)的作業不會運行
下面是策略規則:
only和except可同時使用,如果在一個作業中同時定義了only和except,則同時onlyexcept進行過濾(注意,不是忽略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 regexponly:- /^issue-.*$/# use special keywordexcept:- branches
匹配模式默認是大小寫敏感的(case-sensitive),使用 i 標志,如 /pattern/i 可以使匹配模式大小寫不敏感::
job:# use regexponly:- /^issue-.*$/i# use special keywordexcept:- branches
下面這個示例,僅當指定標記的tags的refs引用,或者通過API觸發器的構建、或者流水線計劃調度的構建才會運行:
job:# use special keywordsonly:- tags- triggers- schedules
倉庫的路徑(repository path)只能用于父級倉庫執行作業,不能用于forks:
job:only:- branches@gitlab-org/gitlab-ceexcept:- 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`` 的分支,所以正則表達式的使用要謹慎!
4.8 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 deployonly:refs:- branchesvariables:- $RELEASE == "staging"- $STAGING下面這個例子,會根據提交日志信息來排除某些作業::end-to-end:script: rake test:end-to-endexcept: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 testonly:changes:- "*.json"- "**/*.sql".. Attention::在上面的示例中,``glob模式匹配`` 的字符串需要使用雙引號包裹起來,否則會導致 ``.gitlab-ci.yml`` 解析錯誤。下面這個例子,當md文件發生變化時,會忽略CI作業::build:script: npm run buildexcept: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_requestschanges:- Dockerfile- service-one/**/*上面這個例子中,一旦合并請求中修改了 ``Dockerfile`` 文件或者修改了 ``service`` 目錄下的文件,都會觸發Docker構建。``only`` 和 ``except`` 綜合示例
我們將 bluelog 項目的描述和主題進行修改:
創建三個分支 issue-pylint 、Issue-flake8 和 severe-issues :
剛新增的三個分支,自動繼承了master主干的CI RUNNER。
為了便于測試,將"sunshine"賬號設置為 bluelog 項目的主程序員!
現在朝 .gitlab-ci.yml 文件中增加 only 和 except 策略。匹配 issue- 開頭的分支,創建僅匹配 issue- 開頭的分支:
設置后可以發現master主干沒有執行 find Bugs 作業,現在只會觸發同時滿足CI觸發按鈕的條件和only條件的分支。
為了快速測試,我們對每個作業都使用 only 和 except 策略:
# 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 optionsbefore_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- deploybuild1:stage: buildbefore_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 -yafter_script:- echo "After script in build stage that overwrited the globally defined after_script"- cloc --version# cloc .only:- /^issue-.*$/except:- masterscript:- echo "Do your build here"- cloc --version# - cloc .tags:- bluelogfind Bugs:stage: code_checkonly:- /^issue-.*$/except:- branchesscript:- echo "Use Flake8 to check python code"- pip install flake8- flake8 --version# - flake8 .tags:- bluelogtest1:stage: testonly:- /^issue-.*$/except:- /issue-pylint/script:- echo "Do a test here"- echo "For example run a test suite"tags:- bluelogtest2:stage: testonly:- /^issue-.*$/except:- /Issue-flake8/script:- echo "Do another parallel test here"- echo "For example run a lint test"tags:- bluelogdeploy1:stage: deployonly:- /^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 | 未觸發 |
解釋上面的流水作業策略:
| 作業 | 規則定義 | 規則解釋 |
|---|---|---|
| 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 標志:
# 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 optionsbefore_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- deploybuild1:stage: buildbefore_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 -yafter_script:- echo "After script in build stage that overwrited the globally defined after_script"- cloc --version# cloc .only:- /^issue-.*$/iexcept:- masterscript:- echo "Do your build here"- cloc --version# - cloc .tags:- bluelogfind Bugs:stage: code_checkonly:- /^issue-.*$/iexcept:- branchesscript:- echo "Use Flake8 to check python code"- pip install flake8- flake8 --version# - flake8 .tags:- bluelogtest1:stage: testonly:- /^issue-.*$/iexcept:- /issue-pylint/script:- echo "Do a test here"- echo "For example run a test suite"tags:- bluelogtest2:stage: testonly:- /^issue-.*$/iexcept:- /Issue-flake8/script:- echo "Do another parallel test here"- echo "For example run a lint test"tags:- bluelogdeploy1:stage: deployonly:- /^issue-.*$/iexcept:- /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 分支不會觸發流水線執行:
解釋上面的流水作業策略:
| 作業 | 規則定義 | 規則解釋 |
|---|---|---|
| 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字符:
# 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 optionsbefore_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- deploybuild1:stage: buildbefore_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 -yafter_script:- echo "After script in build stage that overwrited the globally defined after_script"- cloc --version# cloc .only:- /issue/iexcept:- masterscript:- echo "Do your build here"- cloc --version# - cloc .tags:- bluelogfind Bugs:stage: code_checkonly:- /issue/iexcept:- branchesscript:- echo "Use Flake8 to check python code"- pip install flake8- flake8 --version# - flake8 .tags:- bluelogtest1:stage: testonly:- /issue/iexcept:- /issue-pylint/script:- echo "Do a test here"- echo "For example run a test suite"tags:- bluelogtest2:stage: testonly:- /issue/iexcept:- /Issue-flake8/script:- echo "Do another parallel test here"- echo "For example run a lint test"tags:- bluelogdeploy1:stage: deployonly:- /issue/iexcept:- /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 主干不會觸發流水線執行:
解釋上面的流水作業策略:
| 作業 | 規則定義 | 規則解釋 |
|---|---|---|
| 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分支執行 |
總結
以上是生活随笔為你收集整理的CI流水线配置文件参数详解(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 黄山风景区淡季是几月份
- 下一篇: 宝马钥匙多少钱啊?