@VisibleForTesting
  void buildImages(ProgressEventDispatcher.Factory progressDispatcherFactory) {
    results.baseImagesAndBuiltImages =
        executorService.submit(
            () -> {
              try (ProgressEventDispatcher progressDispatcher =
                  progressDispatcherFactory.create(
                      "scheduling building manifests", results.baseImagesAndLayers.get().size())) {

                Map<Image, Future<Image>> baseImagesAndBuiltImages = new LinkedHashMap<>();
                for (Map.Entry<Image, List<Future<PreparedLayer>>> entry :
                    results.baseImagesAndLayers.get().entrySet()) {
                  Image baseImage = entry.getKey();
                  List<Future<PreparedLayer>> baseLayers = entry.getValue();

                  Future<Image> builtImage =
                      buildImage(baseImage, baseLayers, progressDispatcher.newChildProducer());
                  baseImagesAndBuiltImages.put(baseImage, builtImage);
                }
                return baseImagesAndBuiltImages;
              }
            });
  }
Run all steps and return a BuildResult after a build is completed.

@return a {@link BuildResult} with build metadata
@throws ExecutionException if an error occurred during asynchronous execution of steps
@throws InterruptedException if the build was interrupted while waiting for results
jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/StepsRunner.java