Edited at

RubyでBacklogを操作する

More than 1 year has passed since last update.


前提

要素
バージョン

Debian
8.6

Ruby
2.2.2

gem
2.4.5

bundle
1.13.4

Backlog API
2.9.0

BacklogKit
0.15.0

また、Backlogの個人設定より、APIキーを生成していることを前提とする

以下ブログとのマルチポストです。ブログではQiitaに書くほどのことじゃないメモも投稿しています。

[Ruby] BacklogをCUIで操作してみる


概要

国産プロジェクト管理ツールであるBacklogを、ブラウザではなく、BacklogAPIを用いて、スクリプト経由で操作する。スクリプトの記述には、APIを間接的に利用するライブラリであるBacklogKitを用いるためにRubyを採用する。

本記事で作成するツールでは、主に以下のことをCUIで実現する


  • ユーザ情報の取得

  • 課題の作成(タイトル/本文のみ指定可能)

  • 課題の操作(ステータスの変更/完了理由の変更/実作業時間の変更)

実用的にするにはさらにカスタマイズする必要があるが、本課題では基本的なAPI利用が出来るようになる部分までにする。また、本課題での動作確認は、個人利用のために開設しているBacklogスペースを用いる。


BacklogAPI利用の準備

今回は、BacklogAPIをRubyで簡易的に利用するためのライブラリである、BacklogKitを利用する。BacklogKitはgemで管理されているので、bundleを用いてインストールする。

Gemfileに以下のように記述

source "https://rubygems.org"

gem 'backlog_kit'

Bundleでインストール

bundle install --path bundle/vendor


スペースIDとAPIキーを記述したファイルを作成

BacklogAPIを利用するためには、対象のスペースIDと、APIキーが必要になる。スクリプト中にハードコーディングしても良いが、本記事で実装するツールは、Githubにてコードを公開しているため、APIキーが漏洩することを避けるために別途JSONファイルに記述することにする(もちろん該当のJSONファイルはリポジトリで共有しない)

ということで、以下のようなsecret.jsonを作成する。もちろんAPI_KEYはダミー

{

"space_id": "saknight",
"api_key": "hogehogefugafugafoofoobarbar",
"project_key": "DEV"
}

とりあえず汎用的なメソッドを持たせることを目的に、Util.rbを作成し、そこにJSONファイルをロードするメソッドを実装する

require 'json'

class Util
def self.load_secret_file
File.open('secret.json') do |file|
JSON.load(file)
end
end
end

これでBacklogAPIを利用する下準備は完了


BacklogAPIを使ってみる

Backloger.rbを作成し、ここにBacklogAPIを利用するコードを書いていく。とりあえずBacklogAPIを試しに使ってみるということで、ユーザ情報を取得してみる。

require 'backlog_kit'

require_relative 'Util'
secret = Util.load_secret_file

client = BacklogKit::Client.new(
space_id: secret['space_id'],
api_key: secret['api_key']
)

p client.get_space.body

bundleを使っているため、上記ファイルを以下のように実行する

$ bundle exec ruby Backloger.rb

以下のような実行結果が得られた

$ bundle exec ruby Backloger.rb

#<BacklogKit::Resource:0x007f9534806850 @attributes={:spaceKey=>"saknight", :name=>"saknight", :ownerId=>85748, :lang=>"ja", :timezone=>"Asia/Tokyo", :reportSendTime=>"18:00:00", :textFormattingRule=>"backlog", :created=>"2017-03-04T15:47:40Z", :updated=>"2017-03-04T15:47:40Z"}>

どうやらBacklogKitではAPIの実行結果はBacklogKit::Resourceクラスのオブジェクトとして返却されるらしい。詳しい使い方はドキュメントやソースコードを追う必要があるが、以下のようにコードを変更すればスペースIDが取得できそうだ。

p client.get_space.body.spaceKey

実行結果

$ bundle exec ruby Backloger.rb

"saknight"

とりあえずBacklogkitを用いたBacklogAPIの利用が正常にできていることがわかった。あとはドキュメントやソースコードを読んで本ツールの目的を達成するためのコードを作成していく


課題の作成に必要なパラメータの取得

リファレンスによると、課題の追加には以下のパラメータが必須となる


  • 課題の名前

  • プロジェクトID

  • 課題の種別ID

  • 課題の優先度ID

ここで面倒なのが、プロジェクト/種別/優先度が全てIDを要求されていることだ。

例えば優先度の場合「高」「中」「低」といった表示名で指定するのではなく、それに対応するIDが必要になる。面倒なことにIDはBacklog環境のカスタマイズ次第で変わってしまうので、今回はスクリプトから動的に取得できるようにすることにする。

プロジェクトID/種別ID/優先度IDを動的に取得するために、以下のIdentifierクラスを作成した

require 'backlog_kit'

class Identifier

def initialize(client)
@client = client
end

def project(projectKey)
project = @client.get_projects.body.find do |pb|
pb.projectKey == projectKey
end
project.id
end

def priority(label)
priority = @client.get_priorities.body.find do |pr|
pr.name == label
end
priority.id
end

def issueType(project_key, label)
type = @client.get_issue_types(project_key).body.find do |it|
it.name == label
end
type.id
end
end

上記クラスのメソッドは、それぞれプロジェクトキー、優先度、種別を指定すると、それに対応するIDを返却してくれる。

例えば以下のようなコードを実行すると

identifier = Identifier.new(client)

p identifier.projectId("DEV")
p identifier.priorities('中')
p identifier.issueTypeId("DEV", 'タスク')

以下のようにそれぞれIDに変換して出力してくれる

$ bundle exec ruby Backloger.rb

38382
3
172585

もちろんIDは基本的に不変であるため、毎回動的に取得する必要はなく、一度取得したら適当にキャッシュするなどすれば簡単に高速化することができるが、ここでは割愛する。


課題の作成

ようやく本題。前項で、課題の作成に必要なパラメータを動的に取得できるようになったので、create_issueメソッドを用いて、課題を作成する。以下のコードでは、「課題テスト」という、優先度が「中」で、種別が「タスク」の課題を作成する(他の設定項目は未設定状態)

client.create_issue('課題テスト', {

:projectId => identifier.project(secret['project_key']),
:priorityId => identifier.priority('中'),
:issueTypeId => identifier.issueType(secret['project_key'], 'タスク'),
})

スクリプト実行後、課題が生成されていることが確認できる

スクリーンショット 2017-04-17 23.49.29.png


課題の編集に必要なパラメータの取得

今回は、前項で作成した課題に対して、以下の編集を行う。


  • ステータスを「完了」にする

  • 完了理由を「対応済み」にする

  • 実績時間を「1時間」にする

  • 適当なコメントを投稿する

"課題の作成に必要なパラメータの取得"同様、ステータス/完了理由は、対応するIDが必要になるので、同様にIdentifierクラスに以下のメソッドを追加する。

  def status(label)

status = @client.get_statuses.body.find do |st|
st.name == label
end
status.id
end

def resolution(label)
resolution = @client.get_resolutions.body.find do |res|
res.name == label
end
resolution.id
end

以下のコードを実行すると

identifier = Identifier.new(client)

p identifier.status('完了')
p identifier.resolution('対応済み')

以下のように完了と対応済みに対応するIDが取得できる

$ bundle exec ruby Backloger.rb

4
0


課題の編集

前項で課題編集のためのIDが取得できたので、update_issueメソッドを用いて、以下のように課題の修正を行う

client.update_issue('DEV-47', {

:statusId => identifier.status('完了'),
:resolutionId => identifier.resolution('対応済み'),
})

実行すると、以下のように課題が修正されたことが確認できる

スクリーンショット 2017-04-18 0.10.29.png