【GitHub】GraphQL で issue を登録する

GraphQL を試すために、GitHub が提供している GraphQL を使ってみたいと思います。実際に GraphQL を使用して issue の登録から project 内で issue の移動までやってみます。GraphQL の実行環境として[playgroud](https://github.com/graphql/graphql-playground)を使います。


## 準備

まずは適当なリポジトリを作ります。その後、issue を project で管理するためにproject を用意します。
project の登録は「projects」タブから[New project]を選択することで作成できます。
![project-todo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/780549/3e7610b8-1c57-972f-5075-ca66c7e0e0a9.png)

project を作成したら、任意の数だけカラムを作成します（ここでは「Backlog」「In Progress」「Done」を作成）。
issue が追加されたら「Backlog」に追加されるように automation も設定しておきます。

automation の設定は、カラムの「・・・」を選択し[Manage automation]を選択。
![manage-automation.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/780549/0e0110f6-5232-d616-98cc-b85ac7a00dce.png)

[Newly added]を選択。
![newly-added.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/780549/19b68ed3-b231-e72b-2395-192dd3c90dbc.png)

これで、新規登録した issue がこのプロジェクトに関連づけられていたら自動的に「Backlog」に表示されるようになります。

## issue 登録

GraphQL で issue を登録してみます。issue を登録するには``repository id``が必要なのでまずはこちらを取得します。ついでに、issue を project に関連付けるために``project id``と、後ほど issue に対して label も追加するので``label id``も一緒に取得しておきます。

GitHub の GraphQL を使用するには、ヘッダーに[アクセストークン](https://docs.github.com/ja/github/authenticating-to-github/keeping-your-account-and-data-secure/creating-a-personal-access-token)を設定する必要があります。アクセストークンを付与した上で各クエリを実行してください。

```json:Header
{
  "Authorization": "Bearer access-token"
}
```

ヘッダーを設定したら次のクエリを実行して結果が取得できるか確認してみてください。（``name``にはリポジトリ名を、``owner``には GitHub のユーザー名を指定してください。）

### 

```graphql
query getProjectLabels {
  repository(name:"PersonalTaskManagement", owner:"kiyo27") {
    id
    name
    projects(search:"todo", first:1) {
      nodes {
        id
        name
        columns(first:3) {
          nodes {
            id
            name
            cards {
              nodes {
                id
                content {
                  __typename
                  ... on Issue {
                    id
                    title
                  }
                }
              }
            }
          }
        }
      }
    }
    labels(first: 10) {
      nodes {
        id
        name
      }
    }
  }
}
```

取得結果：

```json
{
  "data": {
    "repository": {
      "id": "repository-id-xxxxxxxxxxxxxxxxxxx",
      "name": "PersonalTaskManagement",
      "projects": {
        "nodes": [
          {
            "id": "project-id-xxxxxxxxxxxx",
            "name": "todo",
            "columns": {
              "nodes": [
                {
                  "id": "column-id-xxxxxxxxxxxxxxxxxxx",
                  "name": "Backlog",
                  "cards": {
                    "nodes": []
                  }
                },
                {
                  "id": "column-id-xxxxxxxxxxxxxxxxxxx",
                  "name": "In Progress",
                  "cards": {
                    "nodes": []
                  }
                },
                {
                  "id": "column-id-xxxxxxxxxxxxxxxxxxx",
                  "name": "Done",
                  "cards": {
                    "nodes": []
                  }
                }
              ]
            }
          }
        ]
      },
      "labels": {
        "nodes": [
          {
            "id": "label-id-xxxxxxxxxxxxxxxxxxxxx",
            "name": "bug"
          },
          {
            "id": "label-id-xxxxxxxxxxxxxxxxxxxxx",
            "name": "documentation"
          },
          {
            "id": "label-id-xxxxxxxxxxxxxxxxxxxxx",
            "name": "duplicate"
          },
          {
            "id": "label-id-xxxxxxxxxxxxxxxxxxxxx",
            "name": "enhancement"
          },
          {
            "id": "label-id-xxxxxxxxxxxxxxxxxxxxx",
            "name": "help wanted"
          },
          {
            "id": "label-id-xxxxxxxxxxxxxxxxxxxxx",
            "name": "good first issue"
          },
          {
            "id": "label-id-xxxxxxxxxxxxxxxxxxxxx",
            "name": "invalid"
          },
          {
            "id": "label-id-xxxxxxxxxxxxxxxxxxxxx",
            "name": "question"
          },
          {
            "id": "label-id-xxxxxxxxxxxxxxxxxxxxx",
            "name": "wontfix"
          }
        ]
      }
    }
  }
}
```

### 登録

取得した``repository id``と``project id``、``label id``を使用して issue を登録します。

```graphql
mutation createIssue {
  createIssue(input:{title: "Create issue from GraphQL", repositoryId :"repository-id-xxxxxxxxxxxxxxxxxxx", projectIds:"project-id-xxxx", labelIds: ["label-id-xxxxxxx"]}) {
    issue {
      id
    }
  }
}
```

実行結果：

```json
{
  "data": {
    "createIssue": {
      "issue": {
        "id": "issue-id-xxxxxxxxxxxx"
      }
    }
  }
}
```

project を確認すると issue が「Backlog」に表示されているのが確認できます。
![first-issue.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/780549/5553ef75-b644-a638-bc74-83436469c0ab.png)

## issue 更新

登録した issue を GraphQL で更新してみます。issue の更新には``issue id``が必要なので、先ほど実行したクエリの戻り値の``id``を指定します。

```graphql
mutation updateIssue{
  updateIssue(input:{id: "issue-id-xxxxxxxxx", title:"Hello world, GraphQL"}) {
    issue {
      id
    }
  }
}
```

実行結果：

```json
{
  "data": {
    "updateIssue": {
      "issue": {
        "id": "iisue-id-xxxxxx"
      }
    }
  }
}
```

project を確認すると、タイトルが変わっているのが確認できます。
![issue-edit.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/780549/1c0a167c-21e7-b11f-70b5-761f376f7b58.png)

## ProjectCard 移動

今登録した issue は「Backlog」の列にあるので、「In Progress」に移動させてみます。issue を移動させるためには``card id``と``column id``が必要になるので下記のクエリを実行して取得します。

```graphql
query getIssue {
  search(query:"Hello world, GraphQL", type:ISSUE, first:1) {
    nodes {
      __typename
      ... on Issue {
        title
        projectCards {
          nodes {
            id
            project {
              name
              columns(first:3) {
                nodes {
                  id
                  name
                }
              }
            }
          }
        }
      }
    }
  }
}
```

実行結果：

```json
{
  "data": {
    "search": {
      "nodes": [
        {
          "__typename": "Issue",
          "title": "Hello world, GraphQL",
          "projectCards": {
            "nodes": [
              {
                "id": "project-card-id-xxxxxxxxx",
                "project": {
                  "name": "todo",
                  "columns": {
                    "nodes": [
                      {
                        "id": "column-backlog-id-xxxxxxxx",
                        "name": "Backlog"
                      },
                      {
                        "id": "column-in-progress-id-xxxxxxxxx",
                        "name": "In Progress"
                      },
                      {
                        "id": "column-done-id-xxxxxxxxxxxx",
                        "name": "Done"
                      }
                    ]
                  }
                }
              }
            ]
          }
        }
      ]
    }
  }
}
```

取得内容から``project-card-id-xxxxxxxxx``と issue の移動先である``column-in-progress-id-xxxxxxxxx``を使用します。issue を移動させてみます。

```graphql
mutation moveProjectCard {
  moveProjectCard(input:{cardId:"PRC_lALOF65GMM4Ax90azgQCJLY", columnId:"project-card-id-xxxxx"}) {
    cardEdge {
      node {
        url
      }
    }
  }
}
```

実行結果：

```json
{
  "data": {
    "moveProjectCard": {
      "cardEdge": {
        "node": {
          "url": "https://github.com/kiyo27/PersonalTaskManagement/projects/1#card-xxxxx"
        }
      }
    }
  }
}
```

project を確認すると、「In Progress」に移動しているのが確認できます。
![issue-in-progress.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/780549/f5628046-0f47-95ff-f5cb-d218a7f8fbd4.png)

以上、 GitHub の GraphQL を使用した簡単な issue と project の操作でした。

## 参考
doc
https://docs.github.com/ja/graphql