Gitlab持續集成-(.gitlab-ci.yml)

從7.12版本開始,GitLab CI使用YAML文件(.gitlab-ci.yml)來管理項目配置。該文件存放於項目倉庫的根目錄,它定義該項目如何構建。

stages

stages用來定義可以被job調用的stages。stages的規範允許有靈活的多級pipelines。stages中元素的順序決定了對應job的執行順序:

  • 相同stage的job是並行執行的;
  • 下一個stage的job在前一個stage的job成功完成後纔開始執行;
  • 如果.gitlab-ci.yml中沒有定義stages,那麼stages默認定義爲build、test和deploy;
  • 如果一個job沒有指定stage,那麼這個任務會分配到test stage。

variables

variables用來定義變量,全局變量作用於所有job,也可以在指定的job中定義變量(優先級高於全局變量)
如果在job中想禁用全局定義的變量,可通過variables: {}定義一個空的哈希值。

GitLab CI/CD內置變量

variables 變量值
CI_JOB_NAME 對應的job_name
GIT_STRATEGY 指定git獲取代碼的方式(clone,fetch,none)

jobs

jobs用來定義了一組作業,其中必須包含script語句。

job.stage(默認:test

job中指定的stage必須是stages中存在的元素

job.tags

指定該job所允許運行的Runner,必須在註冊Runner時設置Runner的tag

job.allow_failure

用於指定該job允許執行失敗,則如果執行失敗也不會影響下一個stage的執行。

job.script

script是job中必須指定的語句,指定Runner所要執行的命令

job.before_script、job.after_script

指定script執行前/後所執行的命令,也可定義在全局模式,則在所有job中的script執行前/後都會執行。

job.artifacts

用於指定job執行成功後,將會被髮送到Gitlab中的文件,且默認情況下job之間會根據stage的優先級自動下載之前所有stage中的artifacts。

  • artifacts.paths:必選
  • artifacts.name:指定artifact的名稱,同時Gitlab上下載的文件名即爲artifact_name.zip
  • artifacts.when:指定artifact上傳到Gitlab的條件(on_success[默認],on_failure,always)
  • artifacts.expire_in:指定artifact的過期時間(默認爲30天),使用keep可永久保存

job.dependencies

dependencies用於在不同的job之間指定在不同的job之間傳遞artifacts,dependencies: []可禁止該job下載artifacts

job.only、job.except

onlyexcept是兩個參數用分支策略來限制jobs構建

  • onlyexcept可同時使用。如果在一個job配置中同時存在,則同時有效;
  • onlyexcept可以使用正則表達式;
  • onlyexcept允許使用特殊的關鍵字:branchestagstriggers

job.environment

environment用於定義job部署到指定的運行環境中。

  • environment.name:必選,指定environment名稱
  • environment.url:可選,指定environment對應的URL,將在指定的environment頁面中添加一個鏈接按鈕指向該URL

特殊的YAML特性

<span id = "jump"> Hidden keys(jobs)</span>

如果想臨時disable某個job,不必註釋整個job定義的行,只需在job name前加一個.即可

.compile_centos:
  stage: build_centos
  tags:
    - centos
  script:
    - echo "##### build library"

Anchors

錨點可用於在文件中複製或繼承配置,一般與Hidden keys(jobs)提供的job模版搭配使用。

.job_template: &job_definition  #job中定義一個anchor:job_definition
  image: ruby:2.1
  services:
    - postgres
    - redis
test1:
  <<: *job_definition           #合併anchor:job_definition中的模版內容
  script:
    - test1 project
test2:
  <<: *job_definition
  script:
    - test2 project

最終實現的效果如下:

.job_template:
  image: ruby:2.1
  services:
    - postgres
    - redis
test1:
  image: ruby:2.1
  services:
    - postgres
    - redis
  script:
    - test1 project
test2:
  image: ruby:2.1
  services:
    - postgres
    - redis
  script:
    - test2 project

Skipping jobs

如果你的commit信息中包含[ci skip]或者[skip ci],不論大小寫,那麼這個commit將會創建但是jobs也會跳過。


example:

以下示例爲編譯nginx的上傳模塊nginx-upload並測試驗證上傳功能,驗證成功後將自動將編譯好的文件打包通過curl上傳到指定的文件服務器。其中只有在非master的branches中提交代碼纔會執行build和test的stage,只有在打tag後纔會執行deploy,且需要手動在gitlab上執行。

variables:
  DIR: nginx
  TOPNODE: package

.function: &function |
  function build() {
    echo "execute function:build"
    chmod +x auto/configure
    sh build.sh
  }

  function changelog() {
    echo "execute function:changelog"
    git log --graph -n 3  --name-status --pretty="%h -[%cd] - <%an> %s" > CHANGELOG
  }

  function test() {
    echo "execute function:test"

    sudo \cp modules/nginx-upload-module-master/nginx.conf /etc/nginx/nginx.conf
    sudo sed -i '/error_log/,/working_directory/d' /etc/nginx/nginx.conf
    if [ -f /run/nginx.pid ];then sudo nginx -s reload;else sudo nginx;fi
    sudo rm -rf /tmp/{0,1,2,3,4,5,6,7,8,9} && sudo mkdir /tmp/{0,1,2,3,4,5,6,7,8,9} && sudo chown -R nginx. /tmp/{0,1,2,3,4,5,6,7,8,9}
    sudo echo nginx_upload > test && curl -F "filename=@test" http://localhost/upload
    sudo find /tmp/{0,1,2,3,4,5,6,7,8,9} -type f -exec grep nginx_upload {} \; 
  }

  function artifacts() {
    echo "execute function:artifacts"
    URL="https://xxx.com/upload?dir=${DIR}/${VERSION}&override=1&topNode=${TOPNODE}"

    echo "push the artifacts:nginx_${VERSION}.tar.gz to $URL"
    tar zcf /tmp/nginx_${VERSION}.tar.gz --exclude=".git*" --exclude=build .
    curl -F "filename=@/tmp/${DIR}_${VERSION}.tar.gz" "$URL"

    echo "push the CHANGELOG to $URL"
    curl -F "filename=@CHANGELOG" "$URL"
  }

  function deploy() {
    echo "execute function:deploy"
  }

  function clean() {
    echo "execute function:clean"
    if [ -f /run/nginx.pid ];then sudo kill `cat /run/nginx.pid`;fi
    sudo rm -rf /tmp/{0,1,2,3,4,5,6,7,8,9} /tmp/nginx_${version}.tar.gz
  }

#########only the section above need to be modify #################
before_script:
  - VERSION=`head -n1 version`
  - *function

stages:
  - build
  - test
  - deploy

build:
  stage: build
  only:
    - branches
  except:
    - master
  script:
    - build
    - changelog

test:
  stage: test
  variables:
    GIT_STRATEGY: none
  only:
    - branches
  except:
    - master
  script:
    - test
    - artifacts
    - clean

.job_template: &deploy_template
  stage: deploy
  variables:
    GIT_STRATEGY: none
  only:
    - tags
  script:
    - deploy
    - delete
  when: manual

staging:
  <<: *deploy_template
  environment:
    name: staging

production:
  <<: *deploy_template
  environment:
    name: production
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章