- TaskSphere:GitHubプロジェクトの認証と情報取得
- TaskSphere:GitHubプロジェクトのフィールドIDを取得するPythonスクリプト
- TaskSphere:GitHub プロジェクトにドラフトIssueを追加する Python スクリプト
- TaskSphere:GitHubのプロジェクト管理機能を使ってアイテム情報を取得しよう
- TaskSphere:GitHub プロジェクトの情報を取得・更新する Python スクリプト
こんにちは!今日は、GitHub の新しい Project V2 API を使って、プロジェクトにドラフトIssueを追加する Python スクリプトを一緒に作っていきましょう。
デモ動画
必要な環境変数
このスクリプトを実行するには、以下の環境変数が必要です。
GITHUB_PERSONAL_ACCESS_TOKEN
: GitHub の Personal Access TokenGITHUB_USER_LOGIN
: GitHub のユーザーログイン名GITHUB_PROJECT_NUMBER
: 対象のプロジェクト番号
これらの環境変数は、スクリプトを実行する前に設定しておいてください。
インポートと環境変数の取得
import os
import requests
from termcolor import colored
from art import *
script_name = os.path.basename(__file__)
tprint(script_name)
token = os.environ.get("GITHUB_PERSONAL_ACCESS_TOKEN")
user_login = os.environ.get("GITHUB_USER_LOGIN")
project_number = os.environ.get("GITHUB_PROJECT_NUMBER")
ここでは、必要なライブラリをインポートし、環境変数から必要な情報を取得しています。
os
: ファイル名を取得するために使用requests
: GitHub API にリクエストを送信するために使用termcolor
: 出力をカラフルにするために使用art
: スクリプト名をアスキーアートで表示するために使用
環境変数の検証
def validate_environment_variables():
if token is None or user_login is None or project_number is None:
print("Error: Required environment variables are not set.")
exit(1)
validate_environment_variables()
関数は、必要な環境変数が設定されているかどうかを確認します。設定されていない場合は、エラーメッセージを表示してスクリプトを終了します。
プロジェクト情報の取得
def get_project_info():
query_project = """
query {
user(login: "USER_LOGIN") {
projectV2(number: NUMBER) {
title
id
}
}
}
"""
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)
if "errors" in response_project.json():
print(f"Error: {response_project.json()['errors'][0]['message']}")
exit(1)
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}", "cyan"))
return project_id
get_project_info()
関数は、指定されたプロジェクトの情報を取得します。
- GraphQL クエリを定義し、
USER_LOGIN
とNUMBER
をそれぞれuser_login
とproject_number
に置き換えます。 - クエリを実行し、レスポンスをチェックします。エラーがある場合は、エラーメッセージを表示してスクリプトを終了します。
- レスポンスからプロジェクトのタイトルとIDを取得し、表示します。
- プロジェクトIDを返します。
プロジェクト内のアイテムの取得
def get_project_items(project_id):
query_items = """
query {
node(id: "PROJECT_ID") {
... on ProjectV2 {
items(first: 20) {
nodes {
id
content {
... on DraftIssue {
title
body
}
... on Issue {
title
number
assignees(first: 10) {
nodes {
login
}
}
}
... on PullRequest {
title
number
assignees(first: 10) {
nodes {
login
}
}
}
}
}
}
}
}
}
"""
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)
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'][:6]}_XXXXXXXXXXXX", "cyan"))
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 "number" in content:
print(colored(f"Number: {content['number']}", "green"))
if "assignees" in content:
assignees = [assignee["login"] for assignee in content["assignees"]["nodes"]]
print(colored(f"Assignees: {', '.join(assignees)}", "green"))
print("---")
get_project_items()
関数は、指定されたプロジェクト内のアイテムを取得します。
- GraphQL クエリを定義し、
PROJECT_ID
をプロジェクトIDに置き換えます。 - クエリを実行し、レスポンスをチェックします。エラーがある場合は、エラーメッセージを表示してスクリプトを終了します。
- レスポンスからアイテムのリストを取得します。
- 各アイテムの情報(ID、タイトル、本文、番号、担当者)を表示します。
プロジェクトにドラフトIssueを追加
def add_draft_issue_to_project(project_id):
draft_title = input("Enter the title for the new draft issue: ")
draft_body = input("Enter the body for the new draft issue: ")
mutation_add_draft_issue = """
mutation {
addProjectV2DraftIssue(input: {projectId: "PROJECT_ID", title: "TITLE", body: "BODY"}) {
projectItem {
id
}
}
}
"""
mutation_add_draft_issue = mutation_add_draft_issue.replace("PROJECT_ID", project_id)
mutation_add_draft_issue = mutation_add_draft_issue.replace("TITLE", draft_title)
mutation_add_draft_issue = mutation_add_draft_issue.replace("BODY", draft_body)
data_add_draft_issue = {
"query": mutation_add_draft_issue
}
response_add_draft_issue = requests.post("https://api.github.com/graphql", headers=headers, json=data_add_draft_issue)
if "errors" in response_add_draft_issue.json():
print(f"Error: {response_add_draft_issue.json()['errors'][0]['message']}")
else:
added_draft_issue_id = response_add_draft_issue.json()["data"]["addProjectV2DraftIssue"]["projectItem"]["id"]
print(colored(f"Added draft issue with ID: {added_draft_issue_id}", "green"))
add_draft_issue_to_project()
関数は、指定されたプロジェクトにドラフトIssueを追加します。
- ユーザーにドラフトIssueのタイトルと本文の入力を求めます。
- GraphQL ミューテーションを定義し、
PROJECT_ID
、TITLE
、BODY
をそれぞれプロジェクトID、ドラフトIssueのタイトル、ドラフトIssueの本文に置き換えます。 - ミューテーションを実行し、レスポンスをチェックします。エラーがある場合は、エラーメッセージを表示します。
- レスポンスから追加されたドラフトIssueのIDを取得し、表示します。
メイン処理
if __name__ == "__main__":
validate_environment_variables()
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
project_id = get_project_info()
get_project_items(project_id)
add_draft_issue_to_project(project_id)
メイン処理では、以下のステップを実行します。
- 環境変数を検証します。
- リクエストヘッダーを設定します。
- プロジェクト情報を取得します。
- プロジェクト内のアイテムを取得します。
- プロジェクトにドラフトIssueを追加します。
これで、GitHub プロジェクトにドラフトIssueを追加する Python スクリプトの説明は以上となります。このスクリプトを実行することで、GitHub の Project V2 API を使ってプロジェクトにドラフトIssueを簡単に追加することができます。
実行方法
-
必要な環境変数を設定します。
GITHUB_PERSONAL_ACCESS_TOKEN
: GitHub の Personal Access TokenGITHUB_USER_LOGIN
: GitHub のユーザーログイン名GITHUB_PROJECT_NUMBER
: 対象のプロジェクト番号
-
スクリプトを実行します。
python script_name.py
-
スクリプトが実行されると、以下のような出力が表示されます。
Project Title: My Project Project ID: PVT_kwDOABCD1234567890 --------------------------- Items: Item ID: ABC123_XXXXXXXXXXXX Title: Issue 1 Number: 1 Assignees: user1, user2 --- Item ID: DEF456_XXXXXXXXXXXX Title: Pull Request 1 Number: 2 Assignees: user3 --- Enter the title for the new draft issue: Draft Issue 1 Enter the body for the new draft issue: This is a draft issue. Added draft issue with ID: GHI789_XXXXXXXXXXXX
-
プロジェクトにドラフトIssueが追加されたことを確認します。
注意点
- このスクリプトを実行するには、適切な権限を持つ Personal Access Token が必要です。トークンには、
read:org
とproject
のスコープが必要です。 - プロジェクト番号は、プロジェクトの URL から取得できます。例えば、
https://github.com/orgs/my-org/projects/1
の場合、プロジェクト番号は1
になります。 - このスクリプトは、プロジェクト内の最初の 20 個のアイテムのみを取得します。より多くのアイテムを取得するには、
items(first: 20)
の数値を変更してください。
全体コード
import os
import requests
from termcolor import colored
from art import *
script_name = os.path.basename(__file__)
tprint(script_name)
token = os.environ.get("GITHUB_PERSONAL_ACCESS_TOKEN")
user_login = os.environ.get("GITHUB_USER_LOGIN")
project_number = os.environ.get("GITHUB_PROJECT_NUMBER")
def validate_environment_variables():
if token is None or user_login is None or project_number is None:
print("Error: Required environment variables are not set.")
exit(1)
def get_project_info():
query_project = """
query {
user(login: "USER_LOGIN") {
projectV2(number: NUMBER) {
title
id
}
}
}
"""
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)
if "errors" in response_project.json():
print(f"Error: {response_project.json()['errors'][0]['message']}")
exit(1)
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}", "cyan"))
return project_id
def get_project_items(project_id):
query_items = """
query {
node(id: "PROJECT_ID") {
... on ProjectV2 {
items(first: 20) {
nodes {
id
content {
... on DraftIssue {
title
body
}
... on Issue {
title
number
assignees(first: 10) {
nodes {
login
}
}
}
... on PullRequest {
title
number
assignees(first: 10) {
nodes {
login
}
}
}
}
}
}
}
}
}
"""
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)
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'][:6]}_XXXXXXXXXXXX", "cyan"))
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 "number" in content:
print(colored(f"Number: {content['number']}", "green"))
if "assignees" in content:
assignees = [assignee["login"] for assignee in content["assignees"]["nodes"]]
print(colored(f"Assignees: {', '.join(assignees)}", "green"))
print("---")
def add_draft_issue_to_project(project_id):
draft_title = input("Enter the title for the new draft issue: ")
draft_body = input("Enter the body for the new draft issue: ")
mutation_add_draft_issue = """
mutation {
addProjectV2DraftIssue(input: {projectId: "PROJECT_ID", title: "TITLE", body: "BODY"}) {
projectItem {
id
}
}
}
"""
mutation_add_draft_issue = mutation_add_draft_issue.replace("PROJECT_ID", project_id)
mutation_add_draft_issue = mutation_add_draft_issue.replace("TITLE", draft_title)
mutation_add_draft_issue = mutation_add_draft_issue.replace("BODY", draft_body)
data_add_draft_issue = {
"query": mutation_add_draft_issue
}
response_add_draft_issue = requests.post("https://api.github.com/graphql", headers=headers, json=data_add_draft_issue)
if "errors" in response_add_draft_issue.json():
print(f"Error: {response_add_draft_issue.json()['errors'][0]['message']}")
else:
added_draft_issue_id = response_add_draft_issue.json()["data"]["addProjectV2DraftIssue"]["projectItem"]["id"]
print(colored(f"Added draft issue with ID: {added_draft_issue_id}", "green"))
if __name__ == "__main__":
validate_environment_variables()
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
project_id = get_project_info()
get_project_items(project_id)
add_draft_issue_to_project(project_id)
まとめ
この記事では、GitHub の Project V2 API を使ってプロジェクトにドラフトIssueを追加する Python スクリプトを作成しました。このスクリプトを使えば、プロジェクトの管理がより簡単になります。
GitHub API には他にも多くの機能があるので、このスクリプトをベースにして、自分のニーズに合わせてカスタマイズしていくことをお勧めします。
Happy coding!
コメント