🐍
Issueに紐づくGitHub Projectsの情報をGraphQL経由で取得する
小ネタです🍣
Issueに紐づくGitHub Projectsを情報を取得するスクリプトをChatGPTに教えてもらったので共有します
例えば、取得したいProjectに以下のようなCustom fieldsがあった場合、
以下のようなスクリプトで対象のIssueに紐づく内容が取得できます
fieldValueByName
の戻り値について、どのようなデータ型を選択すべきかについては、以下を確認してください
get_projects_by_issue_number.py
import csv
import json
import os
import sys
import requests
query = """
query($owner: String!, $repo: String!, $issueNumber: Int!) {
repository(owner: $owner, name: $repo) {
issue(number: $issueNumber) {
number
title
state
closedAt
projectItems(first: 10) {
totalCount
nodes {
project {
number
title
}
status: fieldValueByName(name: "Status") {
... on ProjectV2ItemFieldSingleSelectValue {
name
}
}
iteration: fieldValueByName(name: "Iteration") {
... on ProjectV2ItemFieldIterationValue {
title
startDate
duration
}
}
storyType: fieldValueByName(name: "Story Type") {
... on ProjectV2ItemFieldSingleSelectValue {
name
}
}
storyPoint: fieldValueByName(name: "Story Point") {
... on ProjectV2ItemFieldNumberValue {
number
}
}
from: fieldValueByName(name: "From") {
... on ProjectV2ItemFieldSingleSelectValue {
name
}
}
}
}
}
}
}
"""
writer = csv.writer(sys.stdout, delimiter='\t')
def fetch_issue(owner: str, repo: str, issue_number: int) -> None:
headers = {
"Authorization": f"Bearer {os.environ['GITHUB_TOKEN']}"
}
response = requests.post(
"https://api.github.com/graphql",
headers=headers,
json={
"query": query,
"variables": {
"owner": owner,
"repo": repo,
"issueNumber": issue_number,
}
}
)
response.raise_for_status()
if not response.json().get('data'):
raise Exception(json.dumps(response.json()))
else:
data = response.json()['data']
for project_item in data['repository']['issue']['projectItems']['nodes']:
writer.writerow([
owner,
repo,
issue_number,
data['repository']['issue']['title'],
data['repository']['issue']['state'],
data['repository']['issue']['closedAt'],
project_item['project']['number'],
project_item['project']['title'],
project_item['iteration']['title'] if project_item['iteration'] else None,
project_item['iteration']['startDate'] if project_item['iteration'] else None,
project_item['iteration']['duration'] if project_item['iteration'] else None,
project_item['storyType']['name'] if project_item['storyType'] else None,
project_item['storyPoint']['number'] if project_item['storyPoint'] else None,
project_item['from']['name'] if project_item['from'] else None,
])
owner = sys.argv[1]
repo = sys.argv[2]
issue_numbers = map(int, sys.argv[3].split(','))
writer.writerow([
'owner',
'repo',
'issue_number',
'title',
'state',
'closed_at',
'project_number',
'project_title',
'iteration',
'iteration_startDate',
'iteration_duration',
'story_type',
'story_point',
'from',
])
for issue_number in map(int, sys.argv[3].split(',')):
fetch_issue(owner=owner, repo=repo, issue_number=issue_number)
実行イメージは以下です
実行時に、 GITHUB_TOKEN
にPATを設定してください
$ python ./get_projects_by_issue_number owner repo "18101"
owner repo issue_number title state closed_at project_number project_title iteration iteration_startDate iteration_duration story_type story_point from
owner repo 18101 tflintの導入 OPEN 13 SR Agile Board Iteration 6 2023-03-24 14 🚸 Unplanned 1.0
そんだけ😌
もしも仕様が期待するものと違ったり、バグがあった場合はChatGPTになおしてもらってください
Discussion