くりにっき

フルスタックキュアエンジニアです

create-merge-requestを作った

これ何?

GitLab CI上で行った変更をMerge Requestとして投げるためのツールです。(開発期間は1週間くらい)

gitlab.com

GitHub Actionsだと peter-evans/create-pull-request が便利でよく使っているのですが、同じようなことをGitLab CIでもやりたくて作りました。

サンプル

一番簡単なサンプルはこれ。

stages:
  - build

create_mr_for_changes:
  stage: build
  
  image: debian:stable-slim

  before_script:
    # Download and install latest create-merge-request
    - apt-get update
    - apt-get install -y curl
    - VERSION=$(curl -s --fail https://gitlab.com/sue445/create-merge-request/-/raw/main/VERSION?ref_type=heads)
    - pushd /tmp
    - curl --retry 3 -L -o create-merge-request.tar.gz https://gitlab.com/sue445/create-merge-request/-/releases/${VERSION}/downloads/create-merge-request_Linux_x86_64.tar.gz
    - tar xzvf create-merge-request.tar.gz
    - mv create-merge-request /usr/local/bin
    - popd

  script:
    # TODO: Add your changes
    - date > now.txt

    # Create Merge Request if repo is changed
    - create-merge-request

  rules:
    # Run only scheduled pipeline
    # ref. https://docs.gitlab.com/ee/ci/pipelines/schedules.html
    - if: $CI_PIPELINE_SOURCE == "schedule"

このサンプルでは実行時にnow.txtを更新して、その差分をMerge Requestとして投げています。

頑張りポイント

gitコマンドを使わずにgitリポジトリにアクセスした

create-merge-requestはGoで作りスタンドアローンバイナリとして配布しています。

しかしスタンドアローンバイナリとして配布しているツールが実行環境にインストールされているgitコマンドに依存していると真のスタンドアローンとはいえないため、 https://github.com/go-git/go-git というGo実装のgitを利用して実行環境にgitがインストールされていなくても使えるようにしました。

可能な限りパラメータを省略できるようにした

下記のhelpを見てもらえれば分かりますが、GitLabのリポジトリに新しいcommitをpushしてMerge Requestを投げるだけでも下記のパラメータが登場します。

REQUIRED PARAMETERS:
   --gitlab-api-endpoint value  GitLab API Endpoint (e.g. https://gitlab.com/api/v4) [$GITLAB_API_ENDPOINT, $CI_API_V4_URL]
   --gitlab-access-token value  GitLab access token [$GITLAB_ACCESS_TOKEN]
   --gitlab-project value       GitLab Project Path (e.g. gitlab-org/gitlab) [$GITLAB_PROJECT, $CI_PROJECT_PATH]

OPTIONAL PARAMETERS:
   --author-email value                     author email for commit (default: create-merge-request@example.com)
   --author-name value                      author name for commit (default: create-merge-request)
   --commit-message value, -m value         commit message (default: [create-merge-request] automated change)
   --source-branch value                    Merge Request branch name (default: create-merge-request/patch)
   --source-branch-suffix value             Merge Request branch name suffix (none,random,timestamp,short-commit-hash) (default: none)
   --target-branch value                    Send Merge Request to this branch (e.g. main, master) (default: main) [$CI_DEFAULT_BRANCH]
   --title value, -t value                  Merge Request title (default: Changes by create-merge-request)
   --description value                      Merge Request description (default: Automated changes by [create-merge-request](https://gitlab.com/sue445/create-merge-request))
   --labels value [ --labels value ]        Merge Request labels
   --assignees value [ --assignees value ]  Merge Request assignees (e.g. user1,user2)
   --reviewers value [ --reviewers value ]  Merge Request reviewers (e.g. user1,user2)

しかし初手で大量にパラメータを設定させるのは大変です。

GitLab CIでは $CI_API_V4_URL$CI_PROJECT_PATH などの環境変数が自動で用意されているため、可能な限りそれらから設定を読み込むようにしました。

それによりGitLab CIで実行する時には GITLAB_ACCESS_TOKEN でGitLabのアクセストークンだけ設定されていればとりあえずMerge Requestが作成できるようにしました。

おまけ

GoのバイナリをGitLabのリポジトリのreleasesに添付する時に https://github.com/goreleaser/goreleaser を利用したのですが、GitLab CI用の設定が現在のGitLabではDeprecatedなものだったのでパッチを投げました。

github.com