之前在《GitLab 簡單的 C++ 專案腳本範例》和《GitLab 的 C++ CI/CD 腳本:使用 PowerShell》這兩篇文章,有分享了 Heresy 這邊目前 GitLab CI/CD 的腳本寫法了。
而當時也有提到,在 build 階段到 test 階段,Heresy 沒有玩出比較正規的檔案傳遞方法。
最近 Heresy 又開始測試這部分的東西。理論上,要在不同的 job 間傳遞檔案,是要透過在 .gitlab-ci.yml 裡面加上 cache(官網)來做。
在有加入 cache 的狀況下,GitLab Runner 會在 job 開始、透過 git 取得檔案後,就試著把 cahce 的檔案抓下來;而當腳本執行完後,則會再把 cache 指定的檔案打包,放到 Gitlab-runner 上。
Heresy 目前加上 cache 後的 .gitlab-ci.yml 大致上會像下面這樣:
stages: - build - test build-linux: stage: build variables: GIT_SUBMODULE_STRATEGY: none script: - git submodule sync --recursive - git submodule update --recursive --init --remote external_linux - make -j cache: key: "linux-$CI_COMMIT_REF_SLUG" policy: push paths: - bin64/ - lib64/*.a tags: - gcc test-linux: stage: test variables: GIT_SUBMODULE_STRATEGY: none script: - echo testing... cache: key: "linux-$CI_COMMIT_REF_SLUG" policy: pull paths: - bin64/ - lib64/*.a tags: - gcc
這邊可以看到,在 cache 下有 key、policy 和 paths 三個參數。其中 key 是用來區隔 cache 的,key 的值一樣的話,那檔案會被後面的 job 取代。
policy 則是可以用來設定 cache 的動作;如果是 push 的話,就不會去抓之前的檔案,而如果是 pull 的話,則不會把檔案上傳。
像這邊建置階段之前沒有需要使用的 cache,所以就設定成 push;測試階段也只需要取得建置階段的檔案、而不需要把檔案再做快取,所以就設定成 pull 。
而 path 的部分,就是指定要快取的檔案了。
理論上這樣的腳本寫法應該是沒錯的,但是 Heresy 這邊在測試的時候,卻會一直出現「Skipping cache archiving due to empty cache key
」這個錯誤訊息…
本來 Heresy 一直以為是 .gitlab-ci.yml 裡面的 cache 的 key 沒給好,但是後來又研究了好一陣子,才發現這個錯誤和 .gitlab-ci.yml 的內容根本無關,而是 GitLab Runner 需要額外設定 cache_dir 才行(參考)。
gitlab-runner 在設定好之後,會把相關的設定資料儲存在 config.toml 這個檔案裡(參考);Windows 的檔案會和執行檔在一起,Linux 則是會放在 /etc/gitlab-runner/config.toml。
而要讓 cache 可以正常運作的話,這邊至少要在 [[runners]] 的區塊下,加入 builds_dir 和 cache_dir,指定相關的路徑。
例如:
[[runners]] ... executor = "shell" builds_dir = "/mnt/codebuild/gitlab-runner/" cache_dir = "/mnt/codebuild/gitlab-runner/cache/"
不過另一方面,在只有指定 cache_dir 的狀況下,cache 只能在同一個 runner 上傳遞、而沒辦法跨不同的 runner…如果要能跨 Runner 的話,那就需要 S3 或 GCS 才行了…
這樣修改好了之後,前面的 CI/CD 腳本就可以正常運作了。在 job 的紀錄裡面,也會看到類似下面的訊息:
Version: 12.1.0 Git revision: de7731dd Git branch: 12-1-stable GO version: go1.8.7 Built: 2019-07-19T13:52:54+0000 OS/Arch: windows/amd64 Checking cache for windows-enginev2-1... Runtime platform arch=amd64 os=windows pid=8720 revision=de7731dd version=12.1.0 No URL provided, cache will not be downloaded from shared cache server. Instead a local version of cache will be extracted. Successfully extracted cache
理論上,這樣至少可以解決同一台 runner 上的檔案傳遞。但是如果真的要增加 runner 的數量、並讓 cache 可以跨 runner 的話,那大概還是得自己搞一個 S3 server 起來玩了…