Gitlab CE中的代码审查:如果没有Merge request approvals,但我真的很想

Gitlab CE中的代码审查:如果没有Merge request approvals,但我真的很想

GitLab 免费版本中没有的最需要的功能之一是能够投票反对将存储库清零以使用强制代码审查来控制合并请求 (MR)。

我们将自己完成最少的功能——我们将禁用合并,直到几个开发人员对 MR 表示“竖起大拇指”。

这是为什么?

我们的组织有能力购买 GitLab 许可证。 但是,由于开发是在无法访问 Internet 的情况下在闭环中进行的,并且有严格的预算计划,因此购买具有必要功能的自我管理许可证可能需要几个月的时间,而您现在需要工作。

因此,您必须:

  • 或者对某些开发者完全禁止 Merge 到受保护的分支,但是有 Merge 权限的开发者在合并其他人的 MR 时会收到冲突作为奖励;
  • 或者允许你在没有代码审查的情况下与你的 master 分支进行不受控制的合并,即使它是昨天刚刚安顿下来的初级分支。

第一件事就是去google,以为已经有人做过类似的事情了(没有提炼代码),结果发现社区版还没有这样的实现。

总体工作计划

例如,让我们在测试存储库上设置合并请求批准 我的应用程序:

  1. 让我们创建一个用于访问 GitLab API 的令牌(通过它我们将收到有关赞成票数和反对票数的信息)
  2. 向 GitLab 变量添加令牌
  3. 如果管道中有错误(如果没有足够的“赞成”票),则禁用合并
  4. 将投票验证设置为 CI/CD 管道的一部分
  5. 我们将禁止对受保护的分支进行提交,我们仅通过 MR 进行所有更改
  6. 让我们看看最后发生了什么

1.创建访问API的token

转到用户设置 → 访问令牌并记下令牌:

Gitlab CE中的代码审查:如果没有Merge request approvals,但我真的很想

接收令牌的帐户
API 访问允许您对您的存储库执行几乎任何操作,因此我建议您创建一个单独的 Gitlab 帐户,赋予它对您的存储库的最小权限(例如,Reporter)并为该帐户获取一个令牌。

2.将token添加到Gitlab变量中

比如上一步,我们收到了一个token QmN2Y0NOUFlfeXhvd21ZS01aQzgK

打开设置 → CI/CD → 变量 → 添加变量 → GITLAB_TOKEN_FOR_CI

Gitlab CE中的代码审查:如果没有Merge request approvals,但我真的很想

结果,我们得到:

Gitlab CE中的代码审查:如果没有Merge request approvals,但我真的很想

这可以在一个存储库和一组存储库上完成。

3. 如果代码审查后没有得到同事的认可,我们将禁止合并

在我们的例子中,如果没有足够的选票,合并管道将返回错误。

转到设置 → 常规 → 合并请求 → 合并检查并启用选项装配线必须成功运行。

Gitlab CE中的代码审查:如果没有Merge request approvals,但我真的很想

4.设置流水线

如果您还没有为您的应用程序制作 CI/CD 管道
在存储库的根目录中创建一个文件 .gitlab-ci.yml 内容简单:

stages:
  - build
  - test

variables:
  NEED_VOTES: 1

include:
  - remote: "https://gitlab.com/gitlab-ce-mr-approvals/ci/-/raw/master/check-approve.gitlab-ci.yml"

run-myapp:
  stage: build
  script: echo "Hello world"

用于 CI/CD 配置的独立存储库
我建议创建一个单独的存储库,您需要在其中创建一个 myapp.gitlab-ci.yml 文件来设置管道。 通过这种方式,您可以更好地控制可以更改构建管道并获得访问令牌的贡献者的访问权限。

需要指定新管道文件的位置,方法是转到 myapp 存储库 - 设置 - CI / CD - 装配线 - 自定义 CI 配置路径 - 指定一个新文件,例如 myapp.gitlab-ci.yml@gitlab-ce-mr-approvals/Ci

提示:使用 linter 对 GitLab CI 文件进行更改
即使你一个人工作,通过 MR 工作也会是一个好帮手,通过 linter 运行你对管道文件的所有更改。 如果您在 YAML 文件的语法中犯了错误,这不会让您中断工作管道,但只会阻止合并。

您可以将带有 linter 的容器示例嵌入到您的管道中:

hub.docker.com/r/gableroux/gitlab-ci-lint
hub.docker.com/r/sebiwi/gitlab-ci-validate

以及验证阶段的示例:

stages:
  - lint

lint:
  stage: lint
  image: sebiwi/gitlab-ci-validate:1.3.0
  variables:
    GITLAB_HOST: https://gitlab.com
  script:
    - CI_FILES=(./*.yml)
    - for f in "${CI_FILES[@]}"; do
        gitlab-ci-validate $f;
      done;

仍然需要向您的管道添加一些参数以使其正常工作:

stages:
- test

variables:
NEED_VOTES: 1

include:
- remote: "https://gitlab.com/gitlab-ce-mr-approvals/ci/-/raw/master/check-approve.gitlab-ci.yml"

NEED_VOTES 变量确定 MR 必须有多少“赞”才能使 Merge 可用。 值为一意味着您自己可以通过“喜欢”它来批准您的 MR。

include 包括测试阶段,它检查“喜欢”的数量。

以myapp.gitlab-ci.yml为例的最简单pipeline
stages:
- build
- test

variables:
NEED_VOTES: 0

include:
- remote: "https://gitlab.com/gitlab-ce-mr-approvals/ci/-/raw/master/check-approve.gitlab-ci.yml"

run-myapp:
stage: build
image: openjdk
script:
- echo CI_MERGE_REQUEST_TARGET_BRANCH_NAME $CI_MERGE_REQUEST_TARGET_BRANCH_NAME
- java HelloWorld.java

check-approve.gitlab-ci.yml 的内容
ci-mr:
stage: test
script:
- echo ${CI_API_V4_URL}
- echo "CI_PROJECT_ID ${CI_PROJECT_ID}"
- echo "CI_COMMIT_SHA ${CI_COMMIT_SHA}"
- "export MR_ID=$(curl --silent --request GET --header "PRIVATE-TOKEN: $GITLAB_TOKEN_FOR_CI" ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests | jq ".[] | if .sha == \"${CI_COMMIT_SHA}\" then .id else {} end" | grep --invert-match {})"
- "export MR_TITLE=$(curl --silent --request GET --header "PRIVATE-TOKEN: $GITLAB_TOKEN_FOR_CI" ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests | jq ".[] | if .sha == \"${CI_COMMIT_SHA}\" then .title else {} end" | grep --invert-match {})"
- "export MR_WIP=$(curl --silent --request GET --header "PRIVATE-TOKEN: $GITLAB_TOKEN_FOR_CI" ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests | jq ".[] | if .sha == \"${CI_COMMIT_SHA}\" then .work_in_progress else {} end" | grep --invert-match {})"
- "export MR_UPVOTES=$(curl --silent --request GET --header "PRIVATE-TOKEN: $GITLAB_TOKEN_FOR_CI" ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests | jq ".[] | if .sha == \"${CI_COMMIT_SHA}\" then .upvotes else {} end" | grep --invert-match {})"
- "export MR_DOWNVOTES=$(curl --silent --request GET --header "PRIVATE-TOKEN: $GITLAB_TOKEN_FOR_CI" ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests | jq ".[] | if .sha == \"${CI_COMMIT_SHA}\" then .downvotes else {} end" | grep --invert-match {})"
- MR_VOTES=$(expr ${MR_UPVOTES} - ${MR_DOWNVOTES})
- NEED_VOTES_REAL=${NEED_VOTES:-1}
- echo "MR_ID ${MR_ID} MR_TITLE ${MR_TITLE} MR_WIP ${MR_WIP} MR_UPVOTES ${MR_UPVOTES} MR_DOWNVOTES ${MR_DOWNVOTES}"
- echo "MR_VOTES ${MR_VOTES} Up vote = 1, down vote = -1, MR OK if votes >=${NEED_VOTES_REAL}"
- if [ "${MR_VOTES}" -ge "$(expr ${NEED_VOTES_REAL})" ];
then
echo "MR OK";
else
echo "MR ERROR Need more votes";
exit 1;
fi
image: laptevss/gitlab-api-util
rules:
- if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME =~ /^release/.*$/'

详细了解检查时会发生什么:

  • 设置了限制,只有在 master 或 release /* 分支中创建 MR 时才会检查
  • 使用 GitLab API,获取“喜欢”和“不喜欢”的数量
  • 计算正面和负面反应之间的差异
  • 如果差异小于我们在 NEED_VOTES 中设置的值,那么我们阻止合并的能力

5.禁用对受保护分支的提交

我们确定我们应该对其进行代码审查的分支,并指出它们只能通过 MR 进行处理。

为此,请转到设置 → 存储库 → 受保护的分支:

Gitlab CE中的代码审查:如果没有Merge request approvals,但我真的很想

6.检查

设置 NEED_VOTES:0

我们做MR,放个“不喜欢”。

Gitlab CE中的代码审查:如果没有Merge request approvals,但我真的很想

在构建日志中:

Gitlab CE中的代码审查:如果没有Merge request approvals,但我真的很想

现在输入“喜欢”并重新检查:

Gitlab CE中的代码审查:如果没有Merge request approvals,但我真的很想

来源: habr.com

添加评论