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,但我真的很想

來源: www.habr.com

添加評論