freeleaps-ops/first-class-pipeline/vars/executeFreeleapsPipeline.groovy

198 lines
6.4 KiB
Groovy
Raw Normal View History

#!groovy
import com.freeleaps.devops.SourceFetcher
import com.freeleaps.devops.DependenciesResolver
import com.freeleaps.devops.enums.DependenciesManager
import com.freeleaps.devops.enums.ServiceLanguage
import com.freeleaps.devops.CommitMessageLinter
import com.freeleaps.devops.ChangedComponentsDetector
def generateComponentStages(component, configurations) {
return [
stage("${component.name} :: Build Agent Setup") {
script {
if (env.executeMode == "fully" || env.changedComponents.contains(component.name)) {
def buildAgentImage = component.buildAgentImage
if (buildAgentImage == null || buildAgentImage.isEmpty()) {
log.warn("Pipeline", "Not set buildAgentImage for ${component.name}, using default build agent image")
def language = ServiceLanguage.parse(configurations.serviceLang)
switch(language) {
case ServiceLanguage.PYTHON:
buildAgentImage = "python:3.10-slim-buster"
break
case ServiceLanguage.JS:
buildAgentImage = "node:lts-alpine"
break
default:
error("Unknown service language")
}
}
log.info("Pipeline", "Using ${buildAgentImage} as build agent image for ${component.name}")
env.buildAgentImage = buildAgentImage
}
}
},
stage("${component.name} :: Dependencies Resolving") {
podTemplate(
label: "dep-resolver-${component.name}",
containers: [
containerTemplate(
name: 'dep-resolver',
image: env.buildAgentImage,
ttyEnabled: true,
command: 'sleep',
args: 'infinity'
)
]
) {
node("dep-resolver-${component.name}") {
step {
script {
catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
if (env.executeMode == "fully" || env.changedComponents.contains(component.name)) {
log.info("Pipeline", "Using ${env.buildAgentImage} as build agent image for dependencies resolving")
def sourceFetcher = new SourceFetcher(this)
sourceFetcher.fetch(configurations)
def language = ServiceLanguage.parse(component.language)
def depManager = DependenciesManager.parse(component.dependenciesManager)
def dependenciesResolver = new DependenciesResolver(this, language, env.workspace + "/" + component.root + "/")
dependenciesResolver.useManager(depManager)
if (component.buildCacheEnabled) {
dependenciesResolver.enableCachingSupport()
} else {
dependenciesResolver.disableCachingSupport()
}
dependenciesResolver.resolve(component)
}
}
}
}
}
}
}
]
}
def call(Closure closure) {
def configurations = [:]
closure.resolveStrategy = Closure.DELEGATE_FIRST
closure.delegate = configurations
closure()
pipeline {
agent any
options {
buildDiscarder(logRotator(numToKeepStr: '25'))
timeout(time: 30, unit: 'MINUTES')
parallelsAlwaysFailFast()
}
stages {
stage("Commit Linting If Enabled") {
when {
expression {
return configurations.commitMessageLintEnabled != null && configurations.commitMessageLintEnabled
}
}
agent {
kubernetes {
defaultContainer 'commit-message-linter'
yaml """
apiVersion: v1
kind: Pod
metadata:
labels:
freeleaps-devops-system/milestone: commit-message-linting
spec:
containers:
- name: commit-message-linter
image: docker.io/commitlint/commitlint:master
command:
- cat
tty: true
volumeMounts:
- name: workspace
mountPath: /workspace
volumes:
- name: workspace
emptyDir: {}
"""
}
}
steps {
script {
log.info("Pipeline","Commit message linting is enabled")
def sourceFetcher = new SourceFetcher(this)
sourceFetcher.fetch(configurations)
def linter = new CommitMessageLinter(this)
linter.lint(configurations)
}
}
}
stage("Execute Mode Detection") {
steps {
script {
def executeMode = configurations.executeMode
if (executeMode == null || executeMode.isEmpty()) {
log.warn("Pipeline","Not set executeMode, using fully as default execute mode")
env.executeMode = "fully"
} else if (executeMode == 'on-demand' && configurations.serviceGitRepoType != 'monorepo') {
log.warn("Pipeline","serviceGirRepoType is not monorepo, on-demand mode is not supported, using fully mode")
env.executeMode = "fully"
} else {
log.info("Pipeline","Using ${executeMode} as execute mode")
env.executeMode = executeMode
}
}
}
}
stage("Code Changes Detection") {
when {
expression {
return env.executeMode == "on-demand"
}
}
steps {
script {
sourceFetcher.fetch(configurations)
def changedComponentsDetector = new ChangedComponentsDetector(this)
def changedComponents = changedComponentsDetector.detect(env.workspace, configurations.components)
log.info("Pipeline","Changed components: ${changedComponents}")
env.changedComponents = changedComponents.join(' ')
}
}
}
stage("Components Build (Dynamic Generated Stages)") {
when {
expression {
return env.executeMode == "fully" || env.changedComponents.size() > 0
}
}
steps {
script {
configurations.components.each { component ->
def generatedStages = generateComponentStages(component, configurations)
generatedStages.each { stage ->
stage(stage)
}
}
}
}
}
}
}
}