#!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) { return [ stage("${component.name} :: Build Agent Setup") { podTemplate( label: "build-agent-${component.name}", containers: [ containerTemplate( name: 'build-agent', image: component.buildAgentImage ?: 'python:3.10-slim-buster', ttyEnabled: true, command: 'cat' ) ] ) { node("build-agent-${component.name}") { steps { script { if (env.executeMode == "fully" || env.changedComponents.contains(component.name)) { def buildAgentImage = component.buildAgentImage ?: "python:3.10-slim-buster" 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}") { steps { script { 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 generateComponentStages(component) { // 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") { // agent { // kubernetes { // defaultContainer 'dep-resolver' // yaml """ // apiVersion: v1 // kind: Pod // metadata: // labels: // freeleaps-devops-system/milestone: dependencies-resolving // spec: // containers: // - name: dep-resolver // image: ${env.buildAgentImage} // command: // - sleep // args: // - infinity // """ // } // } // steps { // script { // if (env.executeMode == "fully" || env.changedComponents.contains(component.name)) { // log.info("Pipeline", "Build Agent sets to: ${env.buildAgentImage}") // 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) generatedStages.each { stage -> stage(stage) } } } } } } } }