GitLab API | gitlab gem で IssueNote (コメント)のリストから IssueNote (コメント)を登録するためのソースコードを生成する

# GitLab API | gitlab gem で IssueNote (コメント)のリストから IssueNote (コメント)を登録するためのソースコードを生成する

## 概要
gitlab gem で IssueNote (コメント)のリストから IssueNote (コメント)を登録するためのソースコードを生成します

## 経緯
なんでこんな妙なことをしているかというと、GitLabサーバーAのデータを別マシンの
GitLabサーバーBに移行したかったのですが、
公式の手順でうまくいかなかったのでAPIで対応することにしました。

前提としてプロジェクトやユーザーやIssueの情報は移行済みです。
※プロジェクトやユーザーやIssueは基本的な登録内容は同じだが、id が変わっていることに注意。

## コードジェネレーター

~~~ruby:generate_create_issues_code.rb
require 'gitlab'

Gitlab.configure do |config|
  config.endpoint       = 'http://some_path/api/v3' 
  config.private_token  = 'your token'
end

Gitlab.projects(per_page: 100).each do |project|
  method_name = "create_#{project.name}_issue_note"
  # メソッドとして定義することで、コメントがあったかどうか判断して後から呼ぶ出すか呼び出さないか決める
  puts "def #{method_name}"
  project_id_code = "  projects = Gitlab.projects(per_page: 100).select { |e|e.name == '#{project.name}' }"
  puts project_id_code
  puts "  if projects.first"
  issue_notes_exist = false
  Gitlab.issues(project.id, per_page: 100).each do |issue|
    issue_id_code = "issues = Gitlab.issues(project_id, per_page: 100).select { |e|e.title == '#{issue.title}' }"
    issue_notes = Gitlab.issue_notes(project.id, issue.id)
    # issueにコメントがない場合は登録ロジックを出力しない
    next if issue_notes.size == 0
    issue_notes_exist = true
    # コメントを昇順にする
    issue_notes.sort_by { |e|e.created_at }
    puts "    project_id = projects.first.id"
    puts "    issues = #{issue_id_code}"
    puts "    if issues.first"
    issue_notes.each do |issue_note|
      puts "     issue_id = issues.first.id"
      body = issue_note.body.gsub("\r\n", '\\r\\n').gsub('"', '""')
      puts "      Gitlab.create_issue_note(project_id, issue_id, \"#{body}\")"
    end
    puts "    end"
  end
  puts "  end"
  puts "end"

  # コメントがあった場合のみメソッドを呼び出す
  puts method_name if issue_notes_exist
end
~~~

## 出力

ちょっと冗長で非効率なコードが生成されますが、使い捨てなのであまり気にせず。
コメントが1件もなかった場合は、メソッドを呼び出していないことが確認できます。

~~~ruby
# : 
# : 多数の出力
# : 
def create_project1_issue_note
  projects = Gitlab.projects(per_page: 100).select { |e|e.name == 'project1' }
  if projects.first
  end
end
def create_project2_issue_note
  projects = Gitlab.projects(per_page: 100).select { |e|e.name == 'project2' }
  if projects.first
    project_id = projects.first.id
    issues = issues = Gitlab.issues(project_id, per_page: 100).select { |e|e.title == 'title1' }
    if issues.first
      issue_id = issues.first.id
      Gitlab.create_issue_note(project_id, issue_id, "comment1")
      issue_id = issues.first.id
      Gitlab.create_issue_note(project_id, issue_id, "comment2")
      issue_id = issues.first.id
      Gitlab.create_issue_note(project_id, issue_id, "comment3")
    end
    project_id = projects.first.id
    issues = issues = Gitlab.issues(project_id, per_page: 100).select { |e|e.title == 'title2' }
    if issues.first
      issue_id = issues.first.id
      Gitlab.create_issue_note(project_id, issue_id, "comment1")
    end
  end
end
create_project2_issue_note
# : 
# : 多数の出力
# : 
~~~

## コードジェネレーターで生成されたコードを利用して IssueNote (コメント) の登録

~~~ruby:create_issue_note.rb
require 'gitlab'

# 今回は固定ユーザーでコメントを登録します。元のユーザーでコメントを作成したい場合は、
# private_tokenを切り替える必要があります。
Gitlab.configure do |config|
  config.endpoint       = 'http://to_server_path/api/v3' 
  config.private_token  = 'to server token'
end

# : 
# : 多数のコメント追加処理
# : 
def create_project1_issue_note
  projects = Gitlab.projects(per_page: 100).select { |e|e.name == 'project1' }
  if projects.first
  end
end
def create_project2_issue_note
  projects = Gitlab.projects(per_page: 100).select { |e|e.name == 'project2' }
  if projects.first
    project_id = projects.first.id
    issues = issues = Gitlab.issues(project_id, per_page: 100).select { |e|e.title == 'title1' }
    if issues.first
      issue_id = issues.first.id
      Gitlab.create_issue_note(project_id, issue_id, "comment1")
      issue_id = issues.first.id
      Gitlab.create_issue_note(project_id, issue_id, "comment2")
      issue_id = issues.first.id
      Gitlab.create_issue_note(project_id, issue_id, "comment3")
    end
    project_id = projects.first.id
    issues = issues = Gitlab.issues(project_id, per_page: 100).select { |e|e.title == 'title2' }
    if issues.first
      issue_id = issues.first.id
      Gitlab.create_issue_note(project_id, issue_id, "comment1")
    end
  end
end
create_project2_issue_note
# : 
# : 多数のコメント追加処理
# : 
~~~

## 補足
* *project* は 100 件以下の想定。それ以上ある場合は、ページング処理が必要
* *issue* は 100 件以下の想定。それ以上ある場合は、ページング処理が必要
* コメントの登録時間、更新時間等は移行先に登録した時間になっています。

## 参照
* GitLab gem RubyGems
https://rubygems.org/gems/gitlab

* GitLab gem GitHub
https://github.com/NARKOZ/gitlab