lyonger

網易資深運維工程師,先後負責過多個遊戲產品的運維工作,多年運維生涯。負責遊戲 CI/CD、遊戲上雲、gitlab 平臺維護等工作。主要關注 Linux 性能優化、DevOps、雲原生領域。探索和分享是一趟美好的旅程。

1. 環境說明

本文提到的社區版本和企業版本信息如下:

  • 社區版本:GitLab Community Edition 11.11.4

  • 企業版本:GitLab Enterprise Edition 12.6.7

注意:本文中有註明企業版 (Starter) 才支持的地方代表只有企業版 (Starter) 才支持。否則默認就是社區版也支持該特性。企業版的收費標準請參考官網:https://about.gitlab.com/pricing

2. Git Flow 簡介

經典的 git flow 圖中,有 Master、Hotfix、Release、Develop、Feature 等分支。每個分支的作用各不相同。各個分支的主要功能如下:

3. Gitlab Code Review 方式

一共有 2 種 常見的方式來進行 gitlab 的 code review,本文主要介紹 遠程方式 的使用。

  • 本地方式:在本地將源分支 (Source branch) 代碼合併到目標分支(Target branch),然後 Push 到遠程的目標分支(Target branch)。

  • 遠程方式:將源分支 (Source branch) Push 到遠端,然後在 GitLab 前端指定目標分支(Target branch)發起 Merge Request,對目標分支(Target branch)擁有 Push 權限的用戶執行 Merge 操作,完成合並。 

4. Gitlab Code Review 配置

在 Code Review 執行之前,進行一些合理的配置會有事半功倍的效果,下面我們來談談有助於 Code Review 常見功能。

4.1 Approvals 與 Merge Request 定製功能

可對 Merge Request 進行定製,如下圖,要求 MR 可點擊合併的條件是:pipeline 必須返回成功,同時所有 discussions 已被標記爲 resolved。其中默認刪除源分支的功能只有 企業版 (Starter) 才支持。

關於審覈員規則 (該功能只有 企業版 才支持),這裏推薦按照團隊的情況進行定製:一種是核心成員,經驗豐富,對成員代碼把關;另一種是,新人團隊,隨機抽取,互相監督,互相學習。

4.2 Issue 與 Merge Request 的模版功能

在開發流程比較固定的情況下,我們可以對 issue 和 Merge Request 的內容格式進行模版化,如下圖,我們以 code_review/project1 這個 repo 爲例,在倉庫根目錄下新增了 .gitlab/issue_templates/Issue.md 和 .gitlab/merge_request_templates/Merge_Request.md 兩個文件,分別代表設置 issue 和 Merge Request 的模版內容。詳細說明可參考官方說明 (https://docs.gitlab.com/ee/user/project/description_templates.html#overview)。

issue 的模版效果如下圖所示:

Merge Request 的模版效果如下圖所示:

4.3 Issue 與 Merge Request 的聯動功能

當提交到 master 默認分支時,gitlab 支持提交信息帶上:關鍵詞 + issue 編號來聯動 issue( 注意關鍵字後面必須跟上一個空格 )。常見的關鍵字 style=fix/fixes/fixed、close/closes/closed、resolve/resolves/resolved

issue 編號可以參考下圖:

4.3.1 案例參考

下圖爲實際的操作案例

Merge Request 聯動 issue 的界面。

issue 裏面聯動 Merge Request 的界面。

4.4 Gitlab 的 Code Quality 功能

我們可以利用開源的 Code Climate Engines 工具,對倉庫代碼進行質量檢查。Code Climate Engines 可以免費使用,但是 report 在 mr 界面的 report 展示需要 企業版 (Starter) 才支持。具體說明可參考官方文檔 (https://docs.gitlab.com/ee/user/project/merge_requests/code_quality.html),要使用該功能,需要配置好 gitlab-runner 的 Docker-in-Docker 模式,其中 gitlab-runner 的 config.toml 配置可參考如下:

[[runners]]
  name = "gitlab_runner_name"
  url = "https://git-test.xxx.com/"
  token = "your_token"
  executor = "docker"
  [runners.custom_build_dir]
  [runners.docker]
    tls_verify = false
    image = "docker:stable"
    privileged = true  # 必須打開特權模式
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/cache"]
    shm_size = 0
  [runners.cache]
    [runners.cache.s3]
    [runners.cache.gcs]

對應的 .gitlab-ci.yml 配置可參考如下:

code_quality:
  stage: check
  tags: 
    - codequality
  image: registry.test.com/library/debian_ci
  allow_failure: false
  services:
    - name: docker:stable-dind
      alias: docker-codequality
  variables:
    DOCKER_TLS_CERTDIR: ""
    DOCKER_HOST: "tcp://docker-codequality:2375"
    DOCKERHUB_URL: "registry.test.com"
    GIT_LFS_SKIP_SMUDGE: "1"
    AUTH_TOKEN_TTL: "1800"
  before_script:
    - |
      if ! [ -f .codeclimate.yml -o -f .codeclimate.json ] ; then
        cp .gitlab/ci/codeclimate/.codeclimate.yml ./
      fi
    - |
      if ! [ -f tox.ini ] ; then # pep8
        cp .gitlab/ci/codeclimate/tox.ini ./
      fi
    - |
      if ! [ -f .pylintrc ] ; then
        cp .gitlab/ci/codeclimate/.pylintrc ./
      fi
    - |
      if ! [ -f .cppcheck-suppressions ] ; then
        cp .gitlab/ci/codeclimate/.cppcheck-suppressions ./
      fi
    - |
      AUTH_TOKEN=`python $PWD/.gitlab/ci/dockerhub/get_token.py`
      docker login -u "$AUTH_USER" -p "$AUTH_TOKEN" "$DOCKERHUB_URL"
      docker run --env CFG="$(cat /root/.docker/config.json)" \
        --volume /root/.docker:/root/.docker \
        alpine sh -c 'echo "$CFG" > /root/.docker/config.json'
  script:
    - |
      if ! docker info &>/dev/null; then
        if [ -z "$DOCKER_HOST" -a "$KUBERNETES_PORT" ]; then
          export DOCKER_HOST='tcp://localhost:2375'
        fi
      fi
    - docker run --env SOURCE_CODE="$PWD" 
        --env ENGINE_MEMORY_LIMIT_BYTES=4000000000
        --volume "$PWD":/code 
        --volume /var/run/docker.sock:/var/run/docker.sock 
        --volume /root/.docker:/root/.docker 
        "$DOCKERHUB_URL/test/codequality:12-3-stable" /code
    - |
      if [ -f gl-code-quality-report.json ] ; then
        REPORT=$(head -n 1 gl-code-quality-report.json)
        if [ "$REPORT" != '[]' ] ; then
          exit 1
        fi
      fi
  after_script:
    - docker logout "$DOCKERHUB_URL"
  artifacts:
    reports:
      codequality: gl-code-quality-report.json
    paths: [gl-code-quality-report.json]
    when: on_failure
    expire_in: 1 week
  only:
    refs:
      - merge_requests
    changes:
      - .gitlab/ci/Code-Quality.gitlab-ci.yml
      - .gitlab/ci/codeclimate/*
      - Client/Content/Scripts/**/*.py
      - Server/Logic/**/*.py
      - Server/GameCpp/GameCore/**/*.{cpp,h}
  except:
    variables:
      - $CODE_QUALITY_DISABLED

empty-report:
  stage: check
  tags:
    - docker-dind
  image: registry.test.com/test/alpine:3.11
  variables:
    GIT_LFS_SKIP_SMUDGE: "1"
    GIT_SUBMODULE_STRATEGY: none
    GIT_STRATEGY: none
  script:
    - echo '[]' > gl-code-quality-report.json
  artifacts:
    reports:
      codequality: gl-code-quality-report.json
    expire_in: 1 week
  only:
    refs:
      - master

這裏需要注意的是,當檢查的代碼文件數較多時,需要根據情況適當提高 ENGINE_MEMORY_LIMIT_BYTES 的值,否則會因爲內存不足檢查失敗。同時 gl-code-quality-report 依賴上次 master 分支是否有 diff 而進行展示,故首次使用時,需觸發下面的 empty-report 這個 stage,上傳一個空的 gl-code-quality-report.json 文件。

上傳以後,在 MR 的界面,可以看到類似如下的界面,代表 Code Quality 功能啓用成功。

5. Gitlab Code Review 實踐

我們以一個測試項目爲例進行簡單的 Code Review 說明。

第一步:選擇源目標分支

如下圖,選擇源分支和目標分支,新建 MR:

第二步:設置 MR 相關參數

注意下面的 Merge request dependencies 和 Approval rules 只有 企業版 (Starter) 才支持。

第三步:開始 review

開始 code review,多人進行 discuss 和 comment,其中多人 Finish review 的功能只有 企業版 (Starter) 才支持。如下圖:

第四步:審批解決 discuss

discussions 未解決時,無法點擊 Merge 按鈕。當所有 discussions 已經解決,並且 pipeline 執行成功,approve 批准以後,纔可點擊執行。下圖爲了演示方便,我取消了本次的 approve。

第五步:解決合併衝突

如果合併過程產生了衝突,如下圖所示,提示你有 2 種方式來處理。一種是直接在 web 前端界面進行修改。另外一種是在本地進行修改。解決衝突時需要拉上團隊裏的其他成員一起討論,留下最終需要的內容進行提交即可。

這裏我爲了演示方便,我選擇在前端上直接修改衝突,點擊 Resolve conflicts,出現如下界面,按照圖中三個步驟操作即可。

第六步:融入目標分支

當 discuss 已經解決、pipeline 執行成功、Approval 審批完成、Conflicts 已經解決的時候,可以看到 Merge 按鈕爲綠色,最終點擊 MR 融入目標分支。

6. 建議與總結

選擇社區版本 (CE) 還是企業版 (Starter),取決於業務的需求。如果業務的 Code Review 過程強烈需要多人審批 (approval)、多人 Finish review、Code Quality 的 report 在 MR 展示等功能,則優先考慮企業版,否則社區版本做也是一個不錯的選擇。

相關文章