name.remal.gradle_plugins.plugins.ci.GitlabCIPlugin.kt Maven / Gradle / Ivy
package name.remal.gradle_plugins.plugins.ci
import name.remal.*
import name.remal.gradle_plugins.dsl.*
import name.remal.gradle_plugins.dsl.EnvironmentVariable.EnvironmentVariables
import name.remal.gradle_plugins.dsl.extensions.applyPlugin
import name.remal.gradle_plugins.dsl.extensions.get
import name.remal.gradle_plugins.plugins.environment_variables.EnvironmentVariablesPlugin
import name.remal.gradle_plugins.plugins.vcs.*
import name.remal.gradle_plugins.plugins.vcs.VcsOperationsCustomizer.Companion.VCS_OPERATIONS_CUSTOMIZERS
import org.gradle.api.Project
import org.gradle.api.invocation.Gradle
import org.gradle.api.plugins.ExtensionContainer
import java.io.File
import java.lang.System.getenv
import java.net.URI
@Plugin(
id = "name.remal.gitlab-ci",
description = "Plugin that helps to integrate with GitLab CI.",
tags = ["gitlab-ci", "gitlab"]
)
class GitlabCIPlugin : BaseCIPlugin() {
@PluginCondition
fun Project.`Check if GITLAB_CI == 'true'`(): Boolean {
applyPlugin(EnvironmentVariablesPlugin::class.java)
return getenv("GITLAB_CI") == "true"
}
@PluginAction(order = -1)
fun ExtensionContainer.`Set 'ci' extension values`() {
this[CIExtension::class.java].run {
pipelineId = null
buildId = getenv("CI_PIPELINE_ID").nullIfEmpty()
stageName = getenv("CI_JOB_STAGE").nullIfEmpty()
jobName = getenv("CI_JOB_NAME").nullIfEmpty()
}
}
@PluginActionsGroup("Configure name.remal.vcs-operations plugin")
@WithPluginClasses(VcsOperationsPlugin::class)
inner class ConfigureVcsOperationsPlugin {
@PluginAction("vcsOperations.overwriteCurrentBranch = getenv('CI_COMMIT_REF_NAME')")
fun ExtensionContainer.setOverwriteCurrentBranch() {
getenv("CI_COMMIT_REF_NAME")?.let { refName ->
if (refName.isNotEmpty() && getenv("CI_COMMIT_TAG").isNullOrEmpty()) {
this[VcsOperationsExtension::class.java].overwriteCurrentBranch = refName
}
}
}
@PluginAction
@EnvironmentVariables(
EnvironmentVariable("SSH_PRIVATE_KEY", description = "SSH private key to push into repository"),
EnvironmentVariable("SSH_PRIVATE_KEY_FILE", description = "SSH private key file path to push into repository"),
EnvironmentVariable("SSH_PRIVATE_KEY_PASSWORD", description = "SSH private key password to push into repository")
)
fun ExtensionContainer.`Setup VCS remote URI if SSH_PRIVATE_KEY environment variable is set`(gradle: Gradle) {
val vcsOperations = this[VcsOperationsExtension::class.java]
val sshPrivateKeyFile: File = run {
val sshPrivateKeyFilePath = getenv("SSH_PRIVATE_KEY_FILE")?.trim().nullIfEmpty()
if (sshPrivateKeyFilePath != null) {
return@run File(sshPrivateKeyFilePath).absoluteFile
} else {
val sshPrivateKey = getenv("SSH_PRIVATE_KEY")?.trim().nullIfEmpty()
if (sshPrivateKey != null) {
val sshKeysDir = USER_HOME_DIR.resolve(".ssh-keys")
.createDirectories()
.allowAllOnlyForOwner()
return@run newTempFile(suffix = ".priv", baseTempDir = sshKeysDir)
.allowAllOnlyForOwner()
.forbidExecute()
.also { gradle.buildFinished { _ -> it.deleteRecursively() } }
.also { it.writeText(sshPrivateKey) }
} else {
return@run null
}
}
} ?: return
val repositoryURI = URI(getenv("CI_REPOSITORY_URL") ?: return)
if (repositoryURI.scheme.default().startsWith("http")) {
val remoteURI = buildString {
append("git@")
append(repositoryURI.host)
append(":")
append(repositoryURI.path.substringAfter('/'))
}
vcsOperations.setUnauthorizedRemoteURI(remoteURI)
}
vcsOperations.setSSHAuth(sshPrivateKeyFile, getenv("SSH_PRIVATE_KEY_PASSWORD"))
}
@PluginAction
fun Gradle.`Add GitLab VcsOperationsCustomizer`() {
val customizer = object : VcsOperationsCustomizer {
override fun customize(vcsOperations: VcsOperations) {
if (vcsOperations.commitAuthor == null) {
val name = getenv("GITLAB_USER_NAME")?.trim().nullIfEmpty()
?: getenv("GITLAB_USER_LOGIN")?.trim().nullIfEmpty()
val email = getenv("GITLAB_USER_EMAIL")?.trim().nullIfEmpty()
if (name != null || email != null) {
vcsOperations.commitAuthor = CommitAuthor(name.default(), email.default())
}
}
}
}
VCS_OPERATIONS_CUSTOMIZERS.add(customizer)
buildFinished { VCS_OPERATIONS_CUSTOMIZERS.remove(customizer) }
}
}
}