iMacrosを使って別リポジトリにGithub issueを一括移動させる

# 前提
ある事情により数百件ほどあるGithub issueを別リポジトリに移動させたかったが、Github公式ではそのような機能はなく、
3rd party製のツールでも1つ1つ移すしか方法がなかった。

数百件ほどのissueを1つずつ移していては日が暮れてしまうのでiMacrosを使って移行作業を自動化した。その時のメモ。

- ※ 3rd party製ツール
    - Zenhub
    - [Issue Mover For Github(by Google)](https://github-issue-mover.appspot.com/)

# やりたかったこと
- リポジトリを跨いでGithub issueを移動させたい（ex. AリポのissueをBリポに移動）
- 数百件ほど対象のissueがあるので一括で移動させたい

# 使うもの
- Firefox(※1)
- iMacros for Firefox(Add-on)
- [Issue Mover For Github(by Google)](https://github-issue-mover.appspot.com/)

※1 最初は常用しているChromeでiMacrosを使っていたが必要な機能が使えなかったのでFirefox版を使った。

# やり方の流れ
1. 移行対象のGithub issueのIDを取得しリストを作る
2. iMacrosで[Issue Mover For Github(by Google)](https://github-issue-mover.appspot.com/)を使う作業を自動化する
3. iMacrosをjsで操作して移行対象リストをループで処理

#　やってみる
## 1. 移行対象のGithub issueのIDを取得しリストを作る
今回はGithub APIを使う。
[Tokenを取得し](https://github.com/settings/tokens)、それを使ってOpenなissueリストを取得。簡単なシェル芸でidリストを作成する。

```
$ curl -H "Authorization: token xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" https://api.github.com/repos/fortkle/test_a/issues > issue.txt
$ cat issue.txt | grep number | awk '{ print $2}'
```

こんな感じ。カンマ区切りになってると尚良し。

```
170,
168,
162,
158,
146,
135,
134,
133,
132,
116,
107,
93,
83,
80,
77,
73,
67,
66,
62,
61,
58,
57,
55,
50,
45,
43,
41,
40,
39,
38,
```

（ちなみに私はZenhubの特定のpipelineに属するissueだけを移行したかったので、 ZenhubのAPIを使ってidリストを作成した。ほぼ同じやり方なので詳細は割愛。）

## 2. iMacrosで[Issue Mover For Github(by Google)](https://github-issue-mover.appspot.com/)を使う作業を自動化する
iMacrosとはブラウザの操作をマクロ化するツールである。Chrome, Firefoxで拡張機能として使うことができる。
[Issue Mover For Github(by Google)](https://github-issue-mover.appspot.com/)とはGoogleが提供しているissue移動ツールでコメントやlabelなども含めて移動してくれる（実際には移行元の内容を移行先にコピーして、移行元をcloseする）。

問題点として、 [Issue Mover For Github(by Google)](https://github-issue-mover.appspot.com/)は1件ずつしかissueを移動させることができない。

勘の良い方ならお気づきだと思うが、「移動作業をiMacrosで自動化してしまえば数百件でも処理できる！！」ということである。

### 下準備
- [Firefoxのインストール](https://www.mozilla.org/ja/firefox/new/)
- [iMacrosのインストール](https://addons.mozilla.org/ja/firefox/addon/imacros-for-firefox/)

### マクロを組む
まずは1件ずつ[Issue Mover For Github(by Google)](https://github-issue-mover.appspot.com/)を操作するマクロを組もう。
iMacrosの使い方は[こちらを参考](http://imacros.doorblog.jp/)にさせたもらった。15~30分ぐらいで簡単に理解できる。
http://imacros.doorblog.jp/

組んだマクロはこちら。

```IssueMoverForGithub.iim
VERSION BUILD=9030808 RECORDER=FX
TAB T=1
URL GOTO=https://github-issue-mover.appspot.com/
TAG POS=1 TYPE=INPUT:TEXT FORM=NAME:sf1 ATTR=ID:issue CONTENT=fortkle/test_a#100
TAG POS=1 TYPE=INPUT:TEXT FORM=NAME:sf1 ATTR=ID:repo CONTENT=fortle/test_b
WAIT SECONDS=2
TAG POS=1 TYPE=BUTTON ATTR=ID:move
WAIT SECONDS=10
TAG POS=1 TYPE=BUTTON ATTR=ID:close
```
上記は「fortkle/test_aにあるissue#100をfortkle_test_bに移動する」作業のマクロである。

ハマりどころだけ解説すると、
`WAIT SECONDS=2` とあるが、ここで2秒ほど待たないとボタンがクリックできなかった。
また、 `WAIT SECONDS=10`と書いてあるところは10秒でなくても良いが、issueのコメントの移動に時間がかかるので平均10秒ほどsleepを入れればほとんどのissueは問題なく移動できた。10秒待つとだいたい15件ほどのコメントが付いたissueなら問題なく移行できる。
もし15件以上のissueがあるなら手動で移しておくか、 `WAIT SECONDS=10`の数字をもっと大きくすればよい。

ここまでで、1件移動させる作業を自動化させることができた。

# 3. iMacrosをjsで操作して移行対象リストをループで処理
iMacros for Firefoxではjsを使って連携することができる。jsを使ってiMacrosのマクロを呼び出し、ループさせて数百件のissueを一括移動させれば目的を達成できる。

さっそくiMacrosを操作するjsを作成する。
その前に、事前に作成したマクロを外から対象issueを渡せるようにしておく。

```IssueMoverForGithub.iim
VERSION BUILD=9030808 RECORDER=FX
TAB T=1
URL GOTO=https://github-issue-mover.appspot.com/
TAG POS=1 TYPE=INPUT:TEXT FORM=NAME:sf1 ATTR=ID:issue CONTENT=fortkle/test_a#{{!VAR1}}
TAG POS=1 TYPE=INPUT:TEXT FORM=NAME:sf1 ATTR=ID:repo CONTENT=fortle/test_b
WAIT SECONDS=2
TAG POS=1 TYPE=BUTTON ATTR=ID:move
WAIT SECONDS=10
TAG POS=1 TYPE=BUTTON ATTR=ID:close
```

変わった点は `fortkle/test_a#{{!VAR1}}`のように移行対象のissue idを引数で渡せるようにした点だけだ。

では、上記のマクロをjsで操作してみる。 マクロ（`IssueMoverForGithub.iim`）と同じ階層に js（仮に `exec.js`）を作成する。

![Issue_Mover_for_GitHub.png](https://qiita-image-store.s3.amazonaws.com/0/6159/48b1e108-3e67-eeab-3d42-896ff15f435c.png)

```exec.js
var targetIssueId = [
// ここに 作業 1. で取得移行対象のidを貼り付ける。
100,
101,
102,
];
for(var i=0; i<targetIssueId.length; i++){
  iimSet("!VAR1", targetIssueId[i]);
  iimPlay("IssueMoverForGithub");
}
```

最後にこのexec.jsを実行すれば数百件でも作業を自動化できる。