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)。
- 远程方式:
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 展示等功能,则优先考虑企业版,否则社区版本做也是一个不错的选择。