.gitlab-ci.yml說明


在介紹.gitlab-ci.yml之前,我們先看幾個概念:

GitLab Runner

一般來說,構建任務都會占用很多的系統資源 (譬如編譯代碼),而 GitLab CI 又是 GitLab 的一部分,如果由 GitLab CI 來運行構建任務的話,在執行構建任務的時候,GitLab 的性能會大幅下降。

GitLab CI 最大的作用是管理各個項目的構建狀態,因此,運行構建任務這種浪費資源的事情就交給 GitLab Runner 來做啦。因為 GitLab Runner 可以安裝到不同的機器上,所以在構建任務運行期間並不會影響到 GitLab 的性能。

GitLab Runner的安裝特別簡單,官網有各平台的安裝方法或安裝包,此處不再贅述。

注冊

  • 打開GitLab 中的項目頁面,在項目設置中找到 runners

  • runner
    

    運行的機器上,用命令行注冊,比如:

    gitlab-runner register --name="XX" --url="https://git.xx.com/" --token="XXX" --executor="shell"

按照提示一步一步安裝就可以了。其中,executor可以是多種類型,簡單的話可以選shell。有熟悉docker的可以使用docker

  • 配置文件在/etc/gitlab-runner/config.toml

    配置項類似下面,可能需要手動添加builds_dircache_dir這兩個變量,再重啟服務

     [[runners]]
       name = "216XX"
       url = "https://git.XX.com/"
       token = "XX"
       executor = "shell"
       builds_dir = "/home/gitlab-runner/builds"
       cache_dir = "/home/gitlab-runner/cache"
       [runners.cache]
    

常見命令

    sudo gitlab-runner list 查看各個 Runner 的狀態
    sudo gitlab-runner stop 停止服務
    sudo gitlab-runner start 啟動服務
    sudo gitlab-runner restart 重啟服務

Stages

Stages 表示構建階段,說白了就是上面提到的流程。默認有3個stagesbuild, test, deploy。我們可以在一次 Pipeline 中定義多個 Stages,這些 Stages 會有以下特點:

  1. 所有 Stages 會按照順序運行,即當一個 Stage 完成后,下一個 Stage 才會開始
  2. 只有當所有 Stages 完成后,該構建任務 (Pipeline) 才會成功
  3. 如果任何一個 Stage 失敗,那么后面的Stages不會執行,該構建任務 (Pipeline) 失敗

Jobs

Jobs 表示構建工作,表示某個 Stage 里面執行的工作。我們可以在 Stages 里面定義多個 Jobs,這些 Jobs 會有以下特點:

1、相同 Stage 中的 Jobs 會並行執行

2、相同 Stage 中的 Jobs 都執行成功時,該 Stage 才會成功

3、如果任何一個 Job 失敗,那么該 Stage 失敗,即該構建任務 (Pipeline) 失敗

.gitlab-ci.yml

.gitlab-ci.yml 用來配置 CI 用你的項目中做哪些操作,這個文件位於倉庫的根目錄。

當有新內容push到倉庫,或者有代碼合並后,GitLab會查找是否有.gitlab-ci.yml文件,如果文件存在,Runners將會根據該文件的內容開始build本次commit

.gitlab-ci.yml 使用YAML語法, 你需要格外注意縮進格式,要用空格來縮進,不能用tabs來縮進。

約束

任務中必須得有script部分。

示例

# 定義 stages(階段)。任務將按此順序執行。
stages:
  - build
  - test
  - deploy

# 定義 job(任務)
job1:
  stage: test
  tags:
    - XX #只有標簽為XX的runner才會執行這個任務
  only:        
    - dev    #只有dev分支提交代碼才會執行這個任務。也可以是分支名稱或觸發器名稱
    - /^future-.*$/ #正則表達式,只有future-開頭的分支才會執行
  script:
    - echo "I am job1"
    - echo "I am in test stage"

# 定義 job
job2:
  stage: test    #如果此處沒有定義stage,其默認也是test
  only:
    - master    #只有master分支提交代碼才會執行這個任務
  script:
    - echo "I am job2"
    - echo "I am in test stage"
  allow_failure: true #允許失敗,即不影響下步構建    

# 定義 job
job3:
  stage: build
  except:    
    - dev #除了dev分支,其它分支提交代碼都會執行這個任務
  script:
    - echo "I am job3"
    - echo "I am in build stage"    
  when: always #不管前面幾步成功與否,永遠會執行這一步。它有幾個值:on_success (默認值)\on_failure\always\manual(手動執行)
    
# 定義 job
.job4:    #對於臨時不想執行的job,可以選擇在前面加個".",這樣就會跳過此步任務,否則你除了要注釋掉這個jobj外,還需要注釋上面為deploy的stage
  stage: deploy
  script:
    - echo "I am job4"    

# 模板,相當於公用函數,有重復任務時很有用
.job_template: &job_definition  # 創建一個錨,'job_definition'
  image: ruby:2.1
  services:
    - postgres
    - redis

test1:
  <<: *job_definition           # 利用錨'job_definition'來合並
  script:
    - test1 project

test2:
  <<: *job_definition           # 利用錨'job_definition'來合並
  script:
    - test2 project    

#下面幾個都相當於全局變量,都可以添加到具體job中,這時會被子job的覆蓋    

before_script:
  - echo "每個job之前都會執行"    
  
after_script:
  - echo "每個job之后都會執行"    
  
variables:    #變量
  DATABASE_URL: "postgres://postgres@postgres/my_database"  #在job中可以用${DATABASE_URL}來使用這個變量。常用的預定義變量有CI_COMMIT_REF_NAME(項目所在的分支或標簽名稱),CI_JOB_NAME(任務名稱),CI_JOB_STAGE(任務階段)
  GIT_STRATEGY: "none" #GIT策略,定義拉取代碼的方式,有3種:clone/fetch/none,默認為clone,速度最慢,每步job都會重新clone一次代碼。我們一般將它設置為none,在具體任務里設置為fetch就可以滿足需求,畢竟不是每步都需要新代碼,那也不符合我們測試的流程

cache:    #緩存
  #因為緩存為不同管道和任務間共享,可能會覆蓋,所以有時需要設置key
  key: ${CI_COMMIT_REF_NAME}  # 啟用每分支緩存。
  #key: "$CI_JOB_NAME/$CI_COMMIT_REF_NAME" # 啟用每個任務和每個分支緩存。需要注意的是,如果是在windows中運行這個腳本,需要把$換成%
  untracked: true    #緩存所有Git未跟蹤的文件
  paths:    #以下2個文件夾會被緩存起來,下次構建會解壓出來
    - node_modules/
    - dist/  

驗證gitlab-ci.yml

https://git.xx.com/ci/lint

跳過job

如果你的commit信息包涵[ci skip]或者[skip ci],不論大小寫,這個commit將會被創建,但是job會被跳過

shell問題

使用shell腳本時,每步job一開始總有不短的等待時間,對於我們而言是不必要的,除去后台jenkins_build這步外,仍要最快20分鍾。

之前,我曾在release分支時,暫時將各步整合到一個job里,時間縮短為5分鍾。當然,這是不符合語義的。

最近,發現docker沒有這個問題。所以,建議使用docker

使用docker

示例

以下是我們項目中使用的.gitlab-ci.yml文件:

image: xx:1.0

stages:
  - jenkins_build
  - install
  - test
  - build
  - e2e
  - zip
  - copy
  - end

cache:
    policy: pull
    key: "$CI_COMMIT_REF_NAME"
    paths:
        - node_modules/
        - .eslintcache

variables:
  DOCKER_DRIVER: overlay2
  GIT_STRATEGY: "fetch"

.template: &templateDef  # 創建一個錨,'template'
  only:
      - master
      - release
      - dev

install:
  stage: install
  <<: *templateDef           # 利用錨'templateDef'來合並
  cache:
      key: "$CI_COMMIT_REF_NAME"
      paths:
          - node_modules
  script:
    - cnpm i

eslint:
  stage: test
  <<: *templateDef
  script:
    - npm run eslint

unit:
  stage: test
  <<: *templateDef
  script:
    - npm run unit

build:
  stage: build
  <<: *templateDef
  only:
      - release
  script:
    - npm run clear_dist
    - npm run build

.e2e_ci:
  stage: e2e
  <<: *templateDef
  script:
    - npm run e2e_ci

zip:
  stage: zip
  <<: *templateDef
  only:
      - release
  script:
    - npm run zip

## Jenkins 復制
jenkins_copyweb:
  stage: copy
  <<: *templateDef
  only:
      - release
  script:
    - ssh $JENKINS_SERVER_IP /jenkins/XX_copyweb.sh

## Jenkins 提交
jenkins_commit:
  stage: end
  <<: *templateDef
  only:
      - release
  script:
    - ssh $JENKINS_SERVER_IP /jenkins/XX_svn_commit.sh

## Jenkins 構建
jenkins_build:
  stage: jenkins_build
  <<: *templateDef
  only:
      - master
  script:
     - ssh $JENKINS_SERVER_IP /jenkins/build.sh

其中,XX:1.0是我們自己創建的docker鏡像,它主要安裝了nodejscnpmjdksshpass,其中sshpass不是必須的,它是使用密碼登陸宿主機時的一種方案。

現在,我們使用ssh來與宿主機交互,需要將容器內生成的sshkeyssh-keygen -t rsa),即/root/.ssh/id_rsa.pub中內容,復制到宿主機的/root/.ssh/authorized_keys文件中。

配置

配置文件/etc/gitlab-runner/config.toml修改為

[[runners]]
  name = "216xx"
  url = "https://git.xx.com/"
  token = "xx"
  executor = "docker"
  [runners.docker]
    tls_verify = false
    image = "xx:1.0"
    privileged = false
    disable_cache = false
    pull_policy = "if-not-present"
    volumes = ["/cache","/tmp:/tmp:rw"]
    shm_size = 0
  [runners.cache]

其中,pull_policy是下載docker鏡像image的策略,默認會先從網上找,沒有就報錯,我們改為先從本地找;volumes是將docker中的數據卷掛載到宿主機上。

轉載:持續集成之.gitlab-ci.yml篇 - SegmentFault 思否


免責聲明!

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



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