All Downloads are FREE. Search and download functionalities are using the official Maven repository.

main.name.remal.gradle_plugins.plugins.ci.GitlabCIPlugin.kt Maven / Gradle / Ivy

There is a newer version: 1.9.2
Show newest version
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