これ何?
GitLab CI上で行った変更をMerge Requestとして投げるためのツールです。(開発期間は1週間くらい)
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がインストールされていなくても使えるようにしました。(システムにインストールされている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なものだったのでパッチを投げました。