7
7
from glom import glom
8
8
9
9
from openedx_webhooks .tasks import logger
10
- from openedx_webhooks .types import GhProject , PrDict , PrId
11
- from openedx_webhooks .utils import graphql_query
10
+ from openedx_webhooks .types import GhPrMetaDict , GhProject , PrDict , PrId
11
+ from openedx_webhooks .utils import graphql_query , memoize_timed , value_graphql_type
12
12
13
13
# The name of the query is used by FakeGitHub while testing.
14
14
22
22
pullRequest (number: $number) {
23
23
projectItems (first: 100) {
24
24
nodes {
25
+ id
25
26
project {
26
27
number
27
28
owner {
37
38
}
38
39
"""
39
40
41
+
40
42
def pull_request_projects (pr : PrDict ) -> Set [GhProject ]:
41
43
"""Return the projects this PR is in.
42
44
@@ -90,8 +92,9 @@ def pull_request_projects(pr: PrDict) -> Set[GhProject]:
90
92
}
91
93
"""
92
94
93
- def add_pull_request_to_project (prid : PrId , pr_node_id : str , project : GhProject ) -> None :
94
- """Add a pull request to a project.
95
+
96
+ def add_pull_request_to_project (prid : PrId , pr_node_id : str , project : GhProject ) -> str :
97
+ """Add a pull request to a project and returns its project item id.
95
98
96
99
The project is a tuple: (orgname, number)
97
100
"""
@@ -104,3 +107,95 @@ def add_pull_request_to_project(prid: PrId, pr_node_id: str, project: GhProject)
104
107
# Add the pull request.
105
108
variables = {"projectId" : proj_id , "prNodeId" : pr_node_id }
106
109
data = graphql_query (query = ADD_PROJECT_ITEM , variables = variables )
110
+ # data = {'addProjectV2ItemById': {'item': {'id': '<item_id>'}}}
111
+ return glom (data , "addProjectV2ItemById.item.id" )
112
+
113
+
114
+ ORG_PROJECT_METADATA = """\
115
+ query OrgProjectMetadata ($orgname: String!, $number: Int!) {
116
+ organization(login: $orgname) {
117
+ projectV2(number: $number) {
118
+ id
119
+ fields(first: 100) {
120
+ nodes {
121
+ ... on ProjectV2FieldCommon {
122
+ id
123
+ name
124
+ dataType
125
+ }
126
+ ... on ProjectV2SingleSelectField {
127
+ options {
128
+ id
129
+ name
130
+ }
131
+ }
132
+ }
133
+ }
134
+ }
135
+ }
136
+ }
137
+ """
138
+
139
+
140
+ @memoize_timed (minutes = 30 )
141
+ def get_project_metadata (project : GhProject ) -> GhPrMetaDict :
142
+ # Find the project metadata.
143
+ variables = {"orgname" : project [0 ], "number" : project [1 ]}
144
+ data : GhPrMetaDict = graphql_query (query = ORG_PROJECT_METADATA , variables = variables )
145
+ return glom (data , {"id" : "organization.projectV2.id" , "fields" : "organization.projectV2.fields.nodes" })
146
+
147
+
148
+ UPDATE_PROJECT_ITEM = """\
149
+ mutation UpdateProjectItem (
150
+ $projectId: ID!
151
+ $itemId: ID!
152
+ $fieldId: ID!
153
+ $value: {fieldType}
154
+ ) {{
155
+ updateProjectV2ItemFieldValue (
156
+ input: {{
157
+ projectId: $projectId,
158
+ itemId: $itemId,
159
+ fieldId: $fieldId,
160
+ value: {{
161
+ {fieldTypeName}: $value,
162
+ }}
163
+ }}) {{
164
+ projectV2Item {{
165
+ id
166
+ }}
167
+ }}
168
+ }}
169
+ """
170
+
171
+
172
+ def update_project_pr_custom_field (field_name : str , field_value , item_id : str , project : GhProject ) -> None :
173
+ """Add a pull request to a project.
174
+
175
+ The project is a tuple: (orgname, number)
176
+ """
177
+ logger .info (f"Updating project { project } field { field_name } to { field_value } " )
178
+
179
+ project_metadata = get_project_metadata (project )
180
+ target_field = None
181
+ for field in project_metadata ["fields" ]:
182
+ if field ["name" ] == field_name :
183
+ target_field = field
184
+ break
185
+ else :
186
+ logger .error (f"Could not find field with name: { field_name } in project: { project } " )
187
+ return
188
+
189
+ # Update field value
190
+ variables = {
191
+ "projectId" : project_metadata ["id" ],
192
+ "fieldId" : target_field ["id" ],
193
+ "itemId" : item_id ,
194
+ "value" : field_value ,
195
+ }
196
+ field_type_name = target_field ["dataType" ].lower ()
197
+ field_type = value_graphql_type (field_type_name )
198
+ graphql_query (
199
+ query = UPDATE_PROJECT_ITEM .format (fieldType = field_type , fieldTypeName = field_type_name ),
200
+ variables = variables
201
+ )
0 commit comments