initial commit
This commit is contained in:
25
src/main/groovy/util/CIProperties.groovy
Normal file
25
src/main/groovy/util/CIProperties.groovy
Normal file
@@ -0,0 +1,25 @@
|
||||
package util
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
|
||||
@CompileStatic
|
||||
class CIProperties {
|
||||
|
||||
public static final String CI_PROPERTIES_PREFIX = "ci"
|
||||
|
||||
static String getProperty(String propertyName) {
|
||||
return findProperty(propertyName).orElseThrow { new IllegalStateException("Required CI property named '${propertyName}' was not found!") }
|
||||
}
|
||||
|
||||
static Optional<String> findProperty(String propertyName) {
|
||||
return System.findGlobalProperty("${CI_PROPERTIES_PREFIX}.${propertyName}")
|
||||
}
|
||||
|
||||
static List<String> getListProperty(String propertyName) {
|
||||
return findListProperty(propertyName).orElseThrow { new IllegalStateException("Required CI property named '${propertyName}' was not found!") }
|
||||
}
|
||||
|
||||
static Optional<List<String>> findListProperty(String propertyName) {
|
||||
return System.findGlobalPropertyList("${CI_PROPERTIES_PREFIX}.${propertyName}")
|
||||
}
|
||||
}
|
||||
26
src/main/groovy/util/DockerBuildCommandFactory.groovy
Normal file
26
src/main/groovy/util/DockerBuildCommandFactory.groovy
Normal file
@@ -0,0 +1,26 @@
|
||||
package util
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
|
||||
@CompileStatic
|
||||
class DockerBuildCommandFactory {
|
||||
|
||||
static String getBuildAdditionalArgs(String dockerfileName) {
|
||||
def propertyNames = [
|
||||
"docker.build.${dockerfileName.toLowerCase()}.additional-args",
|
||||
"docker.build.additional-args"
|
||||
]
|
||||
|
||||
return propertyNames.stream()
|
||||
.map { CIProperties.findProperty("ci.docker.build.additional-args").orNull() }
|
||||
.filter { it != null }
|
||||
.findFirst()
|
||||
.orElse("")
|
||||
}
|
||||
|
||||
static String getBuildCommand(String dockerfileName, String additionalArgs = "", String context = ".") {
|
||||
def dockerCommand = "docker build ${context} -f '${dockerfileName}' ${additionalArgs} ${getBuildAdditionalArgs(dockerfileName)}"
|
||||
return dockerCommand
|
||||
}
|
||||
|
||||
}
|
||||
29
src/main/groovy/util/DockerImageNames.groovy
Normal file
29
src/main/groovy/util/DockerImageNames.groovy
Normal file
@@ -0,0 +1,29 @@
|
||||
package util
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
|
||||
@CompileStatic
|
||||
class DockerImageNames {
|
||||
|
||||
static String getImageTag(String baseName, String dockerfile) {
|
||||
def imageTagPostfix = CIProperties.findProperty("docker.image.tag.${dockerfile.toLowerCase()}.postfix").orElse("")
|
||||
return "${baseName}${imageTagPostfix}"
|
||||
}
|
||||
|
||||
static String getImageName(String dockerfileName) {
|
||||
def propertyNames = [
|
||||
"docker.image.${dockerfileName.toLowerCase()}.name",
|
||||
"docker.image.base.name"
|
||||
]
|
||||
|
||||
return propertyNames.stream()
|
||||
.map { it.toString() }
|
||||
.map {
|
||||
CIProperties.findProperty(it).orNull()
|
||||
}
|
||||
.filter { it != null }
|
||||
.findFirst()
|
||||
.orElseThrow { new NoSuchElementException("There is no one property set: ${propertyNames}") }
|
||||
}
|
||||
|
||||
}
|
||||
29
src/main/groovy/util/DockerLogin.groovy
Normal file
29
src/main/groovy/util/DockerLogin.groovy
Normal file
@@ -0,0 +1,29 @@
|
||||
package util
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
import groovy.transform.Memoized
|
||||
|
||||
@CompileStatic
|
||||
class DockerLogin {
|
||||
|
||||
static void perform() {
|
||||
loginDockerInternal()
|
||||
}
|
||||
|
||||
@Memoized
|
||||
private static Object loginDockerInternal() {
|
||||
// Проверяем на всякий случай, что докер вообще установлен
|
||||
if (System.findExecutablesInPath(['docker']).isEmpty())
|
||||
throw new FileNotFoundException("Can't find installed docker-compose at that system!")
|
||||
|
||||
// Логинимся в Registry
|
||||
ScriptLog.printf "Performing login to registry..."
|
||||
def registryName = System.getGlobalProperty("ci.docker.registry")
|
||||
def registryUser = System.getGlobalProperty("ci.docker.registry.username")
|
||||
def registryPassword = System.getGlobalProperty("ci.docker.registry.password")
|
||||
|
||||
sh "docker login $registryName -u $registryUser -p $registryPassword"
|
||||
|
||||
ScriptLog.printf "Login into docker registry '${registryName}' successful!"
|
||||
}
|
||||
}
|
||||
17
src/main/groovy/util/DockerTags.groovy
Normal file
17
src/main/groovy/util/DockerTags.groovy
Normal file
@@ -0,0 +1,17 @@
|
||||
package util;
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
|
||||
@CompileStatic
|
||||
class DockerTags {
|
||||
|
||||
static String getDockerTagForDockerfile(String dockerfileName, String baseTag) {
|
||||
return "${baseTag}${getDockerTagPostfixForDockerfile(dockerfileName)}"
|
||||
}
|
||||
|
||||
static String getDockerTagPostfixForDockerfile(String dockerfileName) {
|
||||
return CIProperties.findProperty("docker.tag.${dockerfileName}.prefix")
|
||||
.orElse("")
|
||||
}
|
||||
|
||||
}
|
||||
38
src/main/groovy/util/Dockerfiles.groovy
Normal file
38
src/main/groovy/util/Dockerfiles.groovy
Normal file
@@ -0,0 +1,38 @@
|
||||
package util
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
|
||||
@CompileStatic
|
||||
class Dockerfiles {
|
||||
|
||||
static List<String> getPresetDockerfiles() {
|
||||
def preset = CIProperties.findProperty("docker.files.preset")
|
||||
.orElse("default")
|
||||
|
||||
def presetDockerfiles = CIProperties.findListProperty("docker.files.${preset}")
|
||||
.orElse([])
|
||||
|
||||
if (presetDockerfiles.isEmpty())
|
||||
return CIProperties.findListProperty("docker.files")
|
||||
.orElse(["Dockerfile"])
|
||||
else
|
||||
return presetDockerfiles
|
||||
}
|
||||
|
||||
static List<String> getReleaseDockerfiles() {
|
||||
return CIProperties.findListProperty("release.artifacts.dockerfiles")
|
||||
.orElseGet {
|
||||
CIProperties.findListProperty("gitea.release.artifacts.dockerfiles") // Обратная совместимость
|
||||
.orElseGet {
|
||||
getPresetDockerfiles()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static List<String> getDeployDockerfiles() {
|
||||
return CIProperties.findListProperty("deploy.dockerfile.names")
|
||||
.orElseGet {
|
||||
getPresetDockerfiles()
|
||||
}
|
||||
}
|
||||
}
|
||||
44
src/main/groovy/util/GitTags.groovy
Normal file
44
src/main/groovy/util/GitTags.groovy
Normal file
@@ -0,0 +1,44 @@
|
||||
package util
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
import io.tswf.groovy.bettergroovy.scripting.v2.git.Git
|
||||
|
||||
@CompileStatic
|
||||
class GitTags {
|
||||
public static final String DEFAULT_RELEASE_TAG_PREFIX = "release-"
|
||||
public static final String DEFAULT_DEPLOY_TAG_PREFIX = DEFAULT_RELEASE_TAG_PREFIX
|
||||
|
||||
static Set<String> getDeployPrefixes() {
|
||||
return CIProperties.findListProperty("git.tag.deploy.prefixes")
|
||||
.orElse([DEFAULT_DEPLOY_TAG_PREFIX])
|
||||
.toSet()
|
||||
}
|
||||
|
||||
static Set<String> getReleasePrefixes() {
|
||||
return CIProperties.findListProperty("git.tag.release.prefixes")
|
||||
.orElse([DEFAULT_RELEASE_TAG_PREFIX])
|
||||
.toSet()
|
||||
}
|
||||
|
||||
static List<String> getTagsWithPrefix(Collection<String> prefixes) {
|
||||
def matchingTags = Git.tags.stream()
|
||||
.filter {tag -> prefixes.any { tag.startsWith(it) }}
|
||||
.toList()
|
||||
|
||||
return matchingTags
|
||||
}
|
||||
|
||||
static List<String> getReleaseTags() {
|
||||
def releasePrefixes = getReleasePrefixes()
|
||||
return getTagsWithPrefix(releasePrefixes)
|
||||
}
|
||||
|
||||
static List<String> getDeployTags() {
|
||||
def deployPrefixes = getDeployPrefixes()
|
||||
return getTagsWithPrefix(deployPrefixes)
|
||||
}
|
||||
|
||||
static String sanitizeTagFromPrefixes(String tag, Collection<String> prefixes) {
|
||||
return tag.removeAll(prefixes)
|
||||
}
|
||||
}
|
||||
39
src/main/groovy/util/GlobalProperties.groovy
Normal file
39
src/main/groovy/util/GlobalProperties.groovy
Normal file
@@ -0,0 +1,39 @@
|
||||
package util
|
||||
|
||||
import groovy.transform.Memoized
|
||||
|
||||
class GlobalProperties {
|
||||
|
||||
@Memoized
|
||||
static loadGlobalProperties() {
|
||||
def propertiesFiles = System.findGlobalPropertyList("${CIProperties.CI_PROPERTIES_PREFIX}.properties.file.locations")
|
||||
.orElse([".ci/ci.properties"])
|
||||
.map { new File(it) }
|
||||
|
||||
if (propertiesFiles.isNotNullOrEmpty()) {
|
||||
propertiesFiles.forEach { propertiesFile ->
|
||||
if (propertiesFile.exists()) {
|
||||
loadPropertiesFile(propertiesFile)
|
||||
} else {
|
||||
ScriptLog.printf "Skipping non-existing properties file '${propertiesFile.absoluteCanonicalFile.path}'!"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void loadPropertiesFile(File propertiesFile) {
|
||||
if (propertiesFile == null) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!propertiesFile.exists()) {
|
||||
throw new IOException("Could not find properties file '${propertiesFile}' (with absolute path: '${propertiesFile.absoluteCanonicalFile.path}')!")
|
||||
}
|
||||
|
||||
if (propertiesFile.isDirectory()) {
|
||||
throw new IOException("Directory found instead properties file '${propertiesFile}' (with absolute path: '${propertiesFile.absoluteCanonicalFile.path}')!")
|
||||
}
|
||||
|
||||
System.registerGlobalConfiguration(propertiesFile)
|
||||
}
|
||||
}
|
||||
67
src/main/groovy/util/ReleaseArtifactNames.groovy
Normal file
67
src/main/groovy/util/ReleaseArtifactNames.groovy
Normal file
@@ -0,0 +1,67 @@
|
||||
package util
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
|
||||
@CompileStatic
|
||||
class ReleaseArtifactNames {
|
||||
|
||||
static List<ArtifactNameResolver> artifactFileNameResolvers = new ArrayList<>()
|
||||
|
||||
static Optional<String> getNewArtifactName(File file, String dockerfileName) {
|
||||
def newArtifactName = artifactFileNameResolvers.stream()
|
||||
.map { it.resolveArtifactNewName(file, dockerfileName) }
|
||||
.filter { it != null }
|
||||
.firstOrNull()
|
||||
|
||||
return Optional.ofNullable(newArtifactName)
|
||||
}
|
||||
|
||||
static void registerArtifactResolver(ArtifactNameResolver resolver) {
|
||||
artifactFileNameResolvers << resolver
|
||||
}
|
||||
|
||||
static {
|
||||
registerArtifactResolver { file, dockerfile ->
|
||||
CIProperties.findProperty("release.artifact.${dockerfile}.${replacePathInvalidChars(file.absoluteCanonicalFile.path)}.name").orNull()
|
||||
}
|
||||
|
||||
registerArtifactResolver { file, dockerfile ->
|
||||
CIProperties.findProperty("release.artifact.${dockerfile}.${file.name}.name").orNull()
|
||||
}
|
||||
|
||||
registerArtifactResolver { file, dockerfile ->
|
||||
CIProperties.findProperty("release.artifact.${replacePathInvalidChars(file.absoluteCanonicalFile.path)}.name").orNull()
|
||||
}
|
||||
|
||||
registerArtifactResolver { file, dockerfile ->
|
||||
CIProperties.findProperty("release.artifact.${file.name}.name").orNull()
|
||||
}
|
||||
|
||||
// В рамках обратной совместимости
|
||||
registerArtifactResolver { file, dockerfile ->
|
||||
CIProperties.findProperty("gitea.release.artifact.${dockerfile}.${replacePathInvalidChars(file.absoluteCanonicalFile.path)}.name").orNull()
|
||||
}
|
||||
|
||||
registerArtifactResolver { file, dockerfile ->
|
||||
CIProperties.findProperty("gitea.release.artifact.${dockerfile}.${file.name}.name").orNull()
|
||||
}
|
||||
|
||||
registerArtifactResolver { file, dockerfile ->
|
||||
CIProperties.findProperty("gitea.release.artifact.${replacePathInvalidChars(file.absoluteCanonicalFile.path)}.name").orNull()
|
||||
}
|
||||
|
||||
registerArtifactResolver { file, dockerfile ->
|
||||
CIProperties.findProperty("gitea.release.artifact.${file.name}.name").orNull()
|
||||
}
|
||||
}
|
||||
|
||||
static String replacePathInvalidChars(String fileFullName) {
|
||||
return fileFullName
|
||||
.replace('\\', '_')
|
||||
.replace('/', '_')
|
||||
}
|
||||
|
||||
static interface ArtifactNameResolver {
|
||||
String resolveArtifactNewName(File artifactFile, String dockerfileName)
|
||||
}
|
||||
}
|
||||
23
src/main/groovy/util/ReleaseArtifacts.groovy
Normal file
23
src/main/groovy/util/ReleaseArtifacts.groovy
Normal file
@@ -0,0 +1,23 @@
|
||||
package util
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
|
||||
@CompileStatic
|
||||
class ReleaseArtifacts {
|
||||
|
||||
static List<String> getArtifacts(String dockerFile) {
|
||||
def propertyNames = [
|
||||
"gitea.release.${dockerFile}.artifacts", // В рамках обратной совместимости
|
||||
"gitea.release.artifacts", // В рамках обратной совместимости
|
||||
"release.artifacts.${dockerFile}.grab",
|
||||
"release.artifacts.grab",
|
||||
]
|
||||
|
||||
return propertyNames.stream()
|
||||
.map { it.toString() }
|
||||
.map { CIProperties.findListProperty(it).orNull() }
|
||||
.filter { it != null }
|
||||
.map { (List<String>) it }
|
||||
.findFirst().orElse([])
|
||||
}
|
||||
}
|
||||
27
src/main/groovy/util/ReleaseDescriptionReader.groovy
Normal file
27
src/main/groovy/util/ReleaseDescriptionReader.groovy
Normal file
@@ -0,0 +1,27 @@
|
||||
package util
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
|
||||
@CompileStatic
|
||||
class ReleaseDescriptionReader {
|
||||
|
||||
static Optional<String> readDescription(String releaseName) {
|
||||
def releaseDescriptionsDir = CIProperties.findProperty("release.descriptions.dir")
|
||||
.orElse(".releases/changelog/")
|
||||
.with {
|
||||
new File(it)
|
||||
}
|
||||
|
||||
def releaseDescriptionFile = releaseDescriptionsDir.subFile("${releaseName}-changelog.md")
|
||||
|
||||
if (releaseDescriptionFile.exists()) {
|
||||
def releaseAbsPath = releaseDescriptionFile.absoluteCanonicalFile.path
|
||||
ScriptLog.printf "Found description file for '$releaseName' release in '$releaseAbsPath'! It will be used for release creation."
|
||||
return Optional.of(releaseDescriptionFile.getText("UTF-8"))
|
||||
} else {
|
||||
ScriptLog.printf "Release description file not found in '${releaseDescriptionFile.absoluteCanonicalFile.path}', falling back to default value..."
|
||||
}
|
||||
|
||||
return Optional.empty()
|
||||
}
|
||||
}
|
||||
8
src/main/groovy/util/ScriptLog.groovy
Normal file
8
src/main/groovy/util/ScriptLog.groovy
Normal file
@@ -0,0 +1,8 @@
|
||||
package util
|
||||
|
||||
class ScriptLog {
|
||||
static void printf(Object text, Object... args) {
|
||||
def callerClassName = new Throwable().getStackTrace()[1].getClassName().split("\\.").last()
|
||||
println "[${callerClassName}]: ${String.format(String.valueOf(text), args)}"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user