Ginagigo

Work Hard, Play Hard

Merge Merge Requests with API in GitLab

前提

會有這個需求是因為最近在當助教,這堂課上過去繳交作業的方式是:「每個學生都需要先將作業fork,並且使用merge request來交作業到自己的branch」,那在之前都是使用手動將 merge request merge起來,並且需要檢查學生是否有交對branch & 是否有commit,再去每個學生的merge request裏頭按下merge按鈕!

但是學生有100多個,那勢必手動檢查每個merge request是很費時的 QQ !!! 所以我研究了一下發現可以透過 command line / call API 的方式去merge !

In Github

如果是在 Github 上面,需要下載 gh,會有 pull requests 跟 issue 等的資訊,可以使用 command line 去 merge pull request了,Github repo-gh,也可以參考這個資料 ( P.S 在 Github 上是 pull request,而在 GitLab 上叫做 merge request )。

In GitLab

如果是在 GitLab 上面的話,只需要透過 call GitLab API 就可以達成了 !! GitLab API 有提供三種方式,分別是

  1. REST API
  2. SCIM API
  3. GraphQL API

我後來選擇使用的是第一種,因為較為熟悉 ~

如何使用 !

我們要使用 API ,先看目前發行的 version 版本號,現在 GitLab 的 api version 是 4,defined在 lib/api.rb,root 路徑就是 /api/v4

像是以下例子,會列出所有的repo:

curl "https://gitlab.example.com/api/v4/projects"

API 會回傳 Json 格式的資料,如果是在 GitLab 上面的話就將 gitlab.example.com 改成 gitlab.com,如果是自行架設 GitLab Server 的話,就是把 gitlab.example.com 改成自己的網址,不過這邊有一點需要注意的是會需要提供 key認證身份

認證方式

有五種認證的方式,我使用的是第二種:

  1. OAuth2 tokens
  2. Personal access tokens
  3. Project access tokens
  4. Session cookie
  5. GitLab CI/CD job token (Specific endpoints only)

Personal Access tokens,可以透過點擊自己的頭像,找到 Access Token,點選Scope: api 就會拿到自己的 token 了!

將這個 token 傳入你要 call 的 api 中,這邊是使用參數傳入,GitLab 也有提供其他方式:

curl "https://gitlab.example.com/api/v4/projects?private_token=<your_access_token>"

是不是其實很簡單,就可以拿到 GitLab 上面的 data 了呢 !!
然後要記得使用 api 都要傳入這個token ! 不然會回傳 400 開頭 或是 404 的 error status code!

可以取得的資源

  1. Projects.
  2. Groups.
  3. Standalone.

這邊只會介紹 Projects ! Projects 就是像我們在 Github 上的 repo ~
像最一開始的測試,就是會列出所有的repo:

GET "https://gitlab.example.com/api/v4/projects"

Merge Requests

接著到我們的重點,就是Merge requests,以下的路徑可以列出所有的merge requests:

GET /projects/:id/merge_requests

這邊的 :id 就是在 repo 裏頭出現的 Project ID,貼過來就可以測試了 ! GitLab 也有提供不同參數去將 merge requests filter。
像是 state 就可以去看現在 merge reqeust 的狀態是 opened, closed, locked, or merged.

列出是 opened 的 merge requests:

GET /projects/:id/merge_requests?state=opened

那這邊也會有一個參數是 page或是 per_page,GitLab 有限制一次只能拿幾筆資料,我測試 page 是一次能拿到 20 筆,page 從 1 開始:

GET /projects/:id/merge_requests?state=opened&page=1

那如何將這個 merge request 改成是 merge的呢? 在之前將 request 回傳的資料中,有一個欄位是 iid, 就是merge requests 的 id,只要使用下面的指令就可以將merge merge request 囉 !!

PUT /projects/:id/merge_requests/:merge_request_iid/merge

我最後是用python requests package 加上一些判斷,去將正確繳交的學生 merge requests 都 merge !

然後程式碼我放在Gist上面,可以點這邊

真是省了一筆時間 ( 灑花 ),因為繳交到 GitLab 的作業有六個,然後至少有90 ~ 100的學生有繳交 !! 這樣也就不用人工去merge啦 !!