Gitlab CI 配置檔案 .gitlab-ci.yaml 詳解(上)
本文件用於描述 .gitlab-ci.yml 語法,.gitlab-ci.yml 檔案被用來管理專案的 runner 任務。如果想要快速的瞭解GitLab CI ,可檢視 ofollow,noindex" target="_blank">快速引導 。 從 7.12 版本開始,GitLab CI 使用 YAML 檔案 (.gitlab-ci.yml) 來管理專案配置。該檔案存放於專案倉庫的根目錄,它定義該專案如何構建。
開始構建之前YAML檔案定義了一系列帶有約束說明的任務。這些任務都是以任務名開始並且至少要包含 script
部分:
job1: script: execute-script-for-job1 job2: script: execute-script-for-job2
上面這個例子就是一個最簡單且帶有兩個獨立任務的CI配置,每個任務分別執行不同的命令。
script
可以直接執行系統命令(例如:./configure && make && make install)或者是直接執行指令碼(test.sh)。
任務是由 Runners 接管並且由伺服器中runner執行。更重要的是,每一個任務的執行過程都是獨立執行的。
用下面這個例子來說明YAML語法還有更多複雜的任務:
image: ruby:2.1 services: - postgres before_script: - bundle install after_script: - rm secrets stages: - build - test - deploy job1: stage: build script: - execute-script-for-job1 only: - master tags: - docker
下面列出保留欄位,這些保留欄位不能被定義為 job
名稱:
關鍵字 | 是否必須 | 描述 |
---|---|---|
image | 否 | 用於docker映象,檢視 docker 文件 |
services | 否 | 用於docker服務,檢視 docker 文件 |
stages | 否 | 定義構建階段 |
types | 否 | stages 的別名(已廢除) |
before_script | 否 | 定義在每個job之前執行的命令 |
after_script | 否 | 定義在每個job之後執行的命令 |
variable | 否 | 定義構建變數 |
cache | 否 | 定義一組檔案列表,可在後續執行中使用 |
image和services
這兩個關鍵字允許使用一個自定義的Docker映象和一系列的服務,並且可以用於整個job週期。詳細配置文件請檢視 a separate document 。
before_script
before_script
用來定義所有job之前執行的命令,包括deploy(部署) jobs,但是在修復artifacts之後。它可以是一個數組或者是多行字串。
after_script
GitLab 8.7 開始引入,並且要求Gitlab Runner v1.2
after_script
用來定義所有job之後執行的命令。它必須是一個數組或者是多行字串
stages
stages
用來定義可以被job呼叫的stages。stages的規範允許有靈活的多級pipelines。
stages中的元素順序決定了對應job的執行順序:
1. 相同stage的job可以平行執行。
2. 下一個stage的job會在前一個stage的job成功後開始執行。
接下仔細看看這個例子,它包含了3個stage:
stages: - build - test - deploy
- 首先,所有
build
的jobs都是並行執行的。 - 所有
build
的jobs執行成功後,test
的jobs才會開始並行執行。 - 所有
test
的jobs執行成功,deploy
的jobs才會開始並行執行。 - 所有的
deploy
的jobs執行成功,commit才會標記為success
- 任何一個前置的jobs失敗了,commit會標記為
failed
並且下一個stages的jobs都不會執行。
這有兩個特殊的例子值得一提:
- 如果
.gitlab-ci.yml
中沒有定義stages
,那麼job’s stages 會預設定義為build
,test
和deploy
。 - 如果一個job沒有指定
stage
,那麼這個任務會分配到test
stage。
types
已廢除,將會在10.0中移除。用stages替代。
與stages同義
variables
GitLab Runner V0.5.0. 開始引入
GItLab CI 允許在 .gitlab-ci.yml
檔案中新增變數,並在job環境中起作用。因為這些配置是儲存在git倉庫中,所以最好是儲存專案的非敏感配置,例如:
variables: DATABASE_URL:"postgres://postgres@postgres/my_database"
這些變數可以被後續的命令和指令碼使用。服務容器也可以使用YAML中定義的變數,因此我們可以很好的調控服務容器。變數也可以定義成 job level 。
除了使用者自定義的變數外,Runner也可以定義它自己的變數。 CI_COMMIT_REG_NAME
就是一個很好的例子,它的值表示用於構建專案的分支或tag名稱。除了在 .gitlab-ci.yml
中設定變數外,還有可以通過GitLab的介面上設定私有變數。
cache
Gitlab Runner v0.7.0 開始引入。
cache
用來指定需要在job之間快取的檔案或目錄。只能使用該專案工作空間內的路徑。
從GitLab 9.0開始,pipelines和job就預設開啟了快取
如果 cache
定義在jobs的作用域之外,那麼它就是全域性快取,所有jobs都可以使用該快取。
快取 binaries
和 .config
中的所有檔案:
rspec: script: test cache: paths: - binaries/ - .config
快取git中沒有被跟蹤的檔案:
rspec: script: test cache: untracked: true
快取 binaries
下沒有被git跟蹤的檔案:
rspec: script: test cache: untracked: true paths: - binaries/
job中優先順序高於全域性的。下面這個 rspec
job中將只會快取 binaries/
下的檔案:
cache: paths: - my/files rspec: script: test cache: key: rspec paths: - binaries/
注意,快取是在jobs之前進行共享的。如果你不同的jobs快取不同的檔案路徑,必須設定不同的 cache:key ,否則快取內容將被重寫。
快取只是盡力而為之,所以別期望快取會一直存在。檢視更多詳細內容,請查閱GitLab Runner。
快取key
GitLab Runner v1.0.0 開始引入。
key
指令允許我們定義快取的作用域(親和性),可以是所有jobs的單個快取,也可以是每個job,也可以是每個分支或者是任何你認為合適的地方。
它也可以讓你很好的調整快取,允許你設定不同jobs的快取,甚至是不同分支的快取。
cache:key
可以使用任何的 預定義變數 。
預設key是預設設定的這個專案快取,因此預設情況下,每個pipelines和jobs中可以共享一切,從GitLab 9.0開始。
配置示例
快取每個job:
cache: key: "$CI_JOB_NAME" untracked: true
快取每個分支:
cache: key: "$CI_COMMIT_REF_NAME" untracked: true
快取每個job且每個分支:
cache: key: "$CI_JOB_NAME/$CI_COMMIT_REF_NAME" untracked: true
快取每個分支且每個stage:
cache: key: "$CI_JOB_STAGE/$CI_COMMIT_REF_NAME" untracked: true
如果使用的 Windows Batch (windows批處理) 來跑指令碼需要用 %
替代 $
:
cache: key: "%CI_JOB_STAGE%/%CI_COMMIT_REF_NAME%" untracked: true
Jobs
.gitlab-ci.yml
允許指定無限量jobs。每個jobs必須有一個唯一的名字,而且不能是上面提到的關鍵字。job由一列引數來定義jobs的行為。
job_name: script: - rake spec - coverage stage: test only: - master except: - develop tags: - ruby - postgres allow_failure: true
Keyword | Required | Description |
---|---|---|
script | yes | Runner執行的命令或指令碼 |
image | no | 所使用的docker映象,查閱 使用docker映象 |
services | no | 所使用的docker服務,查閱 使用docker映象 |
stage | no | 定義job stage(預設: test ) |
type | no | stage 的別名(已棄用) |
variables | no | 定義job級別的變數 |
only | no | 定義一列git分支,併為其建立job |
except | no | 定義一列git分支,不建立job |
tags | no | 定義一列tags,用來指定選擇哪個Runner(同時Runner也要設定tags) |
allow_failure | no | 允許job失敗。失敗的job不影響commit狀態 |
when | no | 定義何時開始job。可以是 on_success , on_failure , always 或者 manual |
dependencies | no | 定義job依賴關係,這樣他們就可以互相傳遞artifacts |
cache | no | 定義應在後續執行之間快取的檔案列表 |
before_script | no | 重寫一組在作業前執行的命令 |
after_script | no | 重寫一組在作業後執行的命令 |
environment | no | 定義此作業完成部署的環境名稱 |
coverage | no | 定義給定作業的程式碼覆蓋率設定 |
script
script
是Runner執行的yaml指令碼。舉個例子:
job: script: "bundle exec rspec"
該引數也可以用陣列包含多個命令:
job: script: - uname -a - bundle exec rspec
有時候, script
命令需要被單引號或者是雙引號包裹起來。舉個例子,當命令中包含冒號( :
)時,script需要被包在雙引號中,這樣YAML解析器才可以正確解析為一個字串而不是一個鍵值對(key:value)。使用這些特殊字元的時候一定要注意: :
, {
, }
, [
, ]
, ,
, &
, *
, #
, ?
, |
, -
, <
, >
, =
, !
。
stage
stage
允許一組jobs進入不同的stages。jobs在相同的 stage
時會 parallel
同時進行。查閱 stages
更多的用法請檢視 stages 。
only and except
only
和except是兩個引數用分支策略來限制jobs構建:
only except
下面是refs策略的使用規則:
-
only
和except
可同時使用。如果only
和except
在一個job配置中同時存在,則以only
為準,跳過except
(從下面示例中得出)。 -
only
和except
可以使用正則表示式。 -
only
和except
允許使用特殊的關鍵字:branches
,tags
和triggers
。 -
only
和except
允許使用指定倉庫地址但不是forks的倉庫(檢視示例3)。
在下面這個例子中, job
將只會執行以 issue-
開始的refs(分支),然而except中設定將被跳過。
job: # use regexp only: - /^issue-.*$/ # use special keyword except: - branches
在下面這個例子中, job
將只會執行有tags的refs,或者通過API觸發器明確地請求構建。
job: # use special keywords only: - tags - triggers
倉庫路徑只能用於父級倉庫執行jobs,而不是forks:
job: only: - branches@gitlab-org/gitlab-ce except: - master@gitlab-org/gitlab-ce
上面這個例子將會為所有的分支執行 job
,但master分支除外。
Job variables
在job中是可以使用關鍵字 variables
來定義job變數。它的執行原理跟 global-level 是一樣的,但是它允許設定特殊的job變數。
當設定了job級別的關鍵字 variables
,它會覆蓋全域性YAML和預定義中的job變數。想要關閉全域性變數可以在job中設定一個空陣列:
job_name: variables: []
Job變數的優先順序關係可檢視 variables文件 說明。
tags
tags
可以從允許執行此專案的所有Runners中選擇特定的Runners來執行jobs。
在註冊Runner的過程中,我們可以設定Runner的標籤,比如 ruby
, postgres
, development
。
tags
可通過tags來指定特殊的Runners來執行jobs:
job: tags: - ruby - postgres
上面這個示例中,需要確保構建此 job
的Runner必須定義了 ruby
和 postgres
這兩個tags。
allow_failure
allow_failure
可以用於當你想設定一個job失敗的之後並不影響後續的CI元件的時候。失敗的jobs不會影響到commit狀態。
當開啟了允許job失敗,所有的intents和purposes裡的pipeline都是成功/綠色,但是也會有一個”CI build passed with warnings”資訊顯示在merge request或commit或job page。這被允許失敗的作業使用,但是如果失敗表示其他地方應採取其他(手動)步驟。
下面的這個例子中, job1
和 job2
將會並列進行,如果 job1
失敗了,它也不會影響進行中的下一個stage,因為這裡有設定了 allow_failure: true
。
job1: stage: test script: - execute_script_that_will_fail allow_failure: true job2: stage: test script: - execute_script_that_will_succeed job3: stage: deploy script: - deploy_to_staging
when
when
is used to implement jobs that are run in case of failure or despite the failure.
when
可以設定以下值:
-
on_success
– 只有前面stages的所有工作成功時才執行。 這是預設值。 -
on_failure
– 當前面stages中任意一個jobs失敗後執行。 -
always
– 無論前面stages中jobs狀態如何都執行。 - “manual
– 手動執行(GitLab8.10增加)。更多請檢視 手動操作 。
舉個例子:
stages: - build - cleanup_build - test - deploy - cleanup build_job: stage: build script: - make build cleanup_build_job: stage: cleanup_build script: - cleanup build when failed when: on_failure test_job: stage: test script: - make test deploy_job: stage: deploy script: - make deploy when: manual cleanup_job: stage: cleanup script: - cleanup after jobs when: always
指令碼說明:
build_job deploy_jobs
Manual actions
GitLab 8.10 開始引入手動執行。GitLab 9.0 開始引入手動停止。GitLab 9.2 開始引入保護手動操作。
手動操作指令是不自動執行的特殊型別的job;它們必須要人為啟動。手動操作指令可以從pipeline,build,environment和deployment檢視中啟動。
部署到生產環境是手動操作指令的一個很好示例。
瞭解更多請檢視 environments documentation 。
手動操作指令可以是可選的或阻塞。在定義了手動執行的那個stage中,手動操作指令將會停止pipline中的自動執行指令。當有人通過點選play按鈕來執行需要手動執行的job時,可以來恢復pipeline的執行。
當pipeline被阻塞時,即使是pipeline是成功狀態也不會merge。被阻塞的pipelines也有一個特殊的狀態,叫 manual
。
手動操作指令預設是不阻塞的。如果你想要手動操作指令產生阻塞,首先需要在job的配置檔案 .gitlab-ci.yml
中新增 allow_failure:false
。
可選的手動操作指令預設設定 allow_failure:true
。
可選動作的狀態不影響整個pipeline的狀態。
手動操作指令被認為是寫操作,所以當前使用者觸發操作時,必須擁有操作保護分支的許可權。換句話說,為了觸發一個手動操作指令到pipeline中正在執行的指定分支,當前使用者必須擁有推送到這分支的許可權。
enviroment
注意:
- GitLab 8.9 開始引入。
- 更多關於environment說明或者示例可以檢視 documentation about environments 。
environment
用於定義job部署到特殊的環境中。如果指定了 environment
,並且沒有該名稱下的環境,則會自動建立新環境。
在最簡單的格式中,環境關鍵字可以定義為:
deploy to production: stage: deploy script: git push production HEAD:master environment: name: production
在上面這個例子中, deploy to profuction
job將會執行部署到 production
環境的操作。
environment:name
注意
- GitLab 8.11 開始引入。
- 在GitLab8.11之前,環境名稱定義為
environment:production
。現在推薦的做法是定義為name
關鍵字。
environment
名稱可以包含:
letters digits spaces - _ / $ { }
常用的名稱有 qa
, staging
,和 production
,當然你可以在你的工作流中使用任意名字。
除了在 environment
關鍵字右邊緊跟name定義方法外,也是可以為環境名稱單獨設定一個值。例如,用 name
關鍵字在 environment
下面設定:
deploy to production: stage: deploy script: git push production HEAD:master environment: name: production
environment:url
注意:
.gitlab-ci.yml
這是設定一個可選值,它會顯示在按鈕中,點選它可以帶你到設定的URL頁面。
在下面這個例子中,如果job都成功完成了,在environment/deployments頁面中將會建立一個合併請求的按鈕,它將指向 https://prod.example.com
。
deploy to production: stage: deploy script: git push production HEAD:master environment: name: production url: https://prod.example.com
environment:on_stop
注意:
- GitLab 8.13中開始 引入 。
- 從GitLab 8.14開始,當在environment中定義了一個stop操作,GitLab將會在相關聯的分支本刪除時自動觸發一個stop操作。
關閉(停止)environments可以通過在 environment
下定義關鍵字 on_stop
來實現。它定義了一個不同的job,用於關閉environment。
請檢視 environment:action
模組中例子。
environment:action
Gitlab 8.13 開始 引入 。
action
和 on_stop
聯合使用,定義在job中,用來關閉environment。
舉個例子:
review_app: stage: deploy script: make deploy-app environment: name: review on_stop: stop_review_app stop_review_app: stage: deploy script: make delete-app when: manual environment: name: review action: stop
上面這個例子中,我們定義了 review_app
job來部署到 review
環境中,同時我們也定義了一個新 stop_review_app
job在 on_stop
中。一旦 review_app
job執行完成並且成功,它將觸發定義在 when
中的 stop_review_app
job。在這種情況下,我們設定為 manual
,需要通過GitLab’s web介面來允許 manual action 。
stop_review_app
job需要定義下面這些關鍵字:
-
when
– 說明 -
environment:name
-
environment:action
-
stage
需要和review_app
相同,以便分支刪除被刪除的時候自動執行停止。
dynamic environment
注意:
$CI_ENVIRONMENT_SLUG
environment
也可以是代表配置項,其中包含 name
和 url
。這些引數可以使用任何的 CI variables (包括預定義、安全變數和 .gitlab-ci.yml
中的變數)。
舉個例子:
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
被Runner設定為 environment variable 時, deply as review app
job將會被指定部署到動態建立 revuew/$CI_COMMIT_REF_NAME
的環境中。 $CI_ENVIRONMENT_SLUG
變數是基於環境名稱的,最終組合成完整的URLs。在這種情況下,如果 deploy as review app
job是執行在名稱為 pow
的分支下,那麼可以通過URL https"//review-pw.example.com/
來訪問這個環境。
這當然意味著託管應用程式的底層伺服器已經正確配置。
常見的做法是為分支建立動態環境,並講它們作為Review Apps。可以通過 https://gitlab.com/gitlab-exa… 上檢視使用Review Apps的簡單示例。