diff --git a/.gitignore b/.gitignore index 9c5cf7b01..955683428 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ *.iml .gradle build +!**/src/main/**/build local.properties out userHome diff --git a/build.gradle.kts b/build.gradle.kts index 5242a2642..207d30cb8 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -9,6 +9,7 @@ buildscript { } plugins { + id("com.github.triplet.gradle.build") id("com.github.ben-manes.versions") version "0.25.0" } @@ -20,23 +21,6 @@ tasks.register("clean") { delete("build") } -tasks.register("ciBuild") { - val isMaster = System.getenv("CIRCLE_BRANCH") == "master" - val isPr = System.getenv("CIRCLE_PULL_REQUEST") != null - val isSnapshot = project("plugin").version.toString().contains("snapshot", true) - - fun allTasks(name: String) = allprojects.mapNotNull { it.tasks.findByName(name) } - if (isMaster && !isPr) { // Release build - if (isSnapshot) { - dependsOn(allTasks("build"), allTasks("publish")) - } else { - dependsOn(allTasks("build")) - } - } else { - dependsOn(allTasks("check")) - } -} - allprojects { repositories.deps() diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 64c90a6db..2b722deda 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -10,3 +10,7 @@ tasks.withType().configureEach { enableStricterValidation = true failOnWarning = true } + +dependencies { + implementation("org.ajoberstar.grgit:grgit-gradle:3.1.1") +} diff --git a/buildSrc/src/main/kotlin/com/github/triplet/gradle/build/GPPBuildPlugin.kt b/buildSrc/src/main/kotlin/com/github/triplet/gradle/build/GPPBuildPlugin.kt new file mode 100644 index 000000000..49d7745e0 --- /dev/null +++ b/buildSrc/src/main/kotlin/com/github/triplet/gradle/build/GPPBuildPlugin.kt @@ -0,0 +1,49 @@ +package com.github.triplet.gradle.build + +import org.ajoberstar.grgit.Grgit +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.Task + +class GPPBuildPlugin : Plugin { + private val isMaster get() = System.getenv("CIRCLE_BRANCH") == "master" + private val isPr get() = System.getenv("CIRCLE_PULL_REQUEST") != null + + override fun apply(project: Project) { + check(project === project.rootProject) { "Cannot apply build plugin to subprojects." } + + project.tasks.register("ciBuild") { + if (isReleaseBuild()) { + val buildTasks = allTasks("build") + + dependsOn(buildTasks) + if (isSnapshotBuild()) { + dependsOn(allTasks("publish").mustRunAfter(buildTasks)) + } else if (isPublishBuild()) { + dependsOn(allTasks("publishPlugins").mustRunAfter(buildTasks)) + } + } else { + dependsOn(allTasks("check")) + } + } + } + + private fun isReleaseBuild() = isMaster && !isPr + + private fun Task.isSnapshotBuild() = + project.allprojects.any { it.version.toString().contains("snapshot", true) } + + private fun Task.isPublishBuild() = Grgit.open { dir = project.rootDir }.use { + if (!it.status().isClean) return@use false + + val latestCommit = it.head() + val latestTag = it.tag.list().maxBy { it.commit.dateTime } ?: return@use false + + latestCommit.id == latestTag.commit.id + } + + private fun Task.allTasks(name: String) = + project.allprojects.mapNotNull { it.tasks.findByName(name) } + + private fun List.mustRunAfter(tasks: List) = onEach { it.mustRunAfter(tasks) } +} diff --git a/buildSrc/src/main/resources/META-INF/gradle-plugins/com.github.triplet.gradle.build.properties b/buildSrc/src/main/resources/META-INF/gradle-plugins/com.github.triplet.gradle.build.properties new file mode 100644 index 000000000..cc8af8645 --- /dev/null +++ b/buildSrc/src/main/resources/META-INF/gradle-plugins/com.github.triplet.gradle.build.properties @@ -0,0 +1 @@ +implementation-class=com.github.triplet.gradle.build.GPPBuildPlugin