From d763b99107a0a9da4f0a9e59ebe51d4a2704bc0e Mon Sep 17 00:00:00 2001 From: CalMWolfs <94038482+CalMWolfs@users.noreply.github.com> Date: Sat, 12 Oct 2024 05:39:53 +1100 Subject: Backend: Add Changelog Verification (#2692) --- .github/workflows/pr-check.yml | 57 ++++++++++++++++++++ build.gradle.kts | 12 ++++- buildSrc/build.gradle.kts | 17 ++++++ .../skyhannibuildsystem/ChangelogVerification.kt | 63 ++++++++++++++++++++++ 4 files changed, 147 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/pr-check.yml create mode 100644 buildSrc/build.gradle.kts create mode 100644 buildSrc/src/main/kotlin/skyhannibuildsystem/ChangelogVerification.kt diff --git a/.github/workflows/pr-check.yml b/.github/workflows/pr-check.yml new file mode 100644 index 000000000..cabb09c1d --- /dev/null +++ b/.github/workflows/pr-check.yml @@ -0,0 +1,57 @@ +name: "PR Changelog Verification" + +on: + pull_request_target: + types: [ opened, edited ] + +jobs: + verify-changelog: + if: github.event.pull_request.state == 'open' && '511310721' == github.repository_id + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - uses: ./.github/actions/setup-normal-workspace + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Run ChangeLog verification + env: + PR_TITLE: ${{ github.event.pull_request.title }} + PR_BODY: ${{ github.event.pull_request.body }} + run: | + ./gradlew checkPrDescription -PprTitle="${PR_TITLE}" -PprBody="${PR_BODY}" + + - name: Add label if changelog verification fails + if: failure() + uses: actions-ecosystem/action-add-labels@v1 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + labels: 'Wrong Title/Changelog' + + - name: Remove label if changelog verification passes + if: success() + uses: actions-ecosystem/action-remove-labels@v1 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + labels: 'Wrong Title/Changelog' + + - name: Add comment to PR if changelog verification fails + if: failure() + uses: actions/github-script@v6 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const fs = require('fs'); + const test = fs.readFileSync('build/changelog_errors.txt', 'utf8'); + const commentBody = `${test}` + + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: commentBody + }) diff --git a/build.gradle.kts b/build.gradle.kts index 190385c1e..dde5ac410 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,11 +3,12 @@ import at.skyhanni.sharedvariables.MultiVersionStage import at.skyhanni.sharedvariables.ProjectTarget import at.skyhanni.sharedvariables.SHVersionInfo import at.skyhanni.sharedvariables.versionString +import io.gitlab.arturbosch.detekt.Detekt +import io.gitlab.arturbosch.detekt.DetektCreateBaselineTask import net.fabricmc.loom.task.RunGameTask import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.tasks.KotlinCompile -import io.gitlab.arturbosch.detekt.Detekt -import io.gitlab.arturbosch.detekt.DetektCreateBaselineTask +import skyhannibuildsystem.ChangelogVerification plugins { idea @@ -102,6 +103,13 @@ tasks.runClient { }, ) } + +tasks.register("checkPrDescription", ChangelogVerification::class) { + this.outputDirectory.set(layout.buildDirectory) + this.prTitle = project.findProperty("prTitle") as String + this.prBody = project.findProperty("prBody") as String +} + val shot = shots.shot("minecraft", rootProject.file("shots.txt")) dependencies { diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts new file mode 100644 index 000000000..505f438b9 --- /dev/null +++ b/buildSrc/build.gradle.kts @@ -0,0 +1,17 @@ +plugins { + `kotlin-dsl` +} + +repositories { + mavenCentral() + maven("https://jitpack.io") { + content { + includeGroupByRegex("com\\.github\\..*") + } + } +} + +dependencies { + implementation("org.jetbrains.kotlin:kotlin-stdlib") + implementation("com.github.SkyHanniStudios:SkyHanniChangelogBuilder:1.0.1") +} diff --git a/buildSrc/src/main/kotlin/skyhannibuildsystem/ChangelogVerification.kt b/buildSrc/src/main/kotlin/skyhannibuildsystem/ChangelogVerification.kt new file mode 100644 index 000000000..422a62cb1 --- /dev/null +++ b/buildSrc/src/main/kotlin/skyhannibuildsystem/ChangelogVerification.kt @@ -0,0 +1,63 @@ +package skyhannibuildsystem + +import at.hannibal2.changelog.SkyHanniChangelogBuilder +import org.gradle.api.DefaultTask +import org.gradle.api.GradleException +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.Internal +import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.TaskAction +import java.io.File + +abstract class ChangelogVerification : DefaultTask() { + + @get:OutputDirectory + abstract val outputDirectory: DirectoryProperty + + @Input + var prTitle: String = "" + + @Input + var prBody: String = "" + + @get:Internal + val prBodyLines get() = prBody.lines() + + private val prLink = "ignored" + private val templateLocation = "https://github.com/hannibal002/SkyHanni/blob/beta/pull_request_template.md" + + @TaskAction + fun scanChangelog() { + if (prBodyLines.contains("exclude_from_changelog")) { + println("PR is excluded from changelog verification") + return + } + + val (changes, bodyErrors) = SkyHanniChangelogBuilder.findChanges(prBodyLines, prLink) + val titleErrors = SkyHanniChangelogBuilder.findPullRequestNameErrors(prTitle, changes) + + if (bodyErrors.isEmpty() && titleErrors.isEmpty()) { + println("Changelog and title verification successful") + } else { + bodyErrors.forEach { println(it.message) } + titleErrors.forEach { println(it.message) } + + // Export errors so that they can be listed in the PR comment + val errorFile = File(outputDirectory.get().asFile, "changelog_errors.txt") + + errorFile.appendText("I have detected some issues with your pull request:\n\n") + + if (bodyErrors.isNotEmpty()) { + errorFile.appendText("Body issues:\n${bodyErrors.joinToString("\n") { it.formatLine() }}\n\n") + } + if (titleErrors.isNotEmpty()) { + errorFile.appendText("Title issues:\n${titleErrors.joinToString("\n") { it.message }}\n\n") + } + + errorFile.appendText("Please fix these issues. For the correct format, refer to the [pull request template]($templateLocation).") + + throw GradleException("Changelog verification failed") + } + } +} -- cgit