公開:2025年3月13日

2分で読めます

gitlab-triage gemを使ったアジャイルワークフローの自動化

「GitLab入門」シリーズでは、イシューやマージリクエストのトリアージなどの繰り返し発生するタスクを自動化して、デベロッパーの貴重な時間を確保する方法をご紹介します。

「GitLab入門」シリーズへようこそ。このシリーズでは新たにGitLabを使い始める方向けに、GitLab DevSecOpsプラットフォームに慣れ親しむために役立つ内容をお届けします。

今回の記事では、gitlab-triage gemを取り上げます。この非常に強力なツールを使用すると、アジャイルワークフローを自動化するボットを作成できます。自動化により、手作業を排除して作業効率を向上させましょう。

ワークフローを自動化すべき理由

ソフトウェア開発では効率性は重要です。イシューやマージリクエストのトリアージなどの繰り返し発生するタスクを自動化できれば、チームの貴重な時間を確保し、一番重要な作業である「素晴らしいソフトウェアの開発」に集中できるようになります。

gitlab-triageを使用すれば、次のことを実現できます。

  • 一貫性の確保:定義済みのルールに基づいて、自動的にラベルを適用し、イシューを自動的に割り当てる
  • レスポンスタイムの短縮:新たなイシューやマージリクエストに関するフィードバックを即座に得られる
  • 手作業の削減:手作業でトリアージや更新を行う必要がなくなる
  • 生産性の向上:チームが、コーディング作業やイノベーションの創出に集中できるようになる

gitlab-triageのご紹介

gitlab-triage gemは、GitLabプロジェクトとやり取りするボットを作成できるRubyのライブラリです。作成したボットを使用すると、次のようなさまざまなアクションの実行を自動化できます。

  • ラベル付け:イシューやマージリクエストを自動的に分類する
  • コメントの追加:最新情報やフィードバックの提供、または情報の提供依頼を行う
  • 割り当て:イシューやマージリクエストを適切なチームメンバーに割り当てる
  • クローズ:解決済み、または古くなったイシューやマージリクエストをクローズする
  • 作成:特定のイベントや条件に基づいて新しいイシューを作成する
  • ほかにもさまざまなことを行えます!

ぜひgitlab-triage gemリポジトリをチェックしてみてください。

トリアージボットのセットアップ

では、最初のトリアージボットをセットアップして動かしてみましょう!

  1. gemをインストールします。(注:gemコマンドは、プログラミング言語のRubyがインストールされている場合に利用できます)。
gem install gitlab-triage
  1. GitLab APIトークンを取得します。
  • GitLabプロファイル設定に移動します。
  • アクセストークン」に移動します。
  • apiスコープを指定して、新しいトークンを作成します。
  • 作成したトークンを安全な場所に保存し、このガイドがいつ頃終わるかに基づいて有効期限を設定します。
  1. トリアージポリシーを定義します。

プロジェクトのルートディレクトリに.triage-policies.ymlという名前のファイルを作成します。このファイルには、ボットの動作を制御するルールを含めます。以下に簡単な例をご紹介します。


---
- name: "Apply 'WIP' label"
  condition:
    draft: true
  action:
    labels:
      - status::wip

- name: "Request more information on old issue"
  condition:
   date:
    attribute: updated_at
    condition: older_than
    interval_type: months
    interval: 12
  action:
    comment: |
      {{author}} This issue has been open for more than 12 months, is this still an issue?

上記の設定では、2つのポリシーを定義しています。

  • 1つ目のポリシーは、ドラフトモードにあるすべてのイシューにstatus::wipラベルを適用します。
  • 2つ目のポリシーは、12か月間更新がないイシューに、その旨のコメントを追加します。
  1. ボットを実行します。

以下のコマンドを使用すると、手動でボットを実行できます。

gitlab-triage -t <your_api_token> -p <your_project_id>

<your_api_token>の部分をご自身のGitLab APIトークンに、また<your_project_id>ご自身のGitLabプロジェクトIDに変更してください。実行前にこれらのアクションの影響を確認したい場合は、-nまたは--dry-runを追加すれば、ポリシーをまずはテストできます。

GitLab CI/CDによる自動化

トリアージボットの実行を自動化するには、GitLab CI/CDと統合します。以下は.gitlab-ci.ymlの設定例です。


triage:
  script:
    - gem install gitlab-triage
    - gitlab-triage -t $GITLAB_TOKEN -p $CI_PROJECT_ID
  only:
    - schedules

上記の設定では、「triage」という名前のジョブを定義しています。このジョブは、gitlab-triage gemをインストールし、$GITLAB_TOKEN(定義済みのCI/CD変数)変数と$CI_PROJECT_ID変数を使用してボットを実行します。only: schedulesによって、ジョブが必ずスケジュールに従って実行されることを保証します。

スケジュールを設定するには、プロジェクトの「CI/CD」設定にアクセスし、「スケジュール」に進みます。新しいスケジュールを作成したら、ボットを実行する頻度(毎日、毎時間など)を設定します。

高度なトリアージポリシー

gitlab-triageには、さらに複雑なトリアージポリシーを作成できるように、次のような高度な機能が用意されています。

  • 正規表現:正規表現を使用すると、より強力なパターン一致を実現できます。
  • サマリーポリシー:関連する複数のイシューを1つのサマリーイシューにまとめます。
  • カスタムアクションRubyコードブロックを使用してカスタムアクションを定義し、GitLab API を使ったより複雑な操作を実行できます。

GitLabのデベロッパーアドボカシーチームによる、高度なトリアージボットの実際の使用例をご紹介します。全ポリシーは、こちらのファイルでご覧いただけます。

- name: Issues where DA team member is an assignee outside DA-Meta project i.e. DevRel-Influenced
  conditions:
    assignee_member:
      source: group
      condition: member_of
      source_id: 1008
    state: opened
    ruby: get_project_id != 18 
    forbidden_labels:
      - developer-advocacy
  actions:   
    labels:
      - developer-advocacy
      - DevRel-Influenced
      - DA-Bot::Skip

こちらの例では、グループ全体のイシュー(IDが18のプロジェクトに含まれるイシューを除く)から、IDが1008のグループに所属し、developer-advocacyというラベルが付いていないメンバーが担当者であるイシューを割り出し、ラベルを適用しています。GitLabデベロッパーアドボカシーチームは、このポリシーを使用して、チームメンバーが担当しているものの、チームのプロジェクトとして割り当てられていないイシューを探し出しています。チームのラベルを追加することで、チーム外からのコントリビュートを特定・追跡しやすくなります。

- name: Missing Due Dates
  conditions:
    ruby: missing_due_date
    state: opened
    labels:
      - developer-advocacy
    forbidden_labels:
      - DA-Due::N/A
      - DA-Bot::Skip
      - DA-Status::FYI
      - DA-Status::OnHold
      - CFP
      - DA-Bot::Triage
  actions:
    labels:
      - DA-Bot-Auto-Due-Date
    comment: |
      /due #{get_current_quarter_last_date}

上記の2つ目の例では、forbidden_labelsに含まれるラベルが適用されておらず、期限を過ぎていて、developer-advocacyラベルが付いているイシューをすべて探し出します。スラッシュコマンドとRubyを使って生成した日付を用いてイシューにコメントすることで、自動的に期限が更新されます。

ポリシーで使用されているRubyスクリプトは、以下のように別のファイルで定義しています。この機能を使用すれば、フィルターとアクションを柔軟に扱えます。ご覧のように、ポリシーで使用したさまざまなRubyコマンド用に関数を作成しています。

require 'json'
require 'date'
require "faraday"
require 'dotenv/load'

module DATriagePlugin
  def last_comment_at
    conn = Faraday.new(
      url: notes_url+"?sort=desc&order_by=created_at&pagination=keyset&per_page=1",
      headers: {'PRIVATE-TOKEN' => ENV.fetch("PRIV_KEY"), 'Content-Type' => 'application/json' }
    )

    response = conn.get()
    if response.status == 200
      jsonData = JSON.parse(response.body)
      if jsonData.length > 0
        Date.parse(jsonData[0]['created_at'])
      else
        Date.parse(resource[:created_at])
      end
    else
      Date.parse(resource[:created_at])
    end
  end

  def notes_url
    resource[:_links][:notes]
  end

  def get_project_id
    resource[:project_id]
  end

  def get_current_quarter_last_date()
    yr = Time.now.year
    case Time.now.month
    when 2..4
      lm = 4
    when 5..7
      lm = 7
    when 8..10
      lm = 10
    when 11..12
      lm = 1
      yr = yr + 1
    else
      lm = 1    
    end

    return Date.new(yr, lm, -1) 
  end

  def one_week_to_due_date
    if(resource[:due_date] == nil)
      false
    else
      days_to_due = (Date.parse(resource[:due_date]) - Date.today).to_i
      if(days_to_due > 0 && days_to_due < 7)
        true
      else
        false
      end
    end
  end

  def due_date_past
    if(resource[:due_date] == nil)
      false
    else
      Date.today > Date.parse(resource[:due_date])
    end
  end

  def missing_due_date
    if(resource[:due_date] == nil)
      true
    else
      false
    end
  end

end

Gitlab::Triage::Resource::Context.include DATriagePlugin

トリアージボットを実行する際は、次のコマンドを使用します。

`gitlab-triage -r ./triage_bot/issue_triage_plugin.rb --debug --token $PRIV_KEY --source-id gitlab-com --source groups`  
  • -r:トリアージを実行するための要件ファイルを渡します。この場合は、Ruby関数を渡します。
  • --debug:出力の一部としてデバッグ情報を表示します。
  • --token:有効なGitLab APIトークンを渡すために使用します。
  • --source:検索対象のイシューのソースがグループ内またはプロジェクト内かを指定します。
  • --source-id:: 選択したソースタイプのID(この場合はグループ)を受け取ります。

もう1つの実際の活用例としては、GitLab triage-opsプロジェクトが挙げられます。こちらはさらに複雑で、専用のトリアージボットの作成方法を学ぶのに最適です。

ベストプラクティス

  • まずは簡単なものから始める:基本的なポリシーから始めて、必要に応じて徐々に複雑な設定にしていきましょう。
  • テストは徹底的に行う:本番環境にデプロイする前に、ステージング環境でポリシーをテストします。
  • 定期的にモニタリングする:ボットの動作をモニタリングし、想定どおりに機能しているか確認してください。
  • わかりやすい名前を付ける:メンテナンスしやすいように、ポリシーには明確でわかりやすい名前を付けましょう。
  • フィルターの適用範囲に注意する:何千ものイシューが存在する全グループを対象に、イシューを絞り込むのはおすすめしません。トリアージに時間がかかってしまう可能性があるだけでなく、GitLab APIのレート制限によってプロセス自体が失敗に終わることもあります。
  • トリアージの際にはラベルを使って優先順位付けする:関係ないコメントやイシューがあふれて、ほかのユーザーの邪魔になることのないよう、トリアージを行う際はラベルを使用することをおすすめします。

ワークフローを制御する

gitlab-triage gemを使用すれば、GitLabワークフローを自動化して、新たなレベルの効率化を実現できます。まずはシンプルなトリアージボットの作成から始めて、徐々に高度な機能を使ってみてください。どれだけ多くの時間や作業負荷を削減できるか、きっと驚かれると思います!

GitLab入門シリーズ

「GitLab入門」シリーズのその他の記事をぜひご覧ください。

ご意見をお寄せください

このブログ記事を楽しんでいただけましたか?ご質問やフィードバックがあればお知らせください。GitLabコミュニティフォーラムで新しいトピックを作成して、ご意見をお聞かせください。

フォーチュン100企業の50%以上がGitLabを信頼

より優れたソフトウェアをより速く提供

インテリジェントなDevSecOpsプラットフォームで

チームの可能性を広げましょう。