JB的git之旅--.gitlab-ci.yml介紹

前言

以前有專門寫過一篇文章,對gitlab ci進行介紹,其中有涉及到gitlab-ci.yml進行介紹,那可能會有疑問,爲何要再開一篇來再說yml這玩意?html

主要是由於以前在用gitlab-ci遇到很多問題,一路上摸索不容易,雖然有前車可鑑,但仍然遇到不可描述的問題,由於想從新瞭解下這塊,當作是一個筆記;
上一篇關於gitlab ci介紹的連接:
https://juejin.im/post/5afd42be6fb9a07aaa11793fgit

gitlab-ci運行介紹

由如下兩個模塊組成:
web

gitlab-ci server
gitlab-ci-runner
複製代碼

其中,gitlab-ci server負責調度、觸發Runner,以及獲取返回結果.
而gitlab-ci-runner則是主要負責來跑自動化CI(測試,編譯,打包等)。正則表達式

基本流程是:
docker

用戶提交代碼
檢查是否有.gitlab-ci.yml文件
若是無,則結束;
若是有,則調用runner執行腳本
獲取返回的結果。
複製代碼

.gitlab-ci.yml

從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
複製代碼
    1. 首先,全部build的job都是並行執行的
    1. 全部build的jobs執行成功後,test的jobs纔會開始並行執行
  • 3.全部的test的jobs執行成功,commit纔會標記爲success
  • 4.任何一個前置的jobs失敗了,commit都會標記爲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
複製代碼

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
複製代碼
關鍵詞 是否必需 描述
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
複製代碼

腳本說明:

  • 只有當build_job失敗的時候纔會執行`cleanup_build_job 。
  • 無論前一個job執行失敗仍是成功都會執行`cleanup_job 。
  • 能夠從GitLab界面中手動執行deploy_jobs。

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設置爲clonefetch時,可使用GIT_CHECKOUT變量來指定是否應該運行git checkout
若是沒有指定,它默認爲true。就像GIT_STRATEGY同樣,它能夠設置在全局variables或者是單個job的variables中設置。

若是設置爲false,Runner就會:

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

若是設置這個爲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
複製代碼

Runner 定義的變量

上面在介紹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上獲取每次提交的信息,而且發送到釘釘通知,這塊也不難,感興趣的同窗能夠想一想怎麼作;

謝謝你們~

相關文章
相關標籤/搜索