--- title: Tips to GitLabCI tags: Git --- # Gitlab-Runner https://docs.gitlab.com/runner/ ## Register a runner instance ### system mode ```bash= sudo gitlab-runner register ``` - conf_path: ==/etc/gitlab-runner/config.toml== ### user mode ```bash= gitlab-runner register ``` - conf_path: ==$HOME/.gitlab-runner/config.toml== :::info 定義 tag 時可以以逗號隔開寫入多個tags, 但若要指定這個 runner 也必須明確宣告所有 tags ::: :::warning :+1: 使用 user-mode 可能在 `mkdir` 會權限不足 (i.e., mkdir ~/builds) ::: ## Run ```bash= sudo gitlab-runner run # system-mode gitlab-runner run # user-mode ``` ### (Option) serve as a service ```bash= sudo gitlab-runner install -n "<service-name>" -u <user-name> sudo gitlab-runner start -n "<service-name>" ``` ## Executor 最常用的是 Docker excecutor 和 Shell exceutor 這些 runner 實際的執行目錄為: ``` <working-directory>/builds/<short-token>/<concurrent-id>/<namespace>/<project-name> ``` cache 位置為: ``` <working-directory>/cache/<namespace>/<project-name> ``` ### Docker Excecutor https://docs.gitlab.com/runner/install/docker.html#upgrade-version > 預設是在 container 內以 system-mode 運行 default `/home`: ``` /root/ ``` default build_dir: ``` /var/lib/docker/volumes/<volume-id>/_data/<project-name> ``` default cache_dir: ``` /cache/ ``` #### how to achieve persistent volume ? within `/etc/gitlab-runner/config.toml`(system-mode): ```yaml= [runner.docker] volumes = ["/cache", "<host_dir:container_dir>:rw"] ``` #### Install the docker image and get started ```bash= docker run -d \ --name gitlab-runner \ --restart always \ -v /etc/gitlab-runner:/etc/gitlab-runner \ -v /var/run/docker.sock:/var/run/docker.sock \ gitlab/gitlab-runner:latest ``` #### Register gitlab-runner ```bash= docker run \ --rm -it \ -v /etc/gitlab-runner:/etc/gitlab-runner \ gitlab/gitlab-runner register ``` #### Verify & delete dead gitlab-runner ```bash= docker run \ --rm -it \ -v /etc/gitlab-runner:/etc/gitlab-runner \ gitlab/gitlab-runner verify --delete ``` # Predefined variables reference https://docs.gitlab.com/ee/ci/variables/predefined_variables.html 定義常用的 system param,能讓 `.gitlab-ci.yml` 更易讀。 ### CI_PROJECT_NAME The name of the directory for the project. ### CI_COMMIT_REF_NAME The branch or tag name for which project is built. ### CI_COMMIT_BRANCH The commit branch name. # Dependencies in GitLab CI/CD https://docs.gitlab.com/ee/ci/caching/ ## cache vs artifacts | cache | artifacts | | -------- | -------- | | For storing project dependencies | Use for stage results that are passed between stages | |cache per job by using `cache:`|artifacts per job| |key, policy(pull,push), paths|paths| |隨後的==pipelines==可以使用|隨後同一個 pipeline上的 ==jobs== 可以使用| |Different projects cannot share| Different projects cannot share| | 取決於機器有沒有生成過 cache | 會上傳 gitlab, 之後從 gitlab 下載 | | 可能不是最新的,可以禁用(`cache: {}`) | 每次都去下載, 可以禁用(`dependencies: []`) | |不會自動清理, 需要定期清除|可以設置自動過期時間(default 30d)| :::danger :warning: the cache might be overwritten because caches are restored before artifacts. - [Get Started] ==> [caches] ==> [artifacts] ==> [Running] ::: :::info 每一次新的push trigger pipeline, 都會重新生成 cache `<cache-key>-<num>` 如果不去清除cache, cache 會永久保留在 Runner 上 ==cache 需要定期清除== ::: :::warning paths主要是来指定需要被缓存的文件路径,需要特别指出的是这里的 paths 是相对路径,是相对于gitlab中项目目录的路径,也就是说被缓存的文件都是在项目目录之内的。 ::: cache source: - https://docs.gitlab.com/ee/ci/caching/ - https://zhuanlan.zhihu.com/p/106971627 ## dependencies Restrict which artifacts are passed to a specific job by providing a list of jobs to fetch artifacts from. > 定義在 `job` 內, 用來指定要使用哪個 `job` 中 `artifacts` 內的路徑。 ```yaml= installing-dependencies: stage: prepare script: - composer install --prefer-dist --optimize-autoloader -n --no-interaction -v --no-suggest - composer dump-autoload --optimize artifacts: name: "vendor" untracked: true expire_in: 60 mins paths: - $CI_PROJECT_DIR/vendor code-review: stage: testing dependencies: - installing-dependencies script: - php vendor/bin/phpcs --config-set ignore_warnings_on_exit 1 - php vendor/bin/phpcs --standard=PSR2 -w --colors ./ ``` ## 禁用 artifacts 默認 artifacts 會自動在不同 stages 上傳輸, 以下配置可以避免多餘的建置時間 ```yaml= dependencies: [] ``` ## SSH amid gitlab-ci runner ```yaml= # Install ssh-agent - 'command -v ssh-agent >/dev/null || ( apt-get update -y && apt-get install openssh-client -y )' # Run ssh-agent - eval $(ssh-agent -s) # Add the SSH key - echo "$CONSOLE_PEM_KEY" | tr -d '\r' | ssh-add - # create ~/.ssh directory - mkdir -p ~/.ssh # All permission to user (gitlab-runner) - chmod 700 ~/.ssh # avoid checking when ssh connection - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config' ``` :::danger docker executor (image: ruby:2.6) would be failed. shell executor 執行的是 ubuntu image. ::: # Issue ## Pseudo-terminal will not be allocated because stdin is not a terminal 禁止分配偽終端-使用ssh -T -> 不互動 強制分配偽終端-使用ssh -t 或 ssh -tt -> 互動 ## docker excecutor 內 build image 直白講就是在 container 內建立 container 會遇到問題 :::danger Cannot connect to the Docker daemon at unix:///var/run/docker.sock. ::: Resolve: 配置 `config.toml` ```yaml= volumes = ["/var/run/docker.sock:/var/run/docker.sock"] ``` ## docker executor 內 git clone 跟上面做法一樣, 把 secret 掛載進去 ```yaml= volumes = ["/home/x1twbm/.ssh:/root/.ssh:ro"] ``` # Reference - https://docs.gitlab.com/ee/ci/ssh_keys/ - http://zacksleo.top/2017/04/18/GitLab-CI%E4%B8%AD%E7%9A%84artifacts%E4%BD%BF%E7%94%A8%E7%A0%94%E7%A9%B6/ - https://www.jianshu.com/p/19fe0ce7ecec