This repository has been archived by the owner on Nov 5, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 739
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add PR description CI check and improve the PR template * Add it to the ci_actions_test.yml * Run the check also on PR open * And reopened * Rename check * Implement Main.kt * Fix workflow * Add CI troubleshooting docs * WIP: Fix the workflow * Fix the workflow * Fix Detekt issues * Simplify the PR template * Expand the workflow trigger
- Loading branch information
1 parent
3c74588
commit 3bb0e2b
Showing
11 changed files
with
317 additions
and
10 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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
name: PR description check | ||
|
||
on: | ||
pull_request: | ||
|
||
jobs: | ||
pr-description-check: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout GIT | ||
uses: actions/checkout@v4 | ||
|
||
- name: Setup Java | ||
uses: actions/setup-java@v4 | ||
with: | ||
distribution: 'adopt' | ||
java-version: '18' | ||
|
||
- name: Enable Gradle Wrapper caching (optimization) | ||
uses: actions/cache@v4 | ||
with: | ||
path: | | ||
~/.gradle/caches | ||
~/.gradle/wrapper | ||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} | ||
restore-keys: | | ||
${{ runner.os }}-gradle- | ||
- name: Extract PR description (base 64) | ||
id: extract_description | ||
run: echo "PR_DESCRIPTION=$(jq -r '.pull_request.body' $GITHUB_EVENT_PATH | base64 | tr -d '\n')" >> $GITHUB_ENV | ||
|
||
- name: Run PR Description Check | ||
run: ./gradlew :ci-actions:pr-description-check:run --args="${{ env.PR_DESCRIPTION }}" |
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,12 @@ | ||
plugins { | ||
id("ivy.script") | ||
application | ||
} | ||
|
||
application { | ||
mainClass = "ivy.automate.pr.MainKt" | ||
} | ||
|
||
dependencies { | ||
implementation(projects.ciActions.base) | ||
} |
29 changes: 29 additions & 0 deletions
29
ci-actions/pr-description-check/src/main/kotlin/ivy/automate/pr/ClosesIssueAnalyzer.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,29 @@ | ||
package ivy.automate.pr | ||
|
||
import arrow.core.Either | ||
|
||
class ClosesIssueAnalyzer : PRDescriptionAnalyzer { | ||
override fun analyze(prDescription: String): Either<String, Unit> { | ||
val cleanedDescription = prDescription.removeMarkdownComments() | ||
|
||
// Regex pattern to find "Closes #NUMBER" or "Closes N/A" | ||
val closesPattern = Regex("""(?i)closes\s+#\d+|closes\s+n/a""") | ||
if (closesPattern.containsMatchIn(cleanedDescription)) { | ||
return Either.Right(Unit) | ||
} | ||
|
||
return Either.Left(MissingClosesProblem) | ||
} | ||
|
||
private fun String.removeMarkdownComments(): String = | ||
replace(Regex("<!--.*?-->", RegexOption.DOT_MATCHES_ALL), "").trim() | ||
|
||
companion object { | ||
val MissingClosesProblem = buildString { | ||
append("[PROBLEM] Missing Closes GitHub Issue section\n") | ||
append("This PR does not close any GitHub issues. ") | ||
append("Add \"Closes #123\" where 123 is the issue number ") | ||
append("or \"Closes N/A\" if doesn't close any issue.") | ||
} | ||
} | ||
} |
42 changes: 42 additions & 0 deletions
42
ci-actions/pr-description-check/src/main/kotlin/ivy/automate/pr/Main.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,42 @@ | ||
package ivy.automate.pr | ||
|
||
import arrow.core.raise.catch | ||
import kotlinx.coroutines.runBlocking | ||
import kotlin.io.encoding.Base64 | ||
import kotlin.io.encoding.ExperimentalEncodingApi | ||
|
||
@OptIn(ExperimentalEncodingApi::class) | ||
fun main(args: Array<String>): Unit = runBlocking { | ||
require(args.size == 1) { "CI error: Missing PR description argument" } | ||
val description = catch({ String(Base64.decode(args.first())) }) { e -> | ||
throw IllegalArgumentException("CI error: Base 64 decoding failed! $e") | ||
} | ||
println("Analyzing PR description:") | ||
println(description) | ||
println("------") | ||
|
||
val analyzers = listOf<PRDescriptionAnalyzer>( | ||
ClosesIssueAnalyzer(), | ||
) | ||
|
||
val problems = analyzers.mapNotNull { | ||
it.analyze(description).leftOrNull() | ||
} | ||
if (problems.isNotEmpty()) { | ||
throw PRDescriptionError( | ||
buildString { | ||
append("\nWe found problems in your PR (Pull Request) description. ") | ||
append("Please, follow our PR template:\n") | ||
append("https://github.com/Ivy-Apps/ivy-wallet/blob/main/.github/PULL_REQUEST_TEMPLATE.md\n") | ||
problems.forEach { | ||
append(it) | ||
append("\n\n") | ||
} | ||
} | ||
) | ||
} | ||
|
||
println("All good! The PR description looks fine.") | ||
} | ||
|
||
class PRDescriptionError(msg: String) : Exception(msg) |
7 changes: 7 additions & 0 deletions
7
ci-actions/pr-description-check/src/main/kotlin/ivy/automate/pr/PRDescriptionAnalyzer.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,7 @@ | ||
package ivy.automate.pr | ||
|
||
import arrow.core.Either | ||
|
||
interface PRDescriptionAnalyzer { | ||
fun analyze(prDescription: String): Either<String, Unit> | ||
} |
170 changes: 170 additions & 0 deletions
170
ci-actions/pr-description-check/src/test/kotlin/ivy/automate/pr/ClosesIssueAnalyzerTest.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,170 @@ | ||
package ivy.automate.pr | ||
|
||
import arrow.core.Either | ||
import com.google.testing.junit.testparameterinjector.TestParameter | ||
import com.google.testing.junit.testparameterinjector.TestParameterInjector | ||
import io.kotest.matchers.shouldBe | ||
import org.junit.Before | ||
import org.junit.Test | ||
import org.junit.runner.RunWith | ||
|
||
@RunWith(TestParameterInjector::class) | ||
class ClosesIssueAnalyzerTest { | ||
|
||
private lateinit var analyzer: PRDescriptionAnalyzer | ||
|
||
@Before | ||
fun setup() { | ||
analyzer = ClosesIssueAnalyzer() | ||
} | ||
|
||
enum class PRDescTestCase( | ||
val prDescription: String, | ||
val expectedResult: Either<String, Unit> | ||
) { | ||
VALID_SHORT_1( | ||
prDescription = """ | ||
## Pull request (PR) checklist | ||
Please check if your pull request fulfills the following requirements: | ||
<!--💡 Tip: Tick checkboxes like this: [x] 💡--> | ||
- [x] I've read the [Contribution Guidelines](https://github.com/Ivy-Apps/ivy-wallet/blob/main/CONTRIBUTING.md) and my PR doesn't break the rules. | ||
- [x] I've read and understand the [Developer Guidelines](https://github.com/Ivy-Apps/ivy-wallet/blob/main/docs/Guidelines.md). | ||
- [x] I confirm that I've run the code locally and everything works as expected. | ||
- [x] My PR includes only the necessary changes to fix the issue (i.e., no unnecessary files or lines of code are changed). | ||
- [x] 🎬 I've attached a **screen recording** of using the new code to the next paragraph (if applicable). | ||
## What's changed? | ||
- The new name reflects the full-featured nature of the application | ||
## Does this PR close any GitHub issues? | ||
- Closes #3361 | ||
""".trimIndent(), | ||
expectedResult = Either.Right(Unit), | ||
), | ||
INVALID_SHORT_1( | ||
prDescription = """ | ||
## Pull request (PR) checklist | ||
Please check if your pull request fulfills the following requirements: | ||
<!--💡 Tip: Tick checkboxes like this: [x] 💡--> | ||
- [x] I've read the [Contribution Guidelines](https://github.com/Ivy-Apps/ivy-wallet/blob/main/CONTRIBUTING.md) and my PR doesn't break the rules. | ||
- [x] I've read and understand the [Developer Guidelines](https://github.com/Ivy-Apps/ivy-wallet/blob/main/docs/Guidelines.md). | ||
- [x] I confirm that I've run the code locally and everything works as expected. | ||
- [x] My PR includes only the necessary changes to fix the issue (i.e., no unnecessary files or lines of code are changed). | ||
- [x] 🎬 I've attached a **screen recording** of using the new code to the next paragraph (if applicable). | ||
## What's changed? | ||
- The new name reflects the full-featured nature of the application | ||
""".trimIndent(), | ||
expectedResult = Either.Left(ClosesIssueAnalyzer.MissingClosesProblem), | ||
), | ||
INVALID_DEFAULT_TEMPLATE( | ||
prDescription = """ | ||
## Pull request (PR) checklist | ||
Please check if your pull request fulfills the following requirements: | ||
<!--💡 Tip: Tick checkboxes like this: [x] 💡--> | ||
- [ ] I've read the [Contribution Guidelines](https://github.com/Ivy-Apps/ivy-wallet/blob/main/CONTRIBUTING.md) and my PR doesn't break the rules. | ||
- [ ] I've read and understand the [Developer Guidelines](https://github.com/Ivy-Apps/ivy-wallet/blob/main/docs/Guidelines.md). | ||
- [ ] I confirm that I've run the code locally and everything works as expected. | ||
- [ ] My PR includes only the necessary changes to fix the issue (i.e., no unnecessary files or lines of code are changed). | ||
- [ ] 🎬 I've attached a **screen recording** of using the new code to the next paragraph (if applicable). | ||
## Screen recording of interacting with your changes: | ||
<!--💡 Tip: Drag & drop the video here. 💡--> | ||
## What's changed? | ||
Describe with a few bullets **what's new:** | ||
<!--💡 Tip: After each more important point leave one line empty and show your changes in markdown table with screenshots or screen recordings replacing {media}. In the end, it should look like this: 💡--> | ||
- I've fixed... | ||
Before|After | ||
---------|--------- | ||
{media}|{media} | ||
{media}|{media} | ||
- ... | ||
- ... | ||
## Risk factors | ||
**What may go wrong if we merge your PR?** | ||
- ... | ||
- ... | ||
**In what cases won't your code work?** | ||
- ... | ||
- ... | ||
## Does this PR close any GitHub issues? (do not delete) | ||
- Closes #{ISSUE_NUMBER} | ||
<!--❗For example: - Closes #123 ❗--> | ||
<!--💡 Tip: Replace {ISSUE_NUMBER} with the number of Ivy Wallet ISSUE (https://github.com/Ivy-Apps/ivy-wallet/issues)(❗NOT PR❗) which this pull request fixes. If done correctly, you'll see the issue title linked on PR preview. 💡--> | ||
<!--💡 Tip: Multiple issues: | ||
- Closes #{ISSUE_NUMBER_1}, closes #{ISSUE_NUMBER_2}, closes #{ISSUE_NUMBER_3} | ||
If the PR doesn't close any GitHub issues, type "Closes N/A" to pass the CI check. | ||
💡--> | ||
## Troubleshooting CI failures ❌ | ||
Pull request checks failing? Read our [CI Troubleshooting guide](https://github.com/Ivy-Apps/ivy-wallet/blob/main/docs/CI-Troubleshooting.md). | ||
""".trimIndent(), | ||
expectedResult = Either.Left(ClosesIssueAnalyzer.MissingClosesProblem), | ||
), | ||
VALID_TEMPLATE_CLOSES_NUMBER( | ||
prDescription = """ | ||
## Pull request (PR) checklist | ||
Please check if your pull request fulfills the following requirements: | ||
<!--💡 Tip: Tick checkboxes like this: [x] 💡--> | ||
- [ ] I've read the [Contribution Guidelines](https://github.com/Ivy-Apps/ivy-wallet/blob/main/CONTRIBUTING.md) and my PR doesn't break the rules. | ||
- [ ] I've read and understand the [Developer Guidelines](https://github.com/Ivy-Apps/ivy-wallet/blob/main/docs/Guidelines.md). | ||
- [ ] I confirm that I've run the code locally and everything works as expected. | ||
- [ ] My PR includes only the necessary changes to fix the issue (i.e., no unnecessary files or lines of code are changed). | ||
- [ ] 🎬 I've attached a **screen recording** of using the new code to the next paragraph (if applicable). | ||
## Screen recording of interacting with your changes: | ||
<!--💡 Tip: Drag & drop the video here. 💡--> | ||
## What's changed? | ||
Describe with a few bullets **what's new:** | ||
- I've fixed... | ||
- | ||
Before|After | ||
---------|--------- | ||
{media}|{media} | ||
{media}|{media} | ||
## Risk factors | ||
**What may go wrong if we merge your PR?** | ||
- ... | ||
- ... | ||
**In what cases won't your code work?** | ||
- ... | ||
- ... | ||
## Does this PR close any GitHub issues? (do not delete) | ||
- Closes #123 | ||
<!--❗For example: - Closes #123 ❗--> | ||
<!--💡 Tip: Replace {ISSUE_NUMBER} with the number of Ivy Wallet ISSUE (https://github.com/Ivy-Apps/ivy-wallet/issues)(❗NOT PR❗) which this pull request fixes. If done correctly, you'll see the issue title linked on PR preview. 💡--> | ||
<!--💡 Tip: Multiple issues: | ||
- Closes #{ISSUE_NUMBER_1}, closes #{ISSUE_NUMBER_2}, closes #{ISSUE_NUMBER_3} | ||
If the PR doesn't close any GitHub issues, type "Closes N/A" to pass the CI check. | ||
💡--> | ||
## Troubleshooting GitHub Actions (CI) failures ❌ | ||
Pull request checks failing? Read our [CI Troubleshooting guide](https://github.com/Ivy-Apps/ivy-wallet/blob/main/docs/CI-Troubleshooting.md). | ||
""".trimIndent(), | ||
expectedResult = Either.Right(Unit) | ||
), | ||
VALID_CLOSES_NA( | ||
prDescription = "Closes N/A", | ||
expectedResult = Either.Right(Unit), | ||
) | ||
} | ||
|
||
@Test | ||
fun `validate PR description check`( | ||
@TestParameter testCase: PRDescTestCase, | ||
) { | ||
// When | ||
val result = analyzer.analyze(testCase.prDescription) | ||
|
||
// Then | ||
result shouldBe testCase.expectedResult | ||
} | ||
} |
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