1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GraphQL APIでproject(beta)の紐つくissueを集計してみた

Last updated at Posted at 2023-12-26

はじめに

人力作業が嫌い、無くしたいと言う願望から
GraphQLを使うための備忘録
GASで集計結果をgoogle sheetに書き込む(略)
今までのgithub apiではproject(beta)が取れない

手順

  1. Github Personal access tokens発行
  2. queryを作成する(もしくはmutations)
  3. queryをhttps://api.github.com/graphqlAPIで投げてquery通りのjsonが返ってくる
  4. json stringを解析して結果出力

Github Personal access tokensについて

これはgithubのsetting画面から操作するだけ。

  • Organizationの認証とか権限の設定とかあるかもしれない
  • 今回はclassicのtokenを作ってrepoとprojectの権限を付与しました。

作り方

ここで初めて触った人は少し苦労するかもしれませんが構成や要件それぞれなので本当にリファレンスみてそれを理解した方が自由に組める。

今回の要件
  • 集計したいissueは全て同じrepositoryにある
  • 集計対象issueは特定のlabelが付く
  • 集計対象issueは特定のproject(beta)に紐づかれている
  • 対象issueの特定属性で合計値をassigneeごとに集計したい
まずはコード
const variables = {
    org: "Your Org",
    repo: "Your Repo",
    assignee: "Your Assignee",
    label: "Your Label",
    since: "issue最後更新時間をfilterしている"
  };
  const query = `
    query($org: String!, $repo: String!, $label: String!, $assignee: String, $since: DateTime!) {
      repository(owner: $org, name: $repo) {
        issues(last: 100, filterBy: {labels: [$label], since: $since, assignee: $assignee}) {
          totalCount
          nodes {
            number
            title
            url
            projectItems(first: 1) {
              nodes{
                filterColumn: fieldValueByName(name: "filterかけたい項目名") {
                    ... on ProjectV2ItemFieldIterationValue{
                      title
                    }
                }
                cost: fieldValueByName(name: "集計したい値") {
                    ... on ProjectV2ItemFieldNumberValue{
                      number
                    }
                }
              }
            }
          }
        }
      }
    }
  `;

  const options = {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${Your token}`,
      "Accept": "application/json",
      "Content-Type": "application/json"
    },
    payload: JSON.stringify({ query: query, variables: variables })
  };

  const response = UrlFetchApp.fetch('https://api.github.com/graphql', options);
  const issues = JSON.parse(response.getContentText());

今回使ったobject

細かいポイント
  • queryの変数について
    • 変数声明仕方$+変数名: で使う時は$+変数名
    • !がつくとnon null、付かない場合はnullable
    • object型入力はJson objectを引数として渡せます(例:filterByのところ)
    • 声明した変数はvariablesobjectに渡すとqueryに適応されます
  • queryの中身について
    • リファレンスから欲しいobjectを探し出しましょう
    • 全てのobjectはNodeを継承している
    • nodesがArrayになる
    • arrayにアクセスするためには基本paging想定されます
      • 件数が少ない場合なら決め打ちで最大以上の件数分とってこれるが、多い場合はPageInfoを使ってpagingの仕組みをくむ
    • ... on {Type}が型filter、Arrayの中は汎用型が含まれる場合が多いからたくさん使う
  • 認証について
    • headderのAuthorizationtokenを渡す
    • tokenの前に固定文字Bearer+スペースを忘れずに
    • 認証失敗すると401Bad credentialsになる
  • レスポンスの使い方について
    • query以下の構造は記載した階層の通りでjson string返却される。
    • 例えばfilterかけたい項目名をアクセスしたい場合はissues.data.repository.issues.nodes[0].projectItems.nodes[0].filterColumn.title

最後に

queryのデバグは割と簡単でresponse.getContentText()の中にエラーの詳細が返却されるのでそれをLogに出せばなんとかなるはず。
ほぼ自分見返す用ですが誰かに役立つと嬉しいです。

1
1
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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?