2021年4月21日水曜日

Gitlab CI から MergeRequest を作成する方法

Gitlab CI から MergeRequest を作成する方法

概要

前回は Gitlab CI から branch を作成してみました
今回は作成した branch を元に MergeRequest を作成してみます

環境

  • Gitlab 13.9.5-ee
  • Ubuntu 18.04
  • docker 19.03.6

create_mr.sh の作成

MergeRequest は Gitlab の API をコールします
公式のスクリプトがあったのでそれを流用しています
master に対して MergeRequest を作成するので TARGET_BRANCH は固定にしています
MergeRequest のタイトルや本文は API のドキュメントを読んで好きなように設定してください

#!/usr/bin/env bash
# Extract the host where the server is running, and add the URL to the APIs
[[ $HOST =~ ^https?://[^/]+ ]] && HOST="${BASH_REMATCH[0]}/api/v4/projects/"

# Look which is the default branch
TARGET_BRANCH="master"

# The description of our new MR, we want to remove the branch after the MR has
# been closed
BODY="{
    \"id\": ${CI_PROJECT_ID},
    \"source_branch\": \"${CI_COMMIT_REF_NAME}\",
    \"target_branch\": \"${TARGET_BRANCH}\",
    \"remove_source_branch\": true,
    \"title\": \"WIP: ${CI_COMMIT_REF_NAME}\",
    \"assignee_id\":\"${GITLAB_USER_ID}\"
}";

# Require a list of all the merge request and take a look if there is already
# one with the same source branch
LISTMR=`curl --silent "${HOST}${CI_PROJECT_ID}/merge_requests?state=opened" --header "PRIVATE-TOKEN:${PRIVATE_TOKEN}"`;
COUNTBRANCHES=`echo ${LISTMR} | grep -o "\"source_branch\":\"${CI_COMMIT_REF_NAME}\"" | wc -l`;

# No MR found, let's create a new one
if [ ${COUNTBRANCHES} -eq "0" ]; then
    curl -X POST "${HOST}${CI_PROJECT_ID}/merge_requests" \
        --header "PRIVATE-TOKEN:${PRIVATE_TOKEN}" \
        --header "Content-Type: application/json" \
        --data "${BODY}";

    echo "Opened a new merge request: WIP: ${CI_COMMIT_REF_NAME} and assigned to you";
    exit;
fi

echo "No new merge request opened";

.gitlab-ci.yml の作成

branch を作成してから MergeRequest を作成します
全体のコードは以下のようになります

stages:
  - create_branch

create_branch:
  image:
    name: alpine/git:latest
    entrypoint: [""]
  stage: create_branch
  before_script:
    - "git config --global user.name root"
    - "git config --global user.email root@mail.domain"
    - "git config --global credential.helper store"
    - "echo https://${GIT_USER}:${GIT_PASSWORD}@gitlab.example.com > ~/.git-credentials"
    - "apk add curl"
    - "apk add bash"
    - "export PROJECT_ID=3947"
  script:
    # Create a branch
    - "git clone https://gitlab.example.com/root/test.git"
    - "cd test"
    - "export LATEST_SHA=$(git show -s --format=%h)"
    - "git checkout -b test_from_${LATEST_SHA}"
    - "git push -u origin test_from_${LATEST_SHA}"
    # Create a merge request
    - "cd $CI_BUILDS_DIR/$CI_PROJECT_PATH"
    - "chmod +x ./create_mr.sh"
    - "HOST=${CI_PROJECT_URL} CI_PROJECT_ID=${PROJECT_ID} CI_COMMIT_REF_NAME=test_from_${LATEST_SHA} GITLAB_USER_ID=${GITLAB_USER_ID} PRIVATE_TOKEN=${GIT_PASSWORD} ./create_mr.sh"

説明

branch と MergeRequest を作成するリポジトリは CI を回すリポジトリとは別のリポジトリを想定しています

まずブランチを作成します
これは前回の方法と同じになります

そしてそのブランチを元に Merge Request を作成します
事前に作成したシェルスクリプトに必要な環境変数を渡しています
CI_PROJECT_URL, GITLAB_USER_ID は Gitlab 側で事前に準備してある変数になります
PROJECT_ID は MergeRequest を作成するプロジェクトの ID になります
これはプロジェクトの設定ページから確認できるので固定で指定します
PRIVATE_TOKEN は clone 時にトークン認証にしているのでそのトークンをそのまま使えます

今回はこれくらいの変数しか準備していませんが作成する MergeRequest の本文やアサインに合わせて適宜変更してください

動作確認

git push して CI を回して問題なく MergeRequest が作成されれば OK です

最後に

実際に動作するようになるまではトライアンドエラーを繰り返しましょう

0 件のコメント:

コメントを投稿