@@ -1038,10 +1038,10 @@ def runAgent(image, config, branchName=null, axis=null, Closure func, runInDocke
10381038}
10391039
10401040
1041- Map getTasks (axes , image , config , include , exclude ) {
1041+ Map getTasks (axes , image , config , include , exclude , stageName = null ) {
10421042
10431043
1044- config. logger. trace(3 , " getTasks() --> image=" + image)
1044+ config. logger. trace(3 , " getTasks() --> image=" + image + " stage= " + stageName )
10451045
10461046 int serialNum = 1
10471047 Map tasks = [:]
@@ -1067,7 +1067,8 @@ Map getTasks(axes, image, config, include, exclude) {
10671067 continue
10681068 }
10691069
1070- if (! config. steps) {
1070+ def stepsToCheck = stageName ? getStepsForStage(config, stageName) : config. steps
1071+ if (! stepsToCheck) {
10711072 continue
10721073 }
10731074
@@ -1081,8 +1082,8 @@ Map getTasks(axes, image, config, include, exclude) {
10811082 def branchName = resolveTemplate(axis, tmpl, config)
10821083
10831084 def canSkip = true
1084- for (int j = 0 ; j < config . steps . size(); j++ ) {
1085- def oneStep = config . steps [j]
1085+ for (int j = 0 ; j < stepsToCheck . size(); j++ ) {
1086+ def oneStep = stepsToCheck [j]
10861087 if (! check_skip_stage(image, config, branchName, oneStep, axis)) {
10871088 canSkip = false
10881089 break
@@ -1106,6 +1107,7 @@ Map getTasks(axes, image, config, include, exclude) {
11061107 }
11071108
11081109 config. logger. trace(5 , " task name " + branchName)
1110+ def taskSteps = stageName ? getStepsForStage(config, stageName) : config. steps
11091111 tasks[branchName] = { ->
11101112 withEnv(axisEnv) {
11111113 if ((config. get(" kubernetes" ) == null ) &&
@@ -1120,11 +1122,11 @@ Map getTasks(axes, image, config, include, exclude) {
11201122 runBareMetal = false
11211123 }
11221124 def callback = {pimage , pconfig , pname , paxis , pruntime ->
1123- runSteps(pimage, pconfig, pname, paxis, pruntime)
1125+ runSteps(pimage, pconfig, pname, paxis, taskSteps, pruntime)
11241126 }
11251127 runAgent(image, config, branchName, axis, callback, runBareMetal)
11261128 } else {
1127- runK8(image, branchName, config, axis)
1129+ runK8(image, branchName, config, axis, taskSteps )
11281130 }
11291131 }
11301132 }
@@ -1154,10 +1156,31 @@ def resolveIncludeExcludeTemplates(filters, config) {
11541156 return resolvedFilters
11551157}
11561158
1157- def getMatrixTasks (image , config ) {
1159+ @NonCPS
1160+ def getUniqueStages (config ) {
1161+ // generate a uniq list of stages from the steps, if no stage is defined, add a default stage
1162+ def stages = config. steps. collect { it. stage ?: " default" }. unique()
1163+ return stages
1164+ }
1165+
1166+ def getStepsForStage (config , stageName ) {
1167+ // generate a list of steps for a given stage
1168+ def stageSteps = []
1169+ if (config. steps) {
1170+ for (step in config. steps) {
1171+ def stepStage = step. get(" stage" , " default" )
1172+ if (stepStage == stageName) {
1173+ stageSteps. add(step)
1174+ }
1175+ }
1176+ }
1177+ return stageSteps
1178+ }
1179+
1180+ def getMatrixTasks (image , config , stageName = null ) {
11581181
11591182 def include = [], exclude = [], axes = []
1160- config. logger. debug(" getMatrixTasks() --> image=" + image)
1183+ config. logger. debug(" getMatrixTasks() --> image=" + image + " stage= " + stageName )
11611184
11621185 if (config. get(" matrix" )) {
11631186 axes = getMatrixAxes(config. matrix. axes). findAll()
@@ -1177,7 +1200,7 @@ def getMatrixTasks(image, config) {
11771200 exclude. size() +
11781201 " ] = " + exclude
11791202 )
1180- return getTasks(axes, image, config, include, exclude)
1203+ return getTasks(axes, image, config, include, exclude, stageName )
11811204}
11821205
11831206def buildImage (img , filename , extra_args , config , image ) {
@@ -1503,7 +1526,7 @@ spec:
15031526 }
15041527}
15051528
1506- def run_parallel_in_chunks (config , myTasks , depth ) {
1529+ def run_parallel_in_chunks (config , myTasks , depth , stageName = null ) {
15071530
15081531 if (myTasks. size() == 0 ) {
15091532 return
@@ -1518,11 +1541,22 @@ def run_parallel_in_chunks(config, myTasks, depth) {
15181541 def val = getConfigVal(config, [' failFast' ], false )
15191542
15201543 config. logger. trace(3 , " run_parallel_in_chunks: batch size is ${ bSize} " )
1521- (myTasks. keySet() as List ). collate(bSize). each {
1522- def batchMap = myTasks. subMap(it)
1523- batchMap[' failFast' ] = val
1524- parallel batchMap
1544+ if (stageName) {
1545+ stage(stageName) {
1546+ (myTasks. keySet() as List ). collate(bSize). each {
1547+ def batchMap = myTasks. subMap(it)
1548+ batchMap[' failFast' ] = val
1549+ parallel batchMap
1550+ }
1551+ }
1552+ } else {
1553+ (myTasks. keySet() as List ). collate(bSize). each {
1554+ def batchMap = myTasks. subMap(it)
1555+ batchMap[' failFast' ] = val
1556+ parallel batchMap
1557+ }
15251558 }
1559+
15261560}
15271561
15281562
@@ -1689,7 +1723,45 @@ def startPipeline(String label) {
16891723 run_step(null , config, " pipeline start" , config. pipeline_start, null )
16901724 }
16911725 }
1692- run_parallel_in_chunks(config, branches, bSize)
1726+
1727+ def stage_arch_distro_map = gen_image_map(config)
1728+ // Get unique stages and execute sequentially
1729+ def stages = getUniqueStages(config)
1730+ if (stages. size() > 1 ) {
1731+ config. logger. debug(" Unique stages identified: " + stages)
1732+ for (stageName in stages) {
1733+ config. logger. info(" Starting stage: ${ stageName} " )
1734+
1735+ def stageBranches = [:]
1736+
1737+ for (def entry in entrySet(stage_arch_distro_map)) {
1738+ def images = entry. value
1739+ for (int j= 0 ; j< images. size(); j++ ) {
1740+ def image = images[j]
1741+ stageBranches + = getMatrixTasks(image, config, stageName)
1742+ }
1743+ }
1744+
1745+ if (config. runs_on_agents) {
1746+ for (int a= 0 ; a< config. runs_on_agents. size();a++ ) {
1747+ def image = config. runs_on_agents[a]
1748+ image. name = image. nodeLabel
1749+ image. arch = ' x86_64'
1750+ stageBranches + = getMatrixTasks(image, config, stageName)
1751+ }
1752+ }
1753+
1754+ // Run all tasks for this stage in parallel
1755+ if (stageBranches. size() > 0 ) {
1756+ run_parallel_in_chunks(config, stageBranches, bSize,stageName)
1757+ }
1758+
1759+ config. logger. info(" Completed stage: ${ stageName} " )
1760+ }
1761+ } else {
1762+ // Fallback if no stages defined
1763+ run_parallel_in_chunks(config, branches, bSize)
1764+ }
16931765 }
16941766 }
16951767 config. env. pipeline_status = ' SUCCESS'
0 commit comments