-
Notifications
You must be signed in to change notification settings - Fork 118
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ci: Copy properties from issue to pull request
- Loading branch information
Piotr Adamczyk
committed
Nov 10, 2020
1 parent
68d52d8
commit fe8d175
Showing
10 changed files
with
315 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
41 changes: 41 additions & 0 deletions
41
flank-scripts/src/main/kotlin/flank/scripts/github/GithubPullRequest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package flank.scripts.github | ||
|
||
import com.github.kittinunf.fuel.core.ResponseDeserializable | ||
import flank.scripts.utils.toObject | ||
import kotlinx.serialization.SerialName | ||
import kotlinx.serialization.Serializable | ||
|
||
@Serializable | ||
data class GithubPullRequest( | ||
@SerialName("html_url") val htmlUrl: String, | ||
val title: String, | ||
val number: Int, | ||
val assignees: List<GithubUser>, | ||
val labels: List<GitHubLabel> = emptyList(), | ||
val body: String = "", | ||
val head: GitHubHead? | ||
) | ||
|
||
@Serializable | ||
data class GithubUser( | ||
val login: String, | ||
@SerialName("html_url") val htmlUrl: String | ||
) | ||
|
||
object GithubPullRequestDeserializer : ResponseDeserializable<List<GithubPullRequest>> { | ||
override fun deserialize(content: String): List<GithubPullRequest> = content.toObject() | ||
} | ||
|
||
@Serializable | ||
data class GitHubLabel( | ||
val name: String | ||
) | ||
|
||
object GitHubLabelDeserializable : ResponseDeserializable<List<GitHubLabel>> { | ||
override fun deserialize(content: String): List<GitHubLabel> = content.toObject() | ||
} | ||
|
||
@Serializable | ||
data class GitHubHead( | ||
val ref: String | ||
) |
14 changes: 14 additions & 0 deletions
14
flank-scripts/src/main/kotlin/flank/scripts/pullrequest/FindReferenceIssue.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package flank.scripts.pullrequest | ||
|
||
fun GitHubPullRequest.findReferenceNumber() = | ||
(tryGetReferenceNumberFromBody() ?: tryGetReferenceNumberFromBranch()) | ||
?.trim() | ||
?.replace("#", "") | ||
?.toInt() | ||
|
||
private fun GitHubPullRequest.tryGetReferenceNumberFromBody() = bodyReferenceRegex.find(body)?.value | ||
|
||
private fun GitHubPullRequest.tryGetReferenceNumberFromBranch() = branchReferenceRegex.find(head?.ref.orEmpty())?.value | ||
|
||
private val bodyReferenceRegex = "#\\d+\\s".toRegex() | ||
private val branchReferenceRegex = "#\\d+".toRegex() |
60 changes: 60 additions & 0 deletions
60
flank-scripts/src/main/kotlin/flank/scripts/pullrequest/GitHubIssuePropertiesCopy.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package flank.scripts.pullrequest | ||
|
||
import com.github.ajalt.clikt.core.CliktCommand | ||
import com.github.ajalt.clikt.parameters.options.default | ||
import com.github.ajalt.clikt.parameters.options.option | ||
import com.github.ajalt.clikt.parameters.options.required | ||
import com.github.ajalt.clikt.parameters.types.int | ||
import com.github.kittinunf.result.onError | ||
import com.github.kittinunf.result.success | ||
import flank.scripts.testartifacts.core.GITHUB_TOKEN_ENV_KEY | ||
import flank.scripts.utils.getEnv | ||
import kotlinx.coroutines.Dispatchers | ||
import kotlinx.coroutines.coroutineScope | ||
import kotlinx.coroutines.joinAll | ||
import kotlinx.coroutines.launch | ||
import kotlinx.coroutines.runBlocking | ||
|
||
object CopyProperties : | ||
CliktCommand(name = "copyProperties", help = "Copy properties from referanced issue to pull request") { | ||
|
||
private val githubToken by option(help = "Git Token").default(getEnv(GITHUB_TOKEN_ENV_KEY)) | ||
private val zenhubToken by option(help = "ZenHub api Token").required() | ||
private val prNumber by option(help = "Pull request number").int().required() | ||
|
||
override fun run() { | ||
runBlocking { | ||
getGitHubPullRequest(githubToken, prNumber) | ||
.onError { | ||
println("Could not copy properties, because of ${it.message}") | ||
} | ||
.success { pullRequest -> | ||
val issueNumber = pullRequest.findReferenceNumber() | ||
checkNotNull(issueNumber) { "Reference issue not found on description and branch" } | ||
println("Found referenced issue #$issueNumber") | ||
launch(Dispatchers.IO) { pullRequest.copyGitHubProperties(githubToken, issueNumber, prNumber) } | ||
launch(Dispatchers.IO) { copyZenhubProperties(zenhubToken, issueNumber, prNumber) } | ||
} | ||
} | ||
} | ||
} | ||
|
||
private suspend fun GitHubPullRequest.copyGitHubProperties( | ||
githubToken: String, | ||
baseIssueNumber: Int, | ||
prNumber: Int | ||
) = coroutineScope { | ||
val assignees = this@copyGitHubProperties.assignees.map { it.login } | ||
listOf( | ||
launch { setAssigneesToPullRequest(githubToken, prNumber, assignees) }, | ||
launch { copyLabels(githubToken, baseIssueNumber, prNumber) }, | ||
).joinAll() | ||
} | ||
|
||
private suspend fun copyZenhubProperties( | ||
zenhubToken: String, | ||
baseIssueNumber: Int, | ||
prNumber: Int | ||
) { | ||
copyEstimations(zenhubToken, baseIssueNumber, prNumber) | ||
} |
13 changes: 13 additions & 0 deletions
13
flank-scripts/src/main/kotlin/flank/scripts/pullrequest/GitHubPullRequestGetter.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package flank.scripts.pullrequest | ||
|
||
import com.github.kittinunf.fuel.Fuel | ||
import com.github.kittinunf.fuel.coroutines.awaitResult | ||
import flank.scripts.exceptions.mapClientError | ||
import flank.scripts.exceptions.toGithubException | ||
|
||
suspend fun getGitHubPullRequest(githubToken: String, issueNumber: Int) = | ||
Fuel.get("https://api.github.com/repos/Flank/flank/pulls/$issueNumber") | ||
.appendHeader("Accept", "application/vnd.github.v3+json") | ||
.appendHeader("Authorization", "token $githubToken") | ||
.awaitResult(GitHubPullRequestDeserializable) | ||
.mapClientError { it.toGithubException() } |
36 changes: 36 additions & 0 deletions
36
flank-scripts/src/main/kotlin/flank/scripts/pullrequest/GithubIssue.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package flank.scripts.pullrequest | ||
|
||
import com.github.kittinunf.fuel.core.ResponseDeserializable | ||
import flank.scripts.utils.toObject | ||
import kotlinx.serialization.Serializable | ||
|
||
@Serializable | ||
data class GitHubPullRequest( | ||
val assignees: List<GitHubUser> = emptyList(), | ||
val labels: List<GitHubLabel> = emptyList(), | ||
val body: String = "", | ||
val head: GitHubHead? | ||
) | ||
|
||
object GitHubPullRequestDeserializable : ResponseDeserializable<GitHubPullRequest> { | ||
override fun deserialize(content: String): GitHubPullRequest = content.toObject() | ||
} | ||
|
||
@Serializable | ||
data class GitHubLabel( | ||
val name: String | ||
) | ||
|
||
object GitHubLabelDeserializable : ResponseDeserializable<List<GitHubLabel>> { | ||
override fun deserialize(content: String): List<GitHubLabel> = content.toObject() | ||
} | ||
|
||
@Serializable | ||
data class GitHubUser( | ||
val login: String | ||
) | ||
|
||
@Serializable | ||
data class GitHubHead( | ||
val ref: String | ||
) |
26 changes: 26 additions & 0 deletions
26
flank-scripts/src/main/kotlin/flank/scripts/pullrequest/SetAssignees.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package flank.scripts.pullrequest | ||
|
||
import com.github.kittinunf.fuel.Fuel | ||
import com.github.kittinunf.fuel.coroutines.awaitStringResult | ||
import com.github.kittinunf.result.onError | ||
import com.github.kittinunf.result.success | ||
import flank.scripts.utils.toJson | ||
import kotlinx.serialization.Serializable | ||
|
||
suspend fun setAssigneesToPullRequest(githubToken: String, pullRequestNumber: Int, assignees: List<String>) { | ||
Fuel.post("https://api.github.com/repos/Flank/flank/issues/$pullRequestNumber/assignees") | ||
.appendHeader("Accept", "application/vnd.github.v3+json") | ||
.appendHeader("Authorization", "token $githubToken") | ||
.body(SetAssigneesRequest(assignees).toJson()) | ||
.awaitStringResult() | ||
.onError { | ||
println("Could not set assignees because of ${it.message}") | ||
it.printStackTrace() | ||
} | ||
.success { println("$assignees set to pull request #$pullRequestNumber") } | ||
} | ||
|
||
@Serializable | ||
private data class SetAssigneesRequest( | ||
val assignees: List<String> | ||
) |
44 changes: 44 additions & 0 deletions
44
flank-scripts/src/main/kotlin/flank/scripts/pullrequest/SetLabels.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package flank.scripts.pullrequest | ||
|
||
import com.github.kittinunf.fuel.Fuel | ||
import com.github.kittinunf.fuel.coroutines.awaitResult | ||
import com.github.kittinunf.fuel.coroutines.awaitStringResult | ||
import com.github.kittinunf.result.map | ||
import com.github.kittinunf.result.onError | ||
import com.github.kittinunf.result.success | ||
import flank.scripts.exceptions.mapClientError | ||
import flank.scripts.exceptions.toGithubException | ||
import flank.scripts.utils.toJson | ||
import kotlinx.serialization.Serializable | ||
|
||
suspend fun copyLabels(githubToken: String, issueNumber: Int, pullRequestNumber: Int) { | ||
getLabelsFromIssue(githubToken, issueNumber) | ||
.onError { println("Could not copy labels because of ${it.message}") } | ||
.map { it.map { label -> label.name } } | ||
.get() | ||
.run { | ||
setLabelsToPullRequest(githubToken, pullRequestNumber, this) | ||
} | ||
} | ||
|
||
private suspend fun getLabelsFromIssue(githubToken: String, issueNumber: Int) = | ||
Fuel.get("https://api.github.com/repos/Flank/flank/issues/$issueNumber/labels") | ||
.appendHeader("Accept", "application/vnd.github.v3+json") | ||
.appendHeader("Authorization", "token $githubToken") | ||
.awaitResult(GitHubLabelDeserializable) | ||
.mapClientError { it.toGithubException() } | ||
|
||
private suspend fun setLabelsToPullRequest(githubToken: String, pullRequestNumber: Int, labels: List<String>) { | ||
Fuel.post("https://api.github.com/repos/Flank/flank/issues/$pullRequestNumber/labels") | ||
.appendHeader("Accept", "application/vnd.github.v3+json") | ||
.appendHeader("Authorization", "token $githubToken") | ||
.body(SetLabelsRequest(labels).toJson()) | ||
.awaitStringResult() | ||
.onError { println("Could not set assignees because of ${it.message}") } | ||
.success { println("$labels set to pull request #$pullRequestNumber") } | ||
} | ||
|
||
@Serializable | ||
private data class SetLabelsRequest( | ||
val labels: List<String> | ||
) |
44 changes: 44 additions & 0 deletions
44
flank-scripts/src/main/kotlin/flank/scripts/pullrequest/ZenHubCopyEstimations.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package flank.scripts.pullrequest | ||
|
||
import com.github.kittinunf.fuel.Fuel | ||
import com.github.kittinunf.fuel.core.Request | ||
import com.github.kittinunf.fuel.coroutines.awaitResult | ||
import com.github.kittinunf.fuel.coroutines.awaitStringResult | ||
import com.github.kittinunf.result.onError | ||
import com.github.kittinunf.result.success | ||
import flank.scripts.utils.toJson | ||
import kotlinx.serialization.Serializable | ||
|
||
private const val FLANK_REPO_ID = 84221974 | ||
private const val ZENHUB_BASE_URL = "https://api.zenhub.com/p1/repositories/$FLANK_REPO_ID" | ||
|
||
suspend fun copyEstimations(zenhubToken: String, issueNumber: Int, pullRequestNumber: Int) { | ||
getEstimation(zenhubToken, issueNumber) | ||
.run { setEstimation(zenhubToken, pullRequestNumber, estimate.value) } | ||
} | ||
|
||
suspend fun getEstimation(zenhubToken: String, issueNumber: Int) = | ||
Fuel.get("$ZENHUB_BASE_URL/issues/$issueNumber") | ||
.withZenhubHeaders(zenhubToken) | ||
.awaitResult(ZenHubIssueDeserializable) | ||
.onError { println("Could not get estimations because of ${it.message}") } | ||
.get() | ||
|
||
private suspend fun setEstimation(zenhubToken: String, pullRequestNumber: Int, estimate: Int) { | ||
Fuel.put("$ZENHUB_BASE_URL/issues/$pullRequestNumber/estimate") | ||
.withZenhubHeaders(zenhubToken) | ||
.body(ZenHubEstimateRequest(estimate).toJson()) | ||
.awaitStringResult() | ||
.onError { | ||
it.printStackTrace() | ||
println("Could not set estimations because of ${it.message}") | ||
} | ||
.success { println("Estimate $estimate set to pull request #$pullRequestNumber") } | ||
} | ||
|
||
private fun Request.withZenhubHeaders(zenhubToken: String) = | ||
appendHeader("Content-Type", "application/json") | ||
.appendHeader("X-Authentication-Token", zenhubToken) | ||
|
||
@Serializable | ||
private data class ZenHubEstimateRequest(val estimate: Int) |
19 changes: 19 additions & 0 deletions
19
flank-scripts/src/main/kotlin/flank/scripts/pullrequest/ZenHubIssue.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package flank.scripts.pullrequest | ||
|
||
import com.github.kittinunf.fuel.core.ResponseDeserializable | ||
import flank.scripts.utils.toObject | ||
import kotlinx.serialization.Serializable | ||
|
||
@Serializable | ||
data class ZenHubIssue( | ||
val estimate: ZenHubEstimate | ||
) | ||
|
||
@Serializable | ||
data class ZenHubEstimate( | ||
val value: Int | ||
) | ||
|
||
object ZenHubIssueDeserializable : ResponseDeserializable<ZenHubIssue> { | ||
override fun deserialize(content: String): ZenHubIssue = content.toObject() | ||
} |