@Override
 public Result runBuild(DynamicBuild build, BuildExecutionContext buildExecutionContext, Launcher launcher, BuildListener listener) throws IOException, InterruptedException {
     Map<String,Object> buildEnvironment = build.getEnvironmentWithChangeSet(listener);
     ShellCommands checkoutCommands = getCheckoutCommands(buildEnvironment);
     Map config = new GroovyYamlTemplateProcessor(getDotCiYml(build), buildEnvironment).getConfig();
     this.buildConfiguration = getBuildConfiguration(build.getParent().getFullName(),config,build.getBuildId(),checkoutCommands,build.getSha(),build.getNumber());
     build.setAxisList(buildConfiguration.getAxisList());
     Result result ;
     if(buildConfiguration.isParallelized()){
         ShellScriptRunner shellScriptRunner = new ShellScriptRunner(buildExecutionContext, listener);
         Result checkoutResult = shellScriptRunner.runScript(checkoutCommands);
         if(Result.FAILURE.equals(checkoutResult)) return checkoutResult;
         result = runMultiConfigbuildRunner(build, buildConfiguration, listener,launcher);
     }else{
         result = runSubBuild(new Combination(ImmutableMap.of("script", buildConfiguration.getOnlyRun())), buildExecutionContext, listener);
     }
     Result pluginResult = runPlugins(build, buildConfiguration.getPlugins(), listener, launcher);
     Result notifierResult = runNotifiers(build, buildConfiguration.getNotifiers(), listener);
     return  result.combine(pluginResult).combine(notifierResult);
 }
 @Override
 public Result runSubBuild(Combination combination, BuildExecutionContext buildExecutionContext, BuildListener listener) throws IOException, InterruptedException {
     ShellScriptRunner shellScriptRunner = new ShellScriptRunner(buildExecutionContext, listener);
     return shellScriptRunner.runScript(buildConfiguration.getCommands(combination));
 }