管理するメンバーが増える & 複数のRepositoryに跨ったプロジェクトだったりすると issueのアサインに時間が掛かることがあるので、特定の記事をモンハンのクエストボードみたいに見立てて、そこから自分に合ったissueを引き受けるような仕組みを作ると楽そうだなと思い以下のスクリプトを作成
PR
実装
大まかな実装は以下の通り
- Cloud Functions のPub/Subを作成
- GitHub AppsからTokenを取得
- GItHub APIから以下の条件でissueを抽出
- アサイン募集中のラベルが設定されている
- 誰もアサインされていない
- 上記のissueを抽出してテキストを作成
- 作成テキストをKibela APIを使用して記事を更新
- 上記のCloud FunctionsをCloud Scheduleで定期実行させる
まず、以下の記事を参考にGitHub Appsの作成
作成したGitHub Appsから以下を取得 - Installation ID → GitHub Appsのinstall Appの画面のURLから値を確認できる - GitHub App ID - GitHub AppのPrivate keysを作成
Private keysはprivate-key.pemにファイル名を変更してカレントのフォルダに配置して以下のコマンドで環境変数を設定
export GITHUB_APP_PRIVATE_KEY=$(cat private-key.pem) export GITHUB_APP_ID=***** export INSTALLATION_ID=*****
以下のコードでGitHub APIのトークンを取得できる
■ postAssignableIssues/function.go
func PostAssignableIssuesPubSub(ctx context.Context, m *pubsub.Message) error { InstallationID, err := strconv.Atoi(os.Getenv("INSTALLATION_ID")) if err != nil { return err } githubAppID := os.Getenv("GITHUB_APP_ID") appID, err := strconv.ParseInt(githubAppID, 10, 64) if err != nil { return err } key := os.Getenv("GITHUB_APP_PRIVATE_KEY") tr := http.DefaultTransport itr, err := ghinstallation.New(tr, appID, int64(InstallationID), []byte(key)) if err != nil { return err } token, err := itr.Token(ctx)
トークンを使用してGitHub APIを実行する GitHub APIでは、以下のGraphQLでアサイン募集中のラベルが設定されていて、アサインの無いissueを抽出できる
query Repository($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { issues(first: 100, states: [OPEN], labels: ["アサイン募集中"], orderBy: {field: CREATED_AT, direction: DESC}, filterBy: {assignee: null}) { nodes { id title url } } } }
このGraphQLを使用してissueを抽出してテキストを作成する 実装コードは以下のファイルを参照
さらに、ここに以下の設定したラベル毎にカテゴリーに分けて表示する実装を追加
ラベル名 | 内容 |
---|---|
RFP | Request For Proposalの略。問題を記載しているのでプロポーザルを記載して全体に共有する |
ドキュメンテーション | ドキュメントにまとめて共有する |
設計前 | 機能の設計書を作成する |
運用改善 | 運用改善系/効率化の対応 |
上記のラベルが無い場合は開発issueの項目に表示される
実装コードは以下のファイルを参照
このコードで生成されるテキストが以下の通り ※表示の元になっているissueは、こちら
### ■ tool-test #### ドキュメンテーション - [06_アサイン募集中_ドキュメンテーション](https://github.com/wheatandcat/tool-test/issues/6) #### RFP - [05_アサイン募集中_ RFP](https://github.com/wheatandcat/tool-test/issues/5) #### 開発issue - 【v1.0.0】[07_アサイン募集中_マイルストーン設定](https://github.com/wheatandcat/tool-test/issues/7) - [02_アサイン募集中](https://github.com/wheatandcat/tool-test/issues/2) - [01_アサイン募集中](https://github.com/wheatandcat/tool-test/issues/1)
上記のテキストを使用してKibela APIから記事の更新を行う
Kibela APIについては以下を参照 github.com
Kibela APIはGraphQLで実装されているので、以下のQueryで記事の内容の取得
query Note($id: ID!) { note(id: $id) { id title url content } }
以下のMutationで記事の更新が行える
mutation UpdateNoteContent($input: UpdateNoteContentInput!) { updateNoteContent(input: $input) { clientMutationId note { id content } } }
上記のGraphQLを使用して記事を更新すると以下のような内容で記事が更新される
ここまでで記事の更新は完了なので、次はCloud Functionを以下のコマンドでデプロイする
$ gcloud functions deploy PostAssignableIssuesPubSub --set-env-vars GITHUB_APP_PRIVATE_KEY=$GITHUB_APP_PRIVATE_KEY,GITHUB_APP_ID=$GITHUB_APP_ID,GITHUB_OWNER=$GITHUB_OWNER,INSTALLATION_ID=$INSTALLATION_ID,NOTE_TOKEN=$NOTE_TOKEN,NOTE_ID=$NOTE_ID,NOTE_HOST=$NOTE_HOST --runtime go116 --trigger-resource post_assignable_issues --trigger-event google.pubsub.topic.publish --region asia-northeast1
以下でデプロイされているのを確認
最後に上記のCloud FunctionをCloud Scheduleのジョブに追加 ターゲットタイプをPub/Subでトピックを上記のCloud Functionに設定して追加
上記の設定で定期的にCloud Functionを実行して記事の更新がされるようになる
以上で実装完了。もし同じような問題をプロジェクトで抱えていたら、こんな方法で自動化できるかもという話でした。