Skip to content

Instantly share code, notes, and snippets.

@tru
Created August 31, 2022 07:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tru/6684c4d0c1984b780423d708ff960bbf to your computer and use it in GitHub Desktop.
Save tru/6684c4d0c1984b780423d708ff960bbf to your computer and use it in GitHub Desktop.
import requests
from pprint import pprint
from typing import Optional, Dict, Union, Tuple
PROJECT_FIELDS = """
query($org: String!, $number: Int!) {
organization(login: $org) {
projectNext(number: $number) {
id
fields(first:20) {
nodes {
id
name
}
}
}
}
}
"""
ISSUE_ID = """
query($org: String!, $repo: String!, $number: Int!) {
organization(login: $org) {
repository(name: $repo) {
issue(number: $number) {
id
}
}
}
}
"""
SEARCH_ISSUES = """
query($searchQuery: String!) {
search(
query: $searchQuery
type: ISSUE
first: 100
) {
edges {
node {
... on Issue {
id
number
title
}
}
}
}
}
"""
ADD_ISSUE_TO_PROJECT = """
mutation AddToProject($project: ID!, $issue: ID!) {
addProjectNextItem(input: { projectId: $project, contentId: $issue }) {
projectNextItem {
id
}
}
}
"""
session = requests.session()
session.headers["Authorization"] = "Bearer TOKEN"
def graphql(query: str, variables: Dict[str, Union[int, str]]) -> Optional[dict]:
req = session.post("https://api.github.com/graphql", json={"query": query, "variables": variables})
req.raise_for_status()
jsondata = req.json()
if "errors" in jsondata:
print("Something went wrong:")
pprint(jsondata["errors"])
raise RuntimeError
if not "data" in jsondata:
print("No data in return - instead we got:")
pprint(jsondata)
raise RuntimeError
return jsondata
def project_id_and_fields(project_id: int) -> Tuple[str, Dict]:
data = graphql(PROJECT_FIELDS, {"org": "llvm", "number": project_id})
fields = {}
for node in data["data"]["organization"]["projectNext"]["fields"]["nodes"]:
fields[node["name"]] = node["id"]
return (data["data"]["organization"]["projectNext"]["id"], fields)
def issue_id(issue_id: int) -> str:
data = graphql(ISSUE_ID, {"org": "llvm", "repo": "llvm-project", "number": issue_id})
return data["data"]["organization"]["repository"]["issue"]["id"]
def search_issues(query: str) -> dict:
data = graphql(SEARCH_ISSUES, {"searchQuery": query})
issues = {}
for node in data["data"]["search"]["edges"]:
node = node["node"]
issues[node["id"]] = {"number": node["number"], "title": node["title"]}
return issues
def add_issue_to_project(project_id:str, issue_id:str) -> str:
data = graphql(ADD_ISSUE_TO_PROJECT, {"project": project_id, "issue": issue_id})
return data["data"]["addProjectNextItem"]["projectNextItem"]["id"]
if __name__ == '__main__':
project_id, fields = project_id_and_fields(3)
issues = search_issues("repo:llvm/llvm-project is:issue is:open no:project milestone:\"LLVM 15.0.0 Release\" ")
for issue_id, issue in issues.items():
print(f"Moving issue #{issue['number']} - {issue['title']}")
pprint(add_issue_to_project(project_id, issue_id))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment