TaskSphere:GitHubのプロジェクト管理機能を使ってアイテム情報を取得しよう

GitHub連携

こんにちは!今日は、GitHubのプロジェクト管理機能を使って、プロジェクト内のアイテム情報を取得する方法を学びましょう。

デモ動画

事前準備

始める前に、以下の準備が必要です。

  1. GitHubのPersonal Access Tokenを取得しておきます。
  2. 環境変数に以下の情報を設定しておきます。
    • GITHUB_PERSONAL_ACCESS_TOKEN: GitHubのPersonal Access Token
    • GITHUB_USER_LOGIN: GitHubのユーザーログイン名
    • GITHUB_PROJECT_NUMBER: 情報を取得したいプロジェクトの番号

必要なライブラリのインストール

以下のライブラリを使用するので、インストールしておきましょう。

pip install requests termcolor art
  • requests: HTTP リクエストを送信するためのライブラリ
  • termcolor: ターミナルの出力に色をつけるためのライブラリ
  • art: アスキーアートを表示するためのライブラリ

コードの説明

それでは、コードを詳しく見ていきましょう。

環境変数の取得

token = os.environ.get("GITHUB_PERSONAL_ACCESS_TOKEN")
user_login = os.environ.get("GITHUB_USER_LOGIN")
project_number = os.environ.get("GITHUB_PROJECT_NUMBER")

ここでは、事前に設定した環境変数から、GitHubのPersonal Access Token、ユーザーログイン名、プロジェクト番号を取得しています。

GraphQLクエリの定義

query_project = """
query {
  user(login: "USER_LOGIN") {
    projectV2(number: NUMBER) {
      title
      id
    }
  }
}
"""

query_items = """
query {
  node(id: "PROJECT_ID") {
    ... on ProjectV2 {
      items(first: 20) {
        nodes {
          id
          fieldValues(first: 8) {
            nodes {
              ... on ProjectV2ItemFieldTextValue {
                text
                field {
                  ... on ProjectV2FieldCommon {
                    name
                  }
                }
              }
              ... on ProjectV2ItemFieldDateValue {
                date
                field {
                  ... on ProjectV2FieldCommon {
                    name
                  }
                }
              }
              ... on ProjectV2ItemFieldSingleSelectValue {
                name
                field {
                  ... on ProjectV2FieldCommon {
                    name
                  }
                }
              }
            }
          }
          content {
            ... on DraftIssue {
              title
              body
            }
            ... on Issue {
              title
              assignees(first: 10) {
                nodes {
                  login
                }
              }
            }
            ... on PullRequest {
              title
              assignees(first: 10) {
                nodes {
                  login
                }
              }
            }
          }
        }
      }
    }
  }
}
"""

ここでは、GraphQLクエリを定義しています。query_projectはプロジェクトの情報を取得するためのクエリで、query_itemsはプロジェクト内のアイテム情報を取得するためのクエリです。

プロジェクト情報の取得

query_project = query_project.replace("USER_LOGIN", user_login)
query_project = query_project.replace("NUMBER", project_number)

data_project = {
    "query": query_project
}

response_project = requests.post("https://api.github.com/graphql", headers=headers, json=data_project)

ここでは、query_project内のプレースホルダーを実際の値に置き換え、GitHub APIにPOSTリクエストを送信してプロジェクト情報を取得しています。

アイテム情報の取得

query_items = query_items.replace("PROJECT_ID", project_id)

data_items = {
    "query": query_items
}

response_items = requests.post("https://api.github.com/graphql", headers=headers, json=data_items)

ここでは、query_items内のプレースホルダーを実際の値に置き換え、GitHub APIにPOSTリクエストを送信してアイテム情報を取得しています。

アイテム情報の表示

items = response_items.json()["data"]["node"]["items"]["nodes"]

print("---------------------------")
print(colored("Items:", "magenta"))
for item in items:
    print(colored(f"Item ID: {item['id'][:4]}XXXXXXXXXX", "cyan"))

    field_values = item["fieldValues"]["nodes"]
    for field_value in field_values:
        if "text" in field_value:
            print(colored(f"{field_value['field']['name']}: {field_value['text']}", "yellow"))
        elif "date" in field_value:
            print(colored(f"{field_value['field']['name']}: {field_value['date']}", "yellow"))
        elif "name" in field_value:
            print(colored(f"{field_value['field']['name']}: {field_value['name']}", "yellow"))

    content = item["content"]
    if "title" in content:
        print(colored(f"Title: {content['title']}", "green"))
    if "body" in content:
        print(colored(f"Body: {content['body']}", "green"))
    if "assignees" in content:
        assignees = [assignee["login"] for assignee in content["assignees"]["nodes"]]
        print(colored(f"Assignees: {', '.join(assignees)}", "green"))

    print("---")

最後に、取得したアイテム情報を表示しています。各アイテムのID、フィールド値、コンテンツ情報(タイトル、本文、担当者)を色付きで出力しています。

コード全体

それでは、コード全体を見てみましょう。

import os
import requests
from termcolor import colored
from art import *
import pprint

script_name = os.path.basename(__file__)
tprint(script_name)

# 環境変数からGitHubのPersonal Access Tokenを取得
token = os.environ.get("GITHUB_PERSONAL_ACCESS_TOKEN")
user_login = os.environ.get("GITHUB_USER_LOGIN")
project_number = os.environ.get("GITHUB_PROJECT_NUMBER")

# トークンが設定されていない場合はエラーを表示して終了
if token is None or user_login is None or project_number is None:
    print("Error: Required environment variables are not set.")
    exit(1)

# プロジェクト情報を取得するためのGraphQLクエリ
query_project = """
query {
  user(login: "USER_LOGIN") {
    projectV2(number: NUMBER) {
      title
      id
    }
  }
}
"""

# アイテム情報を取得するためのGraphQLクエリ
query_items = """
query {
  node(id: "PROJECT_ID") {
    ... on ProjectV2 {
      items(first: 20) {
        nodes {
          id
          fieldValues(first: 8) {
            nodes {
              ... on ProjectV2ItemFieldTextValue {
                text
                field {
                  ... on ProjectV2FieldCommon {
                    name
                  }
                }
              }
              ... on ProjectV2ItemFieldDateValue {
                date
                field {
                  ... on ProjectV2FieldCommon {
                    name
                  }
                }
              }
              ... on ProjectV2ItemFieldSingleSelectValue {
                name
                field {
                  ... on ProjectV2FieldCommon {
                    name
                  }
                }
              }
            }
          }
          content {
            ... on DraftIssue {
              title
              body
            }
            ... on Issue {
              title
              assignees(first: 10) {
                nodes {
                  login
                }
              }
            }
            ... on PullRequest {
              title
              assignees(first: 10) {
                nodes {
                  login
                }
              }
            }
          }
        }
      }
    }
  }
}
"""

# クエリ内のプレースホルダーを実際の値に置き換える
query_project = query_project.replace("USER_LOGIN", user_login)
query_project = query_project.replace("NUMBER", project_number)

# リクエストヘッダー
headers = {
    "Authorization": f"Bearer {token}",
    "Content-Type": "application/json"
}

# プロジェクト情報を取得するためのリクエストデータ
data_project = {
    "query": query_project
}

# プロジェクト情報を取得するためにGitHub APIにPOSTリクエストを送信
response_project = requests.post("https://api.github.com/graphql", headers=headers, json=data_project)

# レスポンスにエラーがあるかどうかを確認
if "errors" in response_project.json():
    print(f"Error: {response_project.json()['errors'][0]['message']}")
    exit(1)

# レスポンスからプロジェクトのタイトルとIDを取得
project_title = response_project.json()["data"]["user"]["projectV2"]["title"]
project_id = response_project.json()["data"]["user"]["projectV2"]["id"]

print(colored(f"Project Title: {project_title}", "green"))
print(colored(f"Project ID: {project_id[:4]}XXXXXXXXXX", "cyan"))

# アイテム情報を取得するためのクエリ内のプレースホルダーを実際の値に置き換える
query_items = query_items.replace("PROJECT_ID", project_id)

# アイテム情報を取得するためのリクエストデータ
data_items = {
    "query": query_items
}

# アイテム情報を取得するためにGitHub APIにPOSTリクエストを送信
response_items = requests.post("https://api.github.com/graphql", headers=headers, json=data_items)

# レスポンスにエラーがあるかどうかを確認
if "errors" in response_items.json():
    print(f"Error: {response_items.json()['errors'][0]['message']}")
    exit(1)

# レスポンスからアイテム情報を取得
items = response_items.json()["data"]["node"]["items"]["nodes"]

print("---------------------------")
print(colored("Items:", "magenta"))
for item in items:
    print(colored(f"Item ID: {item['id'][:4]}XXXXXXXXXX", "cyan"))

    # フィールド値を表示
    field_values = item["fieldValues"]["nodes"]
    for field_value in field_values:
        if "text" in field_value:
            print(colored(f"{field_value['field']['name']}: {field_value['text']}", "yellow"))
        elif "date" in field_value:
            print(colored(f"{field_value['field']['name']}: {field_value['date']}", "yellow"))
        elif "name" in field_value:
            print(colored(f"{field_value['field']['name']}: {field_value['name']}", "yellow"))

    # コンテンツの情報を表示
    content = item["content"]
    if "title" in content:
        print(colored(f"Title: {content['title']}", "green"))
    if "body" in content:
        print(colored(f"Body: {content['body']}", "green"))
    if "assignees" in content:
        assignees = [assignee["login"] for assignee in content["assignees"]["nodes"]]
        print(colored(f"Assignees: {', '.join(assignees)}", "green"))

    print("---")

これで、GitHubのプロジェクト管理機能を使ってアイテム情報を取得するPythonスクリプトが完成しました!

まとめ

今回は、以下のことを学びました。

  1. GitHubのプロジェクト管理機能を使ってアイテム情報を取得する方法
  2. GraphQLクエリを使ってGitHub APIからデータを取得する方法
  3. 取得したデータを処理して、必要な情報を表示する方法

このスクリプトを使えば、GitHubのプロジェクト内のアイテム情報を簡単に取得し、活用することができます。ぜひ、自分のプロジェクトで試してみてください!

初心者の方でも、このスクリプトを理解し、活用できるようになったと思います。これからもGitHubのAPIを使って、さまざまな情報を取得し、活用していきましょう!

リポジトリ

GitHub - Sunwood-ai-labs/TaskSphere
Contribute to Sunwood-ai-labs/TaskSphere development by creating an account on GitHub.

参考サイト

API を使用して Projects を管理する - GitHub Docs
GraphQL API を使用して、プロジェクトを自動化できます。
GitHub GraphQL APIを利用し、複数リポジトリが紐づくGitHub ProjectsのIssueリストを取得する - いいものを広め隊
はじめに 今回想定するGitHub Projects GitHub GraphQL APIを使うまでの準備 1. アクセストークンの登録 2. Issueを取得したいGitHub Projectsのidを取得する 今回はPythonで実行します GitHub Projectsに紐づくIssue一覧を取得する 特定のステ...
個人用アクセス トークンを管理する - GitHub Docs
コマンド ラインまたは API を使用して GitHub への認証を行うときに、パスワードの代わりに personal access token を使用することができます。

コメント

タイトルとURLをコピーしました