-
Notifications
You must be signed in to change notification settings - Fork 119
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ci: Implement workflow for full suite IT (cron + manual) (#1353)
- Loading branch information
1 parent
8f49608
commit 44800ce
Showing
14 changed files
with
512 additions
and
8 deletions.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
name: Full Suite Integration Tests | ||
|
||
on: | ||
schedule: | ||
- cron: '0 0 * * 1-5' # At 00:00 on every day-of-week from Monday through Friday | ||
workflow_dispatch: # or manually | ||
|
||
jobs: | ||
run-it-full-suite: | ||
if: github.ref == 'refs/heads/master' # for now we want this workflow to run only on master, to be removed once support for different branches is implemented | ||
runs-on: ubuntu-latest | ||
outputs: | ||
build-scan-url: ${{ steps.run-it.outputs.build-scan-url }} | ||
it-status: ${{ steps.status.outputs.it-status }} | ||
steps: | ||
- name: Cancel Previous Runs | ||
uses: styfle/[email protected] | ||
with: | ||
access_token: '${{ secrets.GITHUB_TOKEN }}' | ||
|
||
- name: Checkout code | ||
uses: actions/checkout@v2 | ||
with: | ||
submodules: true | ||
|
||
- name: Download flankScripts and add it to PATH | ||
run: | | ||
./gradlew :flank-scripts:download | ||
echo "./flank-scripts/bash" >> $GITHUB_PATH | ||
- uses: actions/cache@v2 | ||
with: | ||
path: ~/.gradle/caches | ||
key: ubuntu-gradle-${{ hashFiles('**/*.gradle*') }} | ||
restore-keys: | | ||
ubuntu-gradle- | ||
- name: Gradle clean build | ||
uses: eskatos/gradle-command-action@v1 | ||
id: build | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
HEAD_REF: ${{ github.ref }} | ||
with: | ||
arguments: "clean assemble" | ||
|
||
- name: Gradle integration tests | ||
uses: eskatos/gradle-command-action@v1 | ||
id: run-it | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
HEAD_REF: ${{ github.ref }} | ||
with: | ||
arguments: "integrationTests" | ||
|
||
- name: Process IT results | ||
run: | | ||
flankScripts integration processResults \ | ||
--result ${{ job.status }} \ | ||
--url ${{ steps.run-it.outputs.build-scan-url }} \ | ||
--github-token ${{ secrets.GITHUB_TOKEN }} \ | ||
--run-id ${{ github.run_id }} |
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
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
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
30 changes: 30 additions & 0 deletions
30
flank-scripts/src/main/kotlin/flank/scripts/integration/CommitList.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,30 @@ | ||
package flank.scripts.integration | ||
|
||
import com.github.kittinunf.result.getOrElse | ||
import com.github.kittinunf.result.onError | ||
import flank.scripts.github.getGitHubCommitList | ||
import flank.scripts.github.getPrDetailsByCommit | ||
import flank.scripts.github.objects.GithubPullRequest | ||
import kotlinx.coroutines.async | ||
import kotlinx.coroutines.awaitAll | ||
import kotlinx.coroutines.coroutineScope | ||
|
||
suspend fun getCommitListSinceDate( | ||
token: String, | ||
since: String | ||
): List<Pair<String, GithubPullRequest?>> = coroutineScope { | ||
getGitHubCommitList(token, listOf("since" to since)) | ||
.onError { println(it.message) } | ||
.getOrElse { emptyList() } | ||
.map { | ||
async { | ||
it.sha to getPrDetailsByCommit(it.sha, token).getOrElse { emptyList() } | ||
} | ||
} | ||
.awaitAll() | ||
.flatMap { (commit, prs) -> | ||
if (prs.isEmpty()) listOf(commit to null) | ||
else prs.map { commit to it } | ||
} | ||
.toList() | ||
} |
72 changes: 72 additions & 0 deletions
72
flank-scripts/src/main/kotlin/flank/scripts/integration/Extensions.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,72 @@ | ||
package flank.scripts.integration | ||
|
||
import com.github.kittinunf.result.onError | ||
import flank.scripts.github.objects.GitHubCreateIssueCommentRequest | ||
import flank.scripts.github.objects.GitHubCreateIssueRequest | ||
import flank.scripts.github.objects.GitHubCreateIssueResponse | ||
import flank.scripts.github.objects.GitHubUpdateIssueRequest | ||
import flank.scripts.github.objects.IssueState | ||
import flank.scripts.github.patchIssue | ||
import flank.scripts.github.postNewIssue | ||
import flank.scripts.github.postNewIssueComment | ||
import flank.scripts.utils.toJson | ||
import kotlinx.coroutines.coroutineScope | ||
import kotlin.system.exitProcess | ||
|
||
internal suspend fun IntegrationContext.createNewIssue(): GitHubCreateIssueCommentRequest = | ||
createAndPostNewIssue().postComment() | ||
|
||
internal suspend fun IntegrationContext.postComment(): GitHubCreateIssueCommentRequest = | ||
createCommentPayload().also { payload -> | ||
postNewIssueComment(token, issueNumber, payload) | ||
println("** Comment posted") | ||
println(payload.toJson()) | ||
} | ||
|
||
internal suspend fun IntegrationContext.closeIssue(): ByteArray = | ||
postComment().run { | ||
println("** Closing issue") | ||
patchIssue(token, issueNumber, GitHubUpdateIssueRequest(state = IssueState.CLOSED)).get() | ||
} | ||
|
||
private suspend fun IntegrationContext.createAndPostNewIssue(payload: GitHubCreateIssueRequest = createIssuePayload()) = | ||
postNewIssue(token, payload) | ||
.onError { | ||
println(it.message) | ||
exitProcess(-1) | ||
} | ||
.get() | ||
.run { | ||
logIssueCreated(this) | ||
copy(openedIssue = number) | ||
} | ||
|
||
private fun createIssuePayload(): GitHubCreateIssueRequest { | ||
println("** Creating new issue") | ||
val issuePayload = GitHubCreateIssueRequest( | ||
title = "Full Suite integration tests failed on master", | ||
body = "### Integration Test failed on master", | ||
labels = listOf("IT_Failed", "bug") | ||
) | ||
println(issuePayload.toJson()) | ||
return issuePayload | ||
} | ||
|
||
private suspend fun IntegrationContext.createCommentPayload() = coroutineScope { | ||
val message = when (result) { | ||
ITResults.SUCCESS -> prepareSuccessMessage(lastRun, runID, url) | ||
ITResults.FAILURE -> { | ||
val commitList = getCommitListSinceDate(token, lastRun) | ||
prepareFailureMessage(lastRun, runID, url, commitList) | ||
} | ||
} | ||
GitHubCreateIssueCommentRequest(message) | ||
} | ||
|
||
private fun logIssueCreated(issue: GitHubCreateIssueResponse) = println( | ||
""" | ||
** Issue created: | ||
url: ${issue.htmlUrl} | ||
number: ${issue.number} | ||
""".trimIndent() | ||
) |
14 changes: 14 additions & 0 deletions
14
flank-scripts/src/main/kotlin/flank/scripts/integration/IntegrationCommand.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.integration | ||
|
||
import com.github.ajalt.clikt.core.CliktCommand | ||
import com.github.ajalt.clikt.core.subcommands | ||
|
||
object IntegrationCommand : CliktCommand(name = "integration") { | ||
|
||
init { | ||
subcommands(ProcessResultCommand) | ||
} | ||
|
||
@Suppress("EmptyFunctionBlock") | ||
override fun run() {} | ||
} |
13 changes: 13 additions & 0 deletions
13
flank-scripts/src/main/kotlin/flank/scripts/integration/IntegrationContext.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.integration | ||
|
||
data class IntegrationContext( | ||
val result: ITResults, | ||
val token: String, | ||
val url: String, | ||
val runID: String, | ||
val lastRun: String, | ||
private val openedIssue: Int?, | ||
) { | ||
val issueNumber: Int | ||
get() = requireNotNull(openedIssue) | ||
} |
21 changes: 21 additions & 0 deletions
21
flank-scripts/src/main/kotlin/flank/scripts/integration/IssueList.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,21 @@ | ||
package flank.scripts.integration | ||
|
||
import com.github.kittinunf.result.getOrElse | ||
import com.github.kittinunf.result.onError | ||
import flank.scripts.github.getGitHubIssueList | ||
|
||
suspend fun checkForOpenedITIssues(token: String): Int? = getGitHubIssueList( | ||
githubToken = token, | ||
parameters = listOf( | ||
"creator" to "github-actions[bot]", | ||
"state" to "open", | ||
"labels" to "IT_Failed" | ||
) | ||
) | ||
.onError { println(it.message) } | ||
.getOrElse { emptyList() } | ||
.firstOrNull() | ||
.also { | ||
if (it != null) println("** Issue found: ${it.htmlUrl}") | ||
else println("** No opened issue") | ||
}?.number |
54 changes: 54 additions & 0 deletions
54
flank-scripts/src/main/kotlin/flank/scripts/integration/PrepareMessage.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,54 @@ | ||
package flank.scripts.integration | ||
|
||
import flank.scripts.github.objects.GithubPullRequest | ||
import java.time.Instant | ||
import java.time.LocalDateTime | ||
import java.time.ZoneOffset | ||
import java.time.format.DateTimeFormatter | ||
|
||
fun prepareSuccessMessage( | ||
lastRun: String, | ||
runId: String, | ||
url: String | ||
): String = successTemplate(lastRun, runId, url) | ||
|
||
fun prepareFailureMessage( | ||
lastRun: String, | ||
runId: String, | ||
url: String, | ||
prs: List<Pair<String, GithubPullRequest?>> | ||
): String = buildString { | ||
appendLine(failureTemplate(lastRun, runId, url)) | ||
if (prs.isEmpty()) appendLine("No new commits") | ||
else { | ||
appendLine("|commit SHA|PR|") | ||
appendLine("|---|:---:|") | ||
prs.forEach { (commit, pr) -> | ||
appendLine("|$commit|${pr?.let { "[${it.title}](${it.htmlUrl})" } ?: "---"}") | ||
} | ||
} | ||
} | ||
|
||
private val successTemplate = { lastRun: String, runId: String, url: String -> | ||
""" | ||
|### Full suite IT run :white_check_mark: SUCCEEDED :white_check_mark: | ||
|**Timestamp:** ${makeHumanFriendly(lastRun)} | ||
|**Job run:** [$runId](https://github.com/Flank/flank/actions/runs/$runId | ||
|**Build scan URL:** $url | ||
|**Closing issue** | ||
""".trimMargin() | ||
} | ||
|
||
private val failureTemplate = { lastRun: String, runId: String, url: String -> | ||
""" | ||
|### Full suite IT run :x: FAILED :x: | ||
|**Timestamp:** ${makeHumanFriendly(lastRun)} | ||
|**Job run:** [$runId](https://github.com/Flank/flank/actions/runs/$runId | ||
|**Build scan URL:** $url | ||
""".trimMargin() | ||
} | ||
|
||
private fun makeHumanFriendly(date: String) = | ||
LocalDateTime | ||
.ofInstant(Instant.from(DateTimeFormatter.ISO_INSTANT.parse(date)), ZoneOffset.UTC) | ||
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) |
60 changes: 60 additions & 0 deletions
60
flank-scripts/src/main/kotlin/flank/scripts/integration/ProcessResultCommand.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 @@ | ||
@file:Suppress("EXPERIMENTAL_API_USAGE") | ||
|
||
package flank.scripts.integration | ||
|
||
import com.github.ajalt.clikt.core.CliktCommand | ||
import com.github.ajalt.clikt.parameters.options.option | ||
import com.github.ajalt.clikt.parameters.options.required | ||
import com.github.ajalt.clikt.parameters.types.enum | ||
import kotlinx.coroutines.runBlocking | ||
|
||
object ProcessResultCommand : CliktCommand(name = "processResults") { | ||
|
||
private val itResult by option(help = "IT run job status", names = arrayOf("--result")) | ||
.enum<ITResults>(ignoreCase = true) | ||
.required() | ||
|
||
private val buildScanURL by option(help = "Gradle build scan URL", names = arrayOf("--url")) | ||
.required() | ||
|
||
private val githubToken by option(help = "Git Token").required() | ||
private val runID by option(help = "Workflow job ID").required() | ||
private val openedIssue by lazy { runBlocking { checkForOpenedITIssues(githubToken) } } | ||
private val lastRun by lazy { runBlocking { getLastITWorkflowRunDate(githubToken) } } | ||
|
||
override fun run() { | ||
runBlocking { | ||
logArgs() | ||
with(makeContext()) { | ||
when { | ||
itResult == ITResults.FAILURE && openedIssue == null -> createNewIssue() | ||
itResult == ITResults.FAILURE && openedIssue != null -> postComment() | ||
itResult == ITResults.SUCCESS && openedIssue != null -> closeIssue() | ||
else -> return@runBlocking | ||
} | ||
} | ||
} | ||
} | ||
|
||
private fun makeContext() = IntegrationContext( | ||
result = itResult, | ||
token = githubToken, | ||
url = buildScanURL, | ||
runID = runID, | ||
lastRun = lastRun, | ||
openedIssue = openedIssue | ||
) | ||
|
||
private fun logArgs() = println( | ||
""" | ||
** Parameters: | ||
result: $itResult | ||
url: $buildScanURL | ||
runID: $runID | ||
""".trimIndent() | ||
) | ||
} | ||
|
||
enum class ITResults { | ||
SUCCESS, FAILURE | ||
} |
Oops, something went wrong.