以前有專門寫過一篇文章,對gitlab ci進行介紹,其中有涉及到gitlab-ci.yml進行介紹,那可能會有疑問,爲何要再開一篇來再說yml這玩意?html
主要是由於以前在用gitlab-ci遇到很多問題,一路上摸索不容易,雖然有前車可鑑,但仍然遇到不可描述的問題,由於想從新瞭解下這塊,當作是一個筆記;
上一篇關於gitlab ci介紹的連接:
https://juejin.im/post/5afd42be6fb9a07aaa11793fgit
由如下兩個模塊組成:
web
gitlab-ci server
gitlab-ci-runner
複製代碼
其中,gitlab-ci server負責調度、觸發Runner,以及獲取返回結果.
而gitlab-ci-runner則是主要負責來跑自動化CI(測試,編譯,打包等)。正則表達式
基本流程是:
docker
用戶提交代碼
檢查是否有.gitlab-ci.yml文件
若是無,則結束;
若是有,則調用runner執行腳本
獲取返回的結果。
複製代碼
從7.12版本開始,GitLab CI使用YAML文件(.gitlab-ci.yml)來管理項目配置。
該文件存放於項目倉庫的根目錄,它定義該項目如何構建。windows
開始構建以前YAML文件定義了一系列帶有約束說明的任務。
這些任務都是以任務名開始而且至少要包含script
部分:api
job1:
script:
- echo "jb1"
job2:
script:
- echo "jb2"
複製代碼
上面例子是一個簡單且帶有兩個獨立任務的CI配置,每一個任務分別執行echo輸出對應的內容。數組
script
能夠直接執行系統命令
(例如:./configure;make;make install)或者是直接執行腳本(test.sh)緩存
任務是由Runners接管而且由服務器中runner執行。
每個任務的執行過程都是獨立運行的。
ruby
例子1:
# 定義 stages
stages:
- build
- test
# 定義 job
job1:
stage: test
script:
- echo "I am jb1"
- echo "I am in test stage"
# 定義 job
job2:
stage: build
script:
- echo "I am jb2"
- echo "I am in build stage"
複製代碼
根據在 stages 中的定義,build 階段要在 test 階段以前運行,
因此 stage:build 的 jobs 會先運行,
以後纔會運行 stage:test 的 jobs。
再來個複雜的例子2:
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:
- docker5+4X5=25
複製代碼
下面列出保留字段,這些保留字段不能被定義爲job
名稱:
關鍵字 | 是否必須 | 描述 |
---|---|---|
image | 否 | 用於docker鏡像,查看docker文檔 |
services | 否 | 用於docker服務,查看docker文檔 |
stages | 否 | 定義構建階段 |
types | 否 | stages 的別名(已廢除) |
before_script | 否 | 定義在每一個job以前運行的命令 |
after_script | 否 | 定義在每一個job以後運行的命令 |
variable | 否 | 定義構建變量 |
cache | 否 | 定義一組文件列表,可在後續運行中使用 |
image和services
這兩個關鍵字容許使用一個自定義的Docker鏡像和一系列的服務,而且能夠用於整個job週期。
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中的元素順序決定了對應job的執行順序:
1. 相同stage的job能夠平行執行。
2. 下一個stage的job會在前一個stage的job成功後開始執行。
複製代碼
這裏劃重點:下一個stage的job會在前一個stage的job成功後開始執行,
正由於如此,因此能夠在stage設定不少相互依賴的步驟,並且不須要判斷是否成功狀態,由於能執行下來的,一定是成功的!
看會上方的例子1:
stages:
- build
- test
複製代碼
build
的job都是並行執行的build
的jobs執行成功後,test
的jobs纔會開始並行執行test
的jobs執行成功,commit纔會標記爲success
failed
而且下一個stages的jobs都不會執行。這裏提兩個特殊例子:
1.若是.gitlab-ci.yml中沒有定義stages,那麼jobs的stages會默認定義成build,test和deploy
2.若是一個job沒有指定stage,那麼這個任務會分配到test stage
複製代碼
types
已廢除,將會在10.0中移除。用stages替代,含義與stages一致
複製代碼
variable
GItLab CI 容許在.gitlab-ci.yml
文件中添加變量,並在job環境中起做用。
由於這些配置是存儲在git倉庫中,因此最好是存儲項目的非敏感配置,例如:
variables:
jb: "jb is here"
複製代碼
這裏注意,:號後面是帶上空格的,否則會說語法錯誤 這些變量能夠被後續的命令和腳本使用.
除了用戶自定義的變量外,Runner也能夠定義它本身的變量。
CI_COMMIT_REG_NAME
就是一個很好的例子,它的值表示用於構建項目的分支或tag名稱。
除了在.gitlab-ci.yml中設置變量外,還有能夠經過GitLab的界面上設置私有變量。
cache
用來指定須要在job之間緩存的文件或目錄。只能使用該項目工做空間內的路徑。
從GitLab 9.0開始,pipelines和job就默認開啓了緩存
若是cache
定義在jobs的做用域以外,那麼它就是全局緩存,全部jobs均可以使用該緩存。
緩存git中沒有被跟蹤的文件:
rspec:
script: test
cache:
untracked: true
複製代碼
緩存binaries
下沒有被git跟蹤的文件:
rspec:
script: test
cache:
untracked: true
paths:
- binaries/
複製代碼
緩存key
key
指令容許咱們定義緩存的做用域(親和性),能夠是全部jobs的單個緩存,也能夠是每一個job,也能夠是每一個分支或者是任何你認爲合適的地方。
cache:key
可使用任何的預約義變量
緩存每一個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
複製代碼
.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
複製代碼
關鍵詞 | 是否必需 | 描述 |
---|---|---|
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同時進行;
更多的用法請點擊這裏;
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狀態。
下面的這個例子中,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.
翻譯過來就是:用於實如今失敗或失敗時運行的做業。
能夠設置如下值:
on_success - 只有前面stages的全部工做成功時才執行。 這是默認值。
on_failure - 當前面stages中任意一個jobs失敗後執行。
always - 不管前面stages中jobs狀態如何都執行。
`manual ` - 手動執行。
複製代碼
舉個例子:
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
複製代碼
腳本說明:
coverage
容許你配置代碼覆蓋率將會從該job中提取輸出。
在這裏正則表達式是惟一有效的值。
所以,字符串的先後必須使用/包含來代表一個正確的正則表達式規則。特殊字符串須要轉義。
舉個例子:
job1:
coverage: '/Code coverage: \d+\.\d+/'
複製代碼
Git Strategy
GitLab 8.9中以試驗性功能引入。未來的版本中可能改變或徹底移除。GIT_STRATEGY要求GitLab Runner v1.7+。
複製代碼
能夠經過設置GIT_STRATEGY用於獲取最新的代碼,能夠再全局variables或者是在單個job的variables模塊中設置。
若是沒有設置,將從項目中使用默認值。
能夠設置的值有:clone,fetch,和none。
clone
是最慢的選項。它會從頭開始克隆整個倉庫,包含每個job,以確保項目工做區是最原始的。
variables:
GIT_STRATEGY: clone
複製代碼
當它從新使用項目工做區是,fetch
是更快(若是不存在則返回克隆)。
git clean
用於撤銷上一個job作的任何改變,git fetch
用於獲取上一個job到如今的的commit。
variables:
GIT_STRATEGY: fetch
複製代碼
none
也是從新使用項目工做區,可是它會跳過全部的Git操做(包括GitLab Runner前的克隆腳本,若是存在的話)。
它主要用在操做job的artifacts(例如:deploy)。
variables:
GIT_STRATEGY: none
複製代碼
Git Checout
當GIT_STRATEGY
設置爲clone
或fetch
時,可使用GIT_CHECKOUT
變量來指定是否應該運行git checkout
。
若是沒有指定,它默認爲true
。就像GIT_STRATEGY
同樣,它能夠設置在全局variables
或者是單個job的variables
中設置。
若是設置爲false
,Runner就會:
若是設置這個爲true將意味着clone和fetch策略都會讓Runner執行項目工做區更新到最新
variables:
GIT_STRATEGY: clone
GIT_CHECKOUT: false
script:
- git checkout master
- git merge $CI_BUILD_REF_NAME
複製代碼
Git Submodule Strategy
GIT_SUBMODULE_STRATEGY
變量用於在構建以前拉取代碼時,Git子模塊是否或者如何被引入。
它的可用值有:none,normal和recursive:
1)none意味着在拉取項目代碼時,子模塊將不會被引入。這個是默認值.
2)normal意味着在只有頂級子模塊會被引入。它至關於
git submodule sync
git submodule update --init
複製代碼
3)recursive意味着全部的子模塊(包括子模塊的子模塊)都會被引入,他至關於:
git submodule sync --recursive
git submodule update --init --recursive
複製代碼
注意:若是想要此功能正常工做,子模塊必須配置(在.gitmodules)下面中任意一個:
可訪問的公共倉庫http(s)地址,
在同一個GitLab服務器上有一個可訪問到另外的倉庫的真實地址。
複製代碼
Job stages attempts
正在執行的job將會按照你設置嘗試次數依次執行下面的stages:
變量 | 描述 |
---|---|
GET_SOURCES_ATTEMPTS | 獲取job源的嘗試次數 |
ARTIFACT_DOWNLOAD_ATTEMPTS | 下載artifacts的嘗試次數 |
RESTORE_CACHE_ATTEMPTS | 重建緩存的嘗試次數 |
默認是一次嘗試。
例子:
variables:
GET_SOURCES_ATTEMPTS: 3
複製代碼
pages
pages是一個特殊的job,用於將靜態的內容上傳到GitLab,可用於爲您的網站提供服務。
它有特殊的語法,所以必須知足如下兩個要求:
任何靜態內容必須放在public/目錄下
artifacts必須定義在public/目錄下
複製代碼
下面的這個例子是將全部文件從項目根目錄移動到public/目錄。
.public工做流是cp,而且它不會循環複製public/自己。
pages:
stage: deploy
script:
- mkdir .public
- cp -r * .public
- mv .public public
artifacts:
paths:
- public
only:
- master
複製代碼
上面在介紹variable的時候,有說起到Runner也有本身定義的變量,以下:
變量 | gitlab版本 | runner | 描述 |
---|---|---|---|
CI | all | 0.4 | 標記這個 job 是在 CI 環境執行的 |
CI_COMMIT_REF_NAME | 9.0 | all | 構建項目的 branch 或 tag 名稱 |
CI_COMMIT_REF_SLUG | 9.0 | all | $CI_COMMIT_REF_NAME小寫,除了0-9和a-z,替換爲- |
CI_COMMIT_SHA | 9.0 | all | 構建項目的 commit SHA 值 |
CI_COMMIT_TAG | 9.0 | 0.5 | 構建項目的 commit 的 tag 名,只有在構建 tags 時纔會使用。 |
CI_COMMIT_MESSAGE | 10.8 | all | 完整的提交消息。 |
CI_COMMIT_TITLE | 10.8 | all | 提交的標題——消息的完整第一行 |
CI_COMMIT_DESCRIPTION | 10.8 | all | 對提交的描述 |
CI_CONFIG_PATH | 9.4 | 0.5 | CI 配置文件路徑,默認值是 .gitlab-ci.yml |
CI_DEBUG_TRACE | all | 1.7 | 是否啓用 debug tracing 跟蹤調試功能 |
CI_DEPLOY_USER | 10.8 | all | GitLab部署令牌的身份驗證用戶名 |
CI_DEPLOY_PASSWORD | 10.8 | all | GitLab部署令牌的身份驗證密碼 |
CI_DISPOSABLE_ENVIRONMENT | all | 10.1 | 標記job 是否運行在一次性環境中 |
CI_ENVIRONMENT_NAME | 8.15 | all | 執行 job 的環境名,如 produciton,dev,pre-production 等 |
CI_ENVIRONMENT_SLUG | 8.15 | all | 環境名稱的簡化版本,適用於DNS、url、Kubernetes標籤等。 |
CI_ENVIRONMENT_URL | 9.3 | all | 執行 job 的環境 URL |
CI_JOB_ID | 9.0 | all | 當前 job 在 GitLab CI 內部的惟一 ID |
CI_JOB_MANUAL | 8.12 | all | 標識該 job 是要手動開始的 |
CI_JOB_NAME | 9.0 | 0.5 | 在 .gitlab-ci.yml 中定義的 job 名稱 |
CI_JOB_STAGE | 9.0 | 0.5 | 在 .gitlab-ci.yml 中定義的 stage 名稱 |
CI_JOB_TOKEN | 9.0 | 1.2 | 用於在GitLab容器註冊表進行身份驗證的令牌 |
CI_JOB_URL | 11.0 | 0.5 | 工做的URL |
CI_REPOSITORY_URL | 9.0 | all | 克隆 Git repository 的 URL |
CI_RUNNER_DESCRIPTION | 8.10 | 0.5 | 保存在 GitLab 中的 runner 描述 |
CI_RUNNER_ID | 8.10 | 0.5 | 正在運行的 runner 的惟一 ID |
CI_RUNNER_TAGS | 8.10 | 0.5 | 正在運行的 runner tags (標籤) |
CI_RUNNER_VERSION | all | 10.6 | 正在執行當前 job 的 GitLab Runner 版本 |
CI_RUNNER_REVISION | all | 10.6 | 正在執行當前 job 的 GitLab Runner 修訂版本 |
CI_RUNNER_EXECUTABLE_ARCH | all | 10.6 | GitLab GitLab Runner 可執行程序的 OS/架構 |
CI_PIPELINE_ID | 8.10 | 0.5 | 當前 pipeline 在 GitLab CI 內部的惟一 ID |
CI_PIPELINE_TRIGGERED | all | all | 標記這個 job 是 triggered 由觸發器觸發的 |
CI_PIPELINE_SOURCE | 10.0 | all | 標明如何觸發 pipeline 。 可用的選項有: push, web, trigger, schedule, api, and pipeline |
CI_PROJECT_DIR | all | all | 克隆下來的倉庫的完整路徑,以及 job 在哪一個目錄運行 |
CI_PROJECT_ID | all | all | 當前項目在 GitLab CI 內部的惟一 ID |
CI_PROJECT_NAME | 8.10 | 0.5 | 當前正在構建的項目名稱(其實是項目文件夾名) |
CI_PROJECT_NAMESPACE | 8.10 | 0.5 當前正在構建的項目命名空間 (用戶名或groupname) | |
CI_PROJECT_PATH | 8.10 | 0.5 | 完整的項目路徑,即命名空間+項目名 |
CI_PROJECT_PATH_SLUG | 9.3 | all | $CI_PROJECT_PATH 小寫,除了0-9和a-z,替換爲- |
CI_PIPELINE_URL | 11.0 | 0.5 | Pipeline 詳細URL |
CI_PROJECT_URL | 8.10 | 0.5 | 訪問項目的HTTP地址 |
CI_PROJECT_VISIBILITY | 10.3 | all | 項目可見性(內部、私人、公共) |
CI_REGISTRY | 8.10 | 0.5 | 若是啓用了註冊中心,它將返回GitLab的註冊表的地址 |
CI_REGISTRY_IMAGE | 8.10 | 0.5 | 若是爲項目啓用了註冊表,那麼它將返回與特定項目相關聯的登記處地址 |
CI_REGISTRY_PASSWORD | 9.0 | all | 用來將容器推到GitLab容器註冊表的密碼 |
CI_REGISTRY_USER | 9.0 | all | 用來將容器推到GitLab容器註冊表的用戶名 |
CI_SERVER | all | all | 標記CI環境中執行 |
CI_SERVER_NAME | all | all | 用於協調做業的CI服務器的名稱 |
CI_SERVER_REVISION | all | all | 用於安排工做的GitLab修訂 |
CI_SERVER_VERSION | all | all | 用於安排工做的GitLab版本 |
CI_SHARED_ENVIRONMENT | all | 10.1 | 標記工做是在共享環境中執行的 |
GET_SOURCES_ATTEMPTS | 8.15 | 1.9 | 試圖獲取運行做業的資源的次數 |
GITLAB_CI | all | all | 在GitLab CI環境中執行該做業 |
GITLAB_USER_EMAIL | 8.12 | all | 開始工做的用戶的電子郵件 |
GITLAB_USER_ID | 8.12 | all | 開始工做的用戶的id |
GITLAB_USER_LOGIN | 10.0 | all | 啓動該工做的用戶的登陸用戶名 |
GITLAB_USER_NAME | 10.0 | all | 啓動工做的用戶的真實姓名 |
RESTORE_CACHE_ATTEMPTS | 8.15 | 1.9 | 試圖休息的次數 |
由於沒有漢化版,所以都是拿到網上翻譯的,大體瞭解就行,詳細信息,能夠看官網的介紹:
https://docs.gitlab.com/ce/ci/variables/README.html
不過從上面runner本身定義的變量,是真的有不少很實用的變量,以前寫腳本都是沒有用變量,本身造輪子的~
本文主要介紹了.gitlab-ci.yml一些經常使用的指令,比較經常使用的就是jobs,stages跟runner本身定義的變量,其餘的能夠先了解;
就介紹到這裏吧,主要介紹經常使用的,剩下的,能夠去官網瞭解下:
https://docs.gitlab.com/ce/ci/yaml/README.html
下篇文章會介紹,怎麼在gitlab ci上獲取每次提交的信息,而且發送到釘釘通知,這塊也不難,感興趣的同窗能夠想一想怎麼作;
謝謝你們~