LoginSignup
1
2

More than 5 years have passed since last update.

GitHubのissueを移行したい・API操作したい

Last updated at Posted at 2018-02-18

実現するCLI兼Node.jsクライアントライブラリを作りました(PR/projectsの操作も実装中)
https://www.npmjs.com/package/issue-ctl

使い方

https://github.com/darai0512/issue-ctl をご覧ください

CLI

$issue-ctl migrate
posted old issue#1 to new issue#4
posted old issue#2 to new issue#5
posted old issue#3 to new issue#6

in Node.js

slackやjiraなどとbot経由で連携するのに便利かと


const {issue} = require('issue-ctl');

const main = async () => {
  const issues = await issue.get('api.github.com', 'org/repo', 'username:passwd');
  // ex, issues.title = prefix + issues.title + postfix;
  await issue.post('your.enterprise.url', 'org/repo', 'oauth2token', issues);
};

// 申し訳ありませんがUnhandledPromiseRejectionWarningが発生します(後述)
// 現在リファクタリング中ですが、エラーハンドリングされたい方は下記を記述ください
process.on('unhandledRejection', (reason, pos) => {
  console.log('at:', pos, 'reason:', reason);
});

main().catch((err) => console.error(err));

できること

  • 特定のリポジトリからissue(PRを除く)を全て取得する
    • 紐付くコメント、ラベル、マイルストーン、アサイン者情報も取得
  • 特定のリポジトリへissueを全てPOSTする
    • 紐付くコメント(順番保持)、ラベル、マイルストーン、アサイン者情報も登録
    • closeしたissueなら登録後closeされる
    • 新規POSTのため、移行前後でissue番号は異なる

やりたかったこと

  • GitHub Enterprise(v2.11)からGitHubへ、コードの公開にあたりissueを移行したい
  • その際、一般に公開できない部分のコードはラップするため、直書きされていた過去のcommit情報は移行させたくない
  • 移行先は既に運用中で、新しいissueなどが作られ続けている
  • リポジトリのマイグレーションはGitHubにAPIで用意されているが、commit履歴も移行されてしまうし、移行先が初期化されるので使えない
  • 移行時に、従来のissueを指定フォーマット(スクラムのユーザーストーリー)に置換したい
    • ex, FEチームとして、${old_title}したい。なぜなら、業務効率化に繋がるから。
    • Get時にファイルにJSONで落とすので、必要に応じて置換し、Postできるよう実装

調査

Tips

内部実装

  • Node.jsのcore APIのみで実装。ブラウザJSでは動作しません。
  • getではリポジトリ内のissueとcommentを100件ずつpagingしながら全件取得します。commentの取得はissue単位ではなくリポジトリ単位で、後から紐付けています。API実行回数は最小のはずですが、利用回数制限がかかっている場合は注意ください。
  • postは1秒ごとに1 issueずつ
    • 紐付くコメント・closedの場合はその操作も含めて

Promise のエラーハンドリング漏れ

上述の通り、一部async/awaitでcatch漏れがあり、下記エラーが発生することがあります。

(node:111) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: ***
(node:111) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

このエラーログだけではコードのどの部分でハンドリングが漏れているのかわかりません。
発生箇所特定のためには、上述のようにunhandledRejectionイベントを登録ください。
これでPromiseの包括的なエラーハンドリングが可能ですが、公式ではこれに頼ってエラーハンドリングを放棄することは推奨していません。
(理由は内部実装を見てみるとわかります、機会があれば記事化します)

これでいつも通りのスタックトレースが見れるので、原因のPromiseでcatch処理を入れれば特定可能です。よければPRお待ちしております。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2