run method

Runs the stages in order and returns the outcome

When a step fails, the FailurePolicy of its stage decides whether the rest of the run is skipped

Implementation

Future<PipeRunResult> run(PipeRunInfo info, List<PipeStage> stages) async {
  List<StepState> states = [];
  for (PipeStage stage in stages) {
    for (int i = 0; i < stage.steps.length; i++) {
      states.add(_createState(stage.steps[i], stage, null, "${states.length + 1}", i == stage.steps.length - 1));
    }
  }

  _steps = states;
  Stopwatch stopwatch = Stopwatch()..start();
  _emit(RunStarted(info: info, steps: states, startedAt: DateTime.now()));

  // Set once a failed step of a stage has stopped the run
  String? stopReason;
  for (StepState state in states) {
    String? skipReason = _skipReason(state, stopReason);
    if (skipReason != null) {
      _skip(state, skipReason);
      continue;
    }

    await _runStep(state);
    if (state.status == StepStatus.failed && state.stage.onFailure == FailurePolicy.stopRun) {
      stopReason ??= "an earlier step has failed";
    }
  }

  PipeRunResult result = PipeRunResult(steps: states, elapsed: stopwatch.elapsed);
  _emit(RunFinished(result));
  for (PipeReporter reporter in reporters) {
    await reporter.close();
  }
  return result;
}