All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.geirsson.CiReleasePlugin.scala Maven / Gradle / Ivy
package com.geirsson
import com.geirsson.PipeFail.PipeFailOps
import com.github.sbt.git.GitPlugin
import com.github.sbt.git.SbtGit.GitKeys
import com.jsuereth.sbtpgp.SbtPgp
import com.jsuereth.sbtpgp.SbtPgp.autoImport.*
import java.nio.file.Files
import java.nio.file.Paths
import java.nio.charset.StandardCharsets
import java.util.Base64
import sbt.Def
import sbt.Keys.*
import sbt.{ given, * }
import sbt.plugins.JvmPlugin
import sbtdynver.DynVerPlugin
import sbtdynver.DynVerPlugin.autoImport.*
import scala.deprecated
import scala.sys.process.{ given, * }
import scala.util.control.NonFatal
import xerial.sbt.Sonatype
import xerial.sbt.Sonatype.autoImport.*
object CiReleasePlugin extends AutoPlugin {
override def trigger = allRequirements
override def requires =
JvmPlugin && SbtPgp && DynVerPlugin && GitPlugin && Sonatype
def isSecure: Boolean =
System.getenv("TRAVIS_SECURE_ENV_VARS") == "true" ||
System.getenv("BUILD_REASON") == "IndividualCI" ||
System.getenv("PGP_SECRET") != null
def isTag: Boolean =
Option(System.getenv("TRAVIS_TAG")).exists(_.nonEmpty) ||
Option(System.getenv("CIRCLE_TAG")).exists(_.nonEmpty) ||
Option(System.getenv("CI_COMMIT_TAG")).exists(_.nonEmpty) ||
Option(System.getenv("BUILD_SOURCEBRANCH"))
.orElse(Option(System.getenv("GITHUB_REF")))
.exists(_.startsWith("refs/tags"))
def releaseTag: String =
Option(System.getenv("TRAVIS_TAG"))
.orElse(Option(System.getenv("CIRCLE_TAG")))
.orElse(Option(System.getenv("CI_COMMIT_TAG")))
.orElse(Option(System.getenv("BUILD_SOURCEBRANCH")))
.orElse(Option(System.getenv("GITHUB_REF")))
.getOrElse("")
def currentBranch: String =
Option(System.getenv("TRAVIS_BRANCH"))
.orElse(Option(System.getenv("CIRCLE_BRANCH")))
.orElse(Option(System.getenv("CI_COMMIT_BRANCH")))
.orElse(Option(System.getenv("BUILD_SOURCEBRANCH")))
.orElse(Option(System.getenv("GITHUB_REF")))
.getOrElse("")
@deprecated("Deprecated, please use isSecure", "1.4.32")
def isTravisSecure: Boolean = isSecure
@deprecated("Deprecated, please use isTag", "1.4.32")
def isTravisTag: Boolean = isTag
@deprecated("Deprecated, please use releaseTag", "1.4.32")
def travisTag: String = releaseTag
@deprecated("Deprecated, please use currentBranch", "1.4.32")
def travisBranch: String = currentBranch
def isAzure: Boolean =
System.getenv("TF_BUILD") == "True"
def isGithub: Boolean =
System.getenv("GITHUB_ACTION") != null
def isCircleCi: Boolean =
System.getenv("CIRCLECI") == "true"
def isGitlab: Boolean =
System.getenv("GITLAB_CI") == "true"
def setupGpg(): Unit = {
val versionLine = List("gpg", "--version").!!.linesIterator.toList.head
println(versionLine)
val TaggedVersion = """(\d{1,14})([\.\d{1,14}]*)((?:-\w+)*)""".r
val gpgVersion: Long = versionLine.split(" ").last match {
case TaggedVersion(m, _, _) => m.toLong
case _ => 0L
}
// https://dev.gnupg.org/T2313
val importCommand =
if (gpgVersion < 2L) "--import"
else "--batch --import"
val secret = sys.env("PGP_SECRET")
if (isAzure) {
// base64 encoded gpg secrets are too large for Azure variables but
// they fit within the 4k limit when compressed.
Files.write(Paths.get("gpg.zip"), Base64.getDecoder.decode(secret))
s"unzip gpg.zip".!
s"gpg $importCommand gpg.key".!
} else {
(Process(s"echo $secret") #|!
Process("base64 --decode") #|!
Process(s"gpg $importCommand")).!
}
}
private def gitHubScmInfo(user: String, repo: String) =
ScmInfo(
url(s"https://github.com/$user/$repo"),
s"scm:git:https://github.com/$user/$repo.git",
Some(s"scm:git:[email protected] :$user/$repo.git")
)
override lazy val buildSettings: Seq[Def.Setting[_]] = List(
dynverSonatypeSnapshots := true,
scmInfo ~= {
case Some(info) => Some(info)
case None =>
import scala.sys.process._
val identifier = """([^\/]+?)"""
val GitHubHttps =
s"https://github.com/$identifier/$identifier(?:\\.git)?".r
val GitHubGit = s"git://github.com:$identifier/$identifier(?:\\.git)?".r
val GitHubSsh = s"[email protected] :$identifier/$identifier(?:\\.git)?".r
try {
val remote = List("git", "ls-remote", "--get-url", "origin").!!.trim()
remote match {
case GitHubHttps(user, repo) => Some(gitHubScmInfo(user, repo))
case GitHubGit(user, repo) => Some(gitHubScmInfo(user, repo))
case GitHubSsh(user, repo) => Some(gitHubScmInfo(user, repo))
case _ => None
}
} catch {
case NonFatal(_) => None
}
}
)
override lazy val globalSettings: Seq[Def.Setting[_]] = List(
(Test / publishArtifact) := false,
publishMavenStyle := true,
commands += Command.command("ci-release") { currentState =>
val shouldDeployToSonatypeCentral = isDeploySetToSonatypeCentral(currentState)
val isSnapshot = isSnapshotVersion(currentState)
if (!isSecure) {
println("No access to secret variables, doing nothing")
currentState
} else {
println(
s"Running ci-release.\n" +
s" branch=$currentBranch"
)
setupGpg()
// https://github.com/olafurpg/sbt-ci-release/issues/64
val reloadKeyFiles =
"; set pgpSecretRing := pgpSecretRing.value; set pgpPublicRing := pgpPublicRing.value"
if (shouldDeployToSonatypeCentral) {
if (isSnapshot) {
println(s"Sonatype Central does not accept snapshots, only official releases. Aborting release.")
currentState
} else if (!isTag) {
println(s"No tag published. Cannot publish an official release without a tag and Sonatype Central does not accept snapshot releases. Aborting release.")
currentState
} else {
println("Tag push detected, publishing a stable release")
reloadKeyFiles ::
sys.env.getOrElse("CI_CLEAN", "; clean ; sonatypeBundleClean") ::
sys.env.getOrElse("CI_RELEASE", "+publishSigned") ::
sys.env.getOrElse("CI_SONATYPE_RELEASE", "sonatypeCentralRelease") ::
currentState
}
} else {
if (!isTag) {
if (isSnapshot) {
println(s"No tag push, publishing SNAPSHOT")
reloadKeyFiles ::
sys.env.getOrElse("CI_SNAPSHOT_RELEASE", "+publish") ::
currentState
} else {
// Happens when a tag is pushed right after merge causing the master branch
// job to pick up a non-SNAPSHOT version even if TRAVIS_TAG=false.
println(
"Snapshot releases must have -SNAPSHOT version number, doing nothing"
)
currentState
}
} else {
println("Tag push detected, publishing a stable release")
reloadKeyFiles ::
sys.env.getOrElse("CI_CLEAN", "; clean ; sonatypeBundleClean") ::
sys.env.getOrElse("CI_RELEASE", "+publishSigned") ::
sys.env.getOrElse("CI_SONATYPE_RELEASE", "sonatypeBundleRelease") ::
currentState
}
}
}
}
)
override lazy val projectSettings: Seq[Def.Setting[_]] = List(
publishConfiguration :=
publishConfiguration.value.withOverwrite(true),
publishLocalConfiguration :=
publishLocalConfiguration.value.withOverwrite(true),
publishTo := sonatypePublishToBundle.value
)
def isDeploySetToSonatypeCentral(state: State): Boolean = {
(ThisBuild / sonatypeCredentialHost).get(Project.extract(state).structure.data) match {
case Some(value) if value == Sonatype.sonatypeCentralHost => {
true
}
case _ => false
}
}
def isSnapshotVersion(state: State): Boolean = {
(ThisBuild / version).get(Project.extract(state).structure.data) match {
case Some(v) => v.endsWith("-SNAPSHOT")
case None => throw new NoSuchFieldError("version")
}
}
}