Skip to content

Commit 56434ca

Browse files
Issue #21977 - Migrate create-release to ziro-cli (PR #40)
* Add ability to update pull request base branch * Spotless * Add regular id to GetLinkedPullRequests query * Split queries * Add option to only include issue ids of pull requests when fetching release by id * Return GH node ID if pull request * Add better error handling * Add return types * Only return release with open pull requests * Tweak addIssuesToRelease to return release * Do same tweak for removeIssuesFromRelease
1 parent 84ed0c9 commit 56434ca

5 files changed

Lines changed: 114 additions & 38 deletions

File tree

src/main/graphql/zenhub/queries/GetLinkedPullRequests.graphql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ query GetLinkedPullRequests($ids: [ID!]!) {
22
nodes(ids: $ids) {
33
... on Issue {
44
ghNodeId
5+
id
56
}
67
}
78
}

src/main/graphql/zenhub/queries/GetRelease.graphql

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ query GetRelease($releaseId: ID!, $endCursor: String) {
99
issues(first: 100, after: $endCursor) {
1010
nodes {
1111
id
12+
ghNodeId
13+
pullRequest
14+
pullRequestObject {
15+
state
16+
}
1217
}
1318
pageInfo {
1419
hasNextPage
@@ -17,4 +22,4 @@ query GetRelease($releaseId: ID!, $endCursor: String) {
1722
}
1823
}
1924
}
20-
}
25+
}

src/main/kotlin/github/GitHubClient.kt

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package github
33
import com.apollographql.apollo3.ApolloClient
44
import com.apollographql.apollo3.api.Optional
55
import com.ziro.engineering.github.graphql.sdk.*
6+
import com.ziro.engineering.github.graphql.sdk.fragment.PullRequestFragment
67
import com.ziro.engineering.github.graphql.sdk.type.CreatePullRequestInput
78
import com.ziro.engineering.github.graphql.sdk.type.PullRequestUpdateState
89
import com.ziro.engineering.github.graphql.sdk.type.UpdatePullRequestInput
@@ -101,7 +102,7 @@ class GitHubClient : AutoCloseable {
101102
currBranch: String,
102103
title: String,
103104
body: String?,
104-
) = runBlocking {
105+
): PullRequestFragment = runBlocking {
105106
val input =
106107
CreatePullRequestInput(
107108
clientMutationId = Optional.absent(),
@@ -163,16 +164,35 @@ class GitHubClient : AutoCloseable {
163164
?.pullRequestFragment
164165
}
165166

166-
fun updatePullRequest(id: String, body: String?, state: PullRequestUpdateState?) = runBlocking {
167+
fun updatePullRequest(
168+
id: String,
169+
baseBranch: String?,
170+
body: String?,
171+
state: PullRequestUpdateState?
172+
): PullRequestFragment = runBlocking {
167173
val input =
168174
UpdatePullRequestInput(
169175
pullRequestId = id,
176+
baseRefName = Optional.presentIfNotNull(baseBranch),
170177
body = Optional.presentIfNotNull(body),
171178
state = Optional.presentIfNotNull(state))
172179

173180
val mutation = UpdatePullRequestMutation(input)
174181
val response = apolloClient.mutation(mutation).execute()
175-
return@runBlocking response.data?.updatePullRequest?.pullRequest?.pullRequestFragment
182+
183+
if (response.hasErrors()) {
184+
val exception = Exception(response.errors?.joinToString { it.message })
185+
throw IllegalStateException(exception)
186+
}
187+
188+
val pullRequestFragment = response.data?.updatePullRequest?.pullRequest?.pullRequestFragment
189+
190+
if (pullRequestFragment == null) {
191+
val exception = Exception("Pull request fragment is null")
192+
throw IllegalStateException(exception)
193+
}
194+
195+
pullRequestFragment
176196
}
177197

178198
override fun close() {

src/main/kotlin/zenhub/ZenHubClient.kt

Lines changed: 83 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -229,17 +229,36 @@ class ZenHubClient(val zenhubWorkspaceId: String = DEFAULT_WORKSPACE_ID) : AutoC
229229
apolloClient.mutation(mutation).toFlow().single().data?.closeIssues
230230
}
231231

232-
fun getRelease(releaseId: String): Release? {
232+
fun getRelease(releaseId: String, pullRequestsOnly: Boolean): Release? {
233233
var queryResult: GetReleaseQuery.OnRelease?
234234
val releaseIssueIds = mutableSetOf<String>()
235235
var endCursor: String? = null
236236
var hasNextPage: Boolean
237237

238238
do {
239239
queryResult = getRelease(releaseId, endCursor)
240-
val pageIssues = queryResult?.issues?.nodes?.map { issue -> issue.id } ?: emptyList()
241-
releaseIssueIds.addAll(pageIssues)
242240

241+
val pageIssues =
242+
queryResult
243+
?.issues
244+
?.nodes
245+
?.filter { node ->
246+
!pullRequestsOnly ||
247+
(node.pullRequest &&
248+
node.pullRequestObject?.state?.equals(PullRequestState.OPEN) ==
249+
true)
250+
}
251+
?.map { node ->
252+
if (pullRequestsOnly) {
253+
requireNotNull(node.ghNodeId) {
254+
"ghNodeId is null for node id=${node.id}"
255+
}
256+
} else {
257+
node.id
258+
}
259+
} ?: emptyList()
260+
261+
releaseIssueIds.addAll(pageIssues)
243262
hasNextPage = queryResult?.issues?.pageInfo?.hasNextPage ?: false
244263
endCursor = queryResult?.issues?.pageInfo?.endCursor
245264
} while (hasNextPage)
@@ -290,45 +309,57 @@ class ZenHubClient(val zenhubWorkspaceId: String = DEFAULT_WORKSPACE_ID) : AutoC
290309

291310
for (release in releases) {
292311
if (release.title == title) {
293-
return@runBlocking getRelease(release.id)
312+
return@runBlocking getRelease(release.id, false)
294313
}
295314
}
296315

297316
throw IllegalArgumentException("Release with title $title not found")
298317
}
299318

300-
fun addIssuesToRelease(
301-
issueIds: Set<String>,
302-
releaseId: String
303-
): AddIssuesToReleasesMutation.Release? = runBlocking {
319+
fun addIssuesToRelease(issueIds: Set<String>, releaseId: String): Release = runBlocking {
304320
val input =
305321
AddIssuesToReleasesInput(Optional.absent(), issueIds.toList(), listOf(releaseId))
306322
val mutation = AddIssuesToReleasesMutation(input)
307-
apolloClient
308-
.mutation(mutation)
309-
.toFlow()
310-
.single()
311-
.data
312-
?.addIssuesToReleases
313-
?.releases
314-
?.get(0)
323+
val response = apolloClient.mutation(mutation).execute()
324+
325+
if (response.hasErrors()) {
326+
val exception = Exception(response.errors?.joinToString { it.message })
327+
throw IllegalStateException(exception)
328+
}
329+
330+
val releaseId =
331+
response.data?.addIssuesToReleases?.releases?.get(0)?.id
332+
?: throw IllegalStateException("Mutation response has null release ID")
333+
334+
val release =
335+
getRelease(releaseId, false)
336+
?: throw IllegalStateException(
337+
"Unable to retrieve release with ID $releaseId. This should never happen because the mutation was successful!")
338+
339+
release
315340
}
316341

317-
fun removeIssuesFromRelease(
318-
issueIds: Set<String>,
319-
releaseId: String
320-
): RemoveIssuesFromReleasesMutation.Release? = runBlocking {
342+
fun removeIssuesFromRelease(issueIds: Set<String>, releaseId: String): Release = runBlocking {
321343
val input =
322344
RemoveIssuesFromReleasesInput(Optional.absent(), issueIds.toList(), listOf(releaseId))
323345
val mutation = RemoveIssuesFromReleasesMutation(input)
324-
apolloClient
325-
.mutation(mutation)
326-
.toFlow()
327-
.single()
328-
.data
329-
?.removeIssuesFromReleases
330-
?.releases
331-
?.get(0)
346+
val response = apolloClient.mutation(mutation).execute()
347+
348+
if (response.hasErrors()) {
349+
val exception = Exception(response.errors?.joinToString { it.message })
350+
throw IllegalStateException(exception)
351+
}
352+
353+
val releaseId =
354+
response.data?.removeIssuesFromReleases?.releases?.get(0)?.id
355+
?: throw IllegalStateException("Mutation response has null release ID")
356+
357+
val release =
358+
getRelease(releaseId, false)
359+
?: throw IllegalStateException(
360+
"Unable to retrieve release with ID $releaseId. This should never happen because the mutation was successful!")
361+
362+
release
332363
}
333364

334365
fun getIssueEvents(githubRepoId: Int, issueNumber: Int): ArrayList<GetIssueEventsQuery.Node> {
@@ -595,7 +626,7 @@ class ZenHubClient(val zenhubWorkspaceId: String = DEFAULT_WORKSPACE_ID) : AutoC
595626
return@runBlocking null
596627
}
597628

598-
getRelease(issue.issueFragment.releases.nodes[0].id)
629+
getRelease(issue.issueFragment.releases.nodes[0].id, false)
599630
}
600631

601632
override fun close() {
@@ -682,11 +713,30 @@ class ZenHubClient(val zenhubWorkspaceId: String = DEFAULT_WORKSPACE_ID) : AutoC
682713
apolloClient.query(query).toFlow().single().data?.viewer?.githubUser
683714
}
684715

685-
fun getLinkedPullRequests(linkIds: Set<String>): List<String>? = runBlocking {
716+
fun getPullRequestGitHubIdsFromLinkIds(linkIds: Set<String>) = runBlocking {
686717
val query = GetLinkedPullRequestsQuery(linkIds.toList())
687-
apolloClient.query(query).toFlow().single().data?.nodes?.mapNotNull { node ->
688-
node?.onIssue?.ghNodeId
689-
}
718+
719+
apolloClient
720+
.query(query)
721+
.toFlow()
722+
.single()
723+
.data
724+
?.nodes
725+
?.mapNotNull { node -> node?.onIssue?.ghNodeId }
726+
?.toSet()
727+
}
728+
729+
fun getPullRequestZenHubIdsFromLinkIds(linkIds: Set<String>) = runBlocking {
730+
val query = GetLinkedPullRequestsQuery(linkIds.toList())
731+
732+
apolloClient
733+
.query(query)
734+
.toFlow()
735+
.single()
736+
.data
737+
?.nodes
738+
?.mapNotNull { node -> node?.onIssue?.id }
739+
?.toSet()
690740
}
691741

692742
fun createIssue(

version.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
8.3.0
1+
9.0.0

0 commit comments

Comments
 (0)