main.name.remal.gradle_plugins.plugins.ci.GitlabCIPlugin.kt Maven / Gradle / Ivy
package name.remal.gradle_plugins.plugins.ci
import name.remal.USER_HOME_DIR
import name.remal.allowAllOnlyForOwner
import name.remal.createDirectories
import name.remal.default
import name.remal.forbidExecute
import name.remal.gradle_plugins.dsl.ApplyPluginClasses
import name.remal.gradle_plugins.dsl.EnvironmentVariable
import name.remal.gradle_plugins.dsl.EnvironmentVariable.EnvironmentVariables
import name.remal.gradle_plugins.dsl.Plugin
import name.remal.gradle_plugins.dsl.PluginAction
import name.remal.gradle_plugins.dsl.PluginActionsGroup
import name.remal.gradle_plugins.dsl.PluginCondition
import name.remal.gradle_plugins.dsl.WithPluginClasses
import name.remal.gradle_plugins.dsl.extensions.get
import name.remal.gradle_plugins.plugins.environment_variables.EnvironmentVariablesPlugin
import name.remal.gradle_plugins.plugins.vcs.CommitAuthor
import name.remal.gradle_plugins.plugins.vcs.VcsOperations
import name.remal.gradle_plugins.plugins.vcs.VcsOperationsCustomizer
import name.remal.gradle_plugins.plugins.vcs.VcsOperationsCustomizer.Companion.VCS_OPERATIONS_CUSTOMIZERS
import name.remal.gradle_plugins.plugins.vcs.VcsOperationsExtension
import name.remal.gradle_plugins.plugins.vcs.VcsOperationsPlugin
import name.remal.newTempFile
import name.remal.nullIfEmpty
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"]
)
@ApplyPluginClasses(EnvironmentVariablesPlugin::class)
class GitlabCIPlugin : AbstractCIPlugin() {
@PluginCondition
fun Project.`Check if GITLAB_CI == 'true'`(): Boolean {
return getenv("GITLAB_CI") == "true"
}
@PluginAction(order = -1)
fun ExtensionContainer.`Set 'ci' extension values`() {
this[CIExtension::class.java].run {
isBuildOnCI = true
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_BRANCH')")
fun ExtensionContainer.setOverwriteCurrentBranch() {
getenv("CI_COMMIT_BRANCH").nullIfEmpty()?.let { branch ->
this[VcsOperationsExtension::class.java].overwriteCurrentBranch = branch
return
}
if (!getenv("CI_COMMIT_TAG").isNullOrEmpty()) {
return
}
getenv("CI_COMMIT_REF_NAME").nullIfEmpty()?.let { branch ->
this[VcsOperationsExtension::class.java].overwriteCurrentBranch = branch
return
}
}
@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) }
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy