基於 Gitlab 的 Code Review 最佳實踐
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 展示等功能,則優先考慮企業版,否則社區版本做也是一個不錯的選擇。
往期精彩
﹀
﹀
﹀