#!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") { steps { 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 -> generateComponentStages(component) } } } } } } }