3.4 pipeline syntax 4

cache 緩存

用來指定需要在job之間緩存的文件或目錄。只能使用該項目工作空間內的路徑。不要使用緩存在階段之間傳遞工件,因爲緩存旨在存儲編譯項目所需的運行時依賴項。

如果在job範圍之外定義了cache ,則意味着它是全局設置,所有job都將使用該定義。如果未全局定義或未按job定義則禁用該功能。

cache:paths

使用paths指令選擇要緩存的文件或目錄,路徑是相對於項目目錄,不能直接鏈接到項目目錄之外。

$CI_PROJECT_DIR 項目目錄

在job build中定義緩存,將會緩存target目錄下的所有.jar文件。

build:
  script: test
  cache:
    paths:
      - target/*.jar

當在全局定義了cache:paths會被job中覆蓋。以下實例將緩存binaries目錄。

cache:
  paths:
    - my/files

build:
  script: echo "hello"
  cache:
    key: build
    paths:
      - target/

由於緩存是在job之間共享的,如果不同的job使用不同的路徑就出現了緩存覆蓋的問題。如何讓不同的job緩存不同的cache呢?設置不同的cache:key


cache:key 緩存標記

爲緩存做個標記,可以配置job、分支爲key來實現分支、作業特定的緩存。爲不同 job 定義了不同的 cache:key 時, 會爲每個 job 分配一個獨立的 cache。cache:key變量可以使用任何預定義變量,默認default ,從GitLab 9.0開始,默認情況下所有內容都在管道和作業之間共享。

按照分支設置緩存

cache:
  key: ${CI_COMMIT_REF_SLUG}

files: 文件發生變化自動重新生成緩存(files最多指定兩個文件),提交的時候檢查指定的文件。

根據指定的文件生成密鑰計算SHA校驗和,如果文件未改變值爲default。

cache:
  key:
    files:
      - Gemfile.lock
      - package.json
  paths:
    - vendor/ruby
    - node_modules

prefix: 允許給定prefix的值與指定文件生成的祕鑰組合。

在這裏定義了全局的cache,如果文件發生變化則值爲 rspec-xxx111111111222222 ,未發生變化爲rspec-default。

cache:
  key:
    files:
      - Gemfile.lock
    prefix: ${CI_JOB_NAME}
  paths:
    - vendor/ruby

rspec:
  script:
    - bundle exec rspec

例如,添加$CI_JOB_NAME prefix將使密鑰看起來像: rspec-feef9576d21ee9b6a32e30c5c79d0a0ceb68d1e5 ,並且作業緩存在不同分支之間共享,如果分支更改了Gemfile.lock ,則該分支將爲cache:key:files具有新的SHA校驗和. 將生成一個新的緩存密鑰,併爲該密鑰創建一個新的緩存. 如果Gemfile.lock未發生變化 ,則將前綴添加default ,因此示例中的鍵爲rspec-default 。


cache:policy 策略

默認:在執行開始時下載文件,並在結束時重新上傳文件。稱爲” pull-push緩存策略.

policy: pull 跳過下載步驟

policy: push 跳過上傳步驟

stages:
  - setup
  - test

prepare:
  stage: setup
  cache:
    key: gems
    paths:
      - vendor/bundle
  script:
    - bundle install --deployment

rspec:
  stage: test
  cache:
    key: gems
    paths:
      - vendor/bundle
    policy: pull
  script:
    - bundle exec rspec ...

綜合實例(一) 全局緩存

before_script:
  - echo "before-script!!"

variables:
  DOMAIN: example.com

cache: 
  paths:
   - target/

stages:
  - build
  - test
  - deploy
  
build:
  before_script:
    - echo "before-script in job"
  stage: build
  tags:
    - build
  only:
    - master
  script:
    - ls
    - id
    - mvn clean package -DskipTests
    - ls target
    - echo "$DOMAIN"
    - false && true ; exit_code=$?
    - if [ $exit_code -ne 0 ]; then echo "Previous command failed"; fi;
    - sleep 2;
  after_script:
    - echo "after script in job"


unittest:
  stage: test
  tags:
    - build
  only:
    - master
  script:
    - echo "run test"
    - echo 'test' >> target/a.txt
    - ls target
  retry:
    max: 2
    when:
      - script_failure
  
deploy:
  stage: deploy
  tags:
    - build
  only:
    - master
  script:
    - echo "run deploy"
    - ls target
  retry:
    max: 2
    when:
      - script_failure
      

after_script:
  - echo "after-script"


Pipeline日誌分析

build作業運行時會對項目代碼打包,然後生成target目錄。作業結束創建緩存。

images 

 

開始第二個作業test,此時會把當前目錄中的target目錄刪除掉(因爲做了git 對比)。

images

獲取到第一個作業生成的緩存target目錄。

images

開始第三個作業,同樣先刪除了target目錄,然後獲取了第二個作業的緩存。最後生成了當前的緩存。

 

images 


Runner緩存

在做本次實驗的時候我現在本地runner清除了項目的工作目錄和歷史緩存。

[root@zeyang-nuc-service ~]# cd /home/gitlab-runner/builds/1Cxihk7-/0/demo/demo-maven-service/
[root@zeyang-nuc-service demo-maven-service]# ls
Jenkinsfile  README.md  aaaaa  jenkins  pom.xml  src  target
[root@zeyang-nuc-service demo-maven-service]# cd ..
[root@zeyang-nuc-service demo]# ls
demo-maven-service  demo-maven-service.tmp
[root@zeyang-nuc-service demo]# rm -fr demo-maven-service
[root@zeyang-nuc-service demo]# rm -fr demo-maven-service.tmp/
[root@zeyang-nuc-service demo]# cd
[root@zeyang-nuc-service ~]# cd /home/gitlab-runner/cache/
[root@zeyang-nuc-service cache]# ls
demo
[root@zeyang-nuc-service cache]# rm -rf *

項目代碼默認不會刪除,可以發現是第二次作業的緩存。(因爲上面的例子中第三次作業並沒有修改緩存內容)

[root@zeyang-nuc-service cache]# cd /home/gitlab-runner/builds/1Cxihk7-/0/demo/demo-maven-service/
[root@zeyang-nuc-service demo-maven-service]# ls
Jenkinsfile  README.md  aaaaa  jenkins  pom.xml  src  target
[root@zeyang-nuc-service demo-maven-service]# cd ..
[root@zeyang-nuc-service demo]# ls
demo-maven-service  demo-maven-service.tmp
[root@zeyang-nuc-service demo]# rm -fr *
[root@zeyang-nuc-service demo]# ls
[root@zeyang-nuc-service demo]# ls
demo-maven-service  demo-maven-service.tmp
[root@zeyang-nuc-service demo]# cd demo-maven-service
[root@zeyang-nuc-service demo-maven-service]# ls
Jenkinsfile  README.md  aaaaa  jenkins  pom.xml  src  target
[root@zeyang-nuc-service demo-maven-service]# cat target/a.txt
test

進入runner緩存目錄中查看緩存。

[root@zeyang-nuc-service ~]# cd /home/gitlab-runner/cache/demo/demo-maven-service/default/
[root@zeyang-nuc-service default]# ls
cache.zip
[root@zeyang-nuc-service default]# unzip cache.zip
Archive:  cache.zip
   creating: target/
  inflating: target/a.txt
   creating: target/classes/
   creating: target/classes/com/
   creating: target/classes/com/mycompany/
   creating: target/classes/com/mycompany/app/
  inflating: target/classes/com/mycompany/app/App.class
   creating: target/maven-archiver/
  inflating: target/maven-archiver/pom.properties
   creating: target/maven-status/
   creating: target/maven-status/maven-compiler-plugin/
   creating: target/maven-status/maven-compiler-plugin/compile/
   creating: target/maven-status/maven-compiler-plugin/compile/default-compile/
  inflating: target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
  inflating: target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
   creating: target/maven-status/maven-compiler-plugin/testCompile/
   creating: target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/
  inflating: target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst
  inflating: target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
  inflating: target/my-app-1.1-SNAPSHOT.jar
   creating: target/test-classes/
   creating: target/test-classes/com/
   creating: target/test-classes/com/mycompany/
   creating: target/test-classes/com/mycompany/app/
  inflating: target/test-classes/com/mycompany/app/AppTest.class
[root@zeyang-nuc-service default]# ls
cache.zip  target
[root@zeyang-nuc-service default]# cd target/
[root@zeyang-nuc-service target]# ls
a.txt  classes  maven-archiver  maven-status  my-app-1.1-SNAPSHOT.jar  test-classes
[root@zeyang-nuc-service target]# cat a.txt
test

此時此刻再次運行流水線作業,第一個作業用的是上個作業最後生成的緩存。

images

進入runner緩存目錄查看,cache.zip時間已經發生的變化。

[root@zeyang-nuc-service default]# ll
total 12
-rw------- 1 gitlab-runner gitlab-runner 9172 Apr 29 10:27 cache.zip
drwxrwxr-x 6 root          root           127 Apr 29 10:05 target

結論: 全局緩存生效於未在作業中定義緩存的所有作業,這種情況如果每個作業都對緩存目錄做了更改,會出現緩存被覆蓋的場景。


綜合實例(二)

控制緩存策略

例如build階段我們需要生成新的target目錄內容,可以優化設置job運行時不下載緩存。

images

before_script:
  - echo "before-script!!"

variables:
  DOMAIN: example.com

cache: 
  paths:
   - target/

stages:
  - build
  - test
  - deploy
  
build:
  before_script:
    - echo "before-script in job"
  stage: build
  tags:
    - build
  only:
    - master
  script:
    - ls
    - id
    - cat target/a.txt
    - mvn clean package -DskipTests
    - ls target
    - echo "$DOMAIN"
    - false && true ; exit_code=$?
    - if [ $exit_code -ne 0 ]; then echo "Previous command failed"; fi;
    - sleep 2;
  after_script:
    - echo "after script in job"
  cache:
    policy: pull   #不下載緩存


unittest:
  stage: test
  tags:
    - build
  only:
    - master
  script:
    - echo "run test"
    - echo 'test' >> target/a.txt
    - ls target
    - cat target/a.txt
  retry:
    max: 2
    when:
      - script_failure
  
deploy:
  stage: deploy
  tags:
    - build
  only:
    - master
  script:
    - cat target/a.txt
    - echo "run deploy"
    - ls target
    - echo "deploy" >> target/a.txt
  retry:
    max: 2
    when:
      - script_failure
      

after_script:
  - echo "after-script"
  
  

一起學習呀:

 

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