/// <summary>
        /// Get the <see cref="BuildStepResult"/> for the specified <see cref="IBuildStep"/>.
        /// </summary>
        /// <param name="buildStep">The build step to search for the result.</param>
        /// <param name="value">The <see cref="BuildStepResult"/> if found, otherwise default(<see cref="BuildStepResult"/>)</param>
        /// <returns><see langword="true"/> if the IBuildStep was found, otherwise <see langword="false"/>.</returns>
        public bool TryGetBuildStepResult(IBuildStep buildStep, out BuildStepResult value)
        {
            foreach (var result in BuildStepsResults)
            {
                if (result.BuildStep == buildStep)
                {
                    value = result;
                    return(true);
                }
            }

            value = default;
            return(false);
        }
 /// <summary>
 /// Construct <see cref="BuildStepResult"/> from this <see cref="BuildStep"/> that represent a failed execution.
 /// </summary>
 /// <param name="message">Message that explain why the <see cref="BuildStep"/> execution failed.</param>
 /// <returns>A new <see cref="BuildStepResult"/> instance.</returns>
 public BuildStepResult Failure(string message) => BuildStepResult.Failure(this, message);
 /// <summary>
 /// Construct <see cref="BuildStepResult"/> from this <see cref="BuildStep"/> that represent a successful execution.
 /// </summary>
 /// <returns>A new <see cref="BuildStepResult"/> instance.</returns>
 public BuildStepResult Success() => BuildStepResult.Success(this);
示例#4
0
        BuildPipelineResult RunBuildSteps(BuildContext context)
        {
            var timer  = new Stopwatch();
            var status = context.BuildPipelineStatus;
            var title  = context.BuildProgress?.Title ?? string.Empty;

            // Setup build steps list
            var cleanupSteps = new Stack <BuildStep>();
            var enabledSteps = EnumerateBuildSteps().Where(step => step.IsEnabled(context)).ToArray();

            // Run build steps and stop on first failure of any kind
            for (var i = 0; i < enabledSteps.Length; ++i)
            {
                var step = enabledSteps[i];

                // Update build progress
                var cancelled = context.BuildProgress?.Update($"{title} (Step {i + 1} of {enabledSteps.Length})", step.Description + "...", (float)i / enabledSteps.Length) ?? false;
                if (cancelled)
                {
                    status.Succeeded = false;
                    status.Message   = $"{title} was cancelled.";
                    break;
                }

                // Add step to cleanup stack only if it overrides implementation
                if (step.GetType().GetMethod(nameof(BuildStep.CleanupBuildStep)).DeclaringType != typeof(BuildStep))
                {
                    cleanupSteps.Push(step);
                }

                // Run build step
                try
                {
                    timer.Restart();
                    var result = step.RunBuildStep(context);
                    timer.Stop();

                    // Update build step duration
                    result.Duration = timer.Elapsed;

                    // Add build step result to pipeline status
                    status.BuildStepsResults.Add(result);

                    // Stop execution for normal build steps after failure
                    if (!result.Succeeded)
                    {
                        break;
                    }
                }
                catch (Exception exception)
                {
                    // Add build step exception to pipeline status, and stop executing build steps
                    status.BuildStepsResults.Add(BuildStepResult.Exception(step, exception));
                    break;
                }
            }

            // Execute cleanup even if there are failures in build steps.
            // * In opposite order of build steps that ran
            // * Can't be cancelled; cleanup step must run
            foreach (var step in cleanupSteps)
            {
                // Update build progress
                context.BuildProgress?.Update($"{title} (Cleanup)", step.Description + "...", 1.0F);

                // Run cleanup step
                try
                {
                    timer.Restart();
                    var result = step.CleanupBuildStep(context);
                    timer.Stop();

                    // Update cleanup step duration
                    result.Duration = timer.Elapsed;

                    // Add cleanup step result to pipeline status
                    status.BuildStepsResults.Add(result);
                }
                catch (Exception exception)
                {
                    // Add cleanup step exception to pipeline status (not stopping execution)
                    status.BuildStepsResults.Add(BuildStepResult.Exception(step, exception));
                }
            }

            return(status);
        }
示例#5
0
        static void RunBuildSteps(BuildContext context, IReadOnlyCollection <IBuildStep> steps)
        {
            var timer  = new Stopwatch();
            var status = context.BuildPipelineStatus;
            var title  = context.BuildProgress?.Title ?? string.Empty;

            // Setup build step actions to perform
            var cleanupSteps = new Stack <IBuildStep>();
            var enabledSteps = steps.Where(step => step.IsEnabled(context)).ToArray();

            // Execute build step actions (Stop executing on first failure - of any kind)
            for (var i = 0; i < enabledSteps.Length; ++i)
            {
                var step = enabledSteps[i];

                var cancelled = context.BuildProgress?.Update($"{title} (Step {i + 1} of {enabledSteps.Length})", step.Description + "...", (float)i / enabledSteps.Length) ?? false;
                if (cancelled)
                {
                    status.Succeeded = false;
                    status.Message   = $"{title} was cancelled.";
                    break;
                }

                cleanupSteps.Push(step);

                try
                {
                    timer.Restart();
                    var result = step.RunStep(context);
                    timer.Stop();

                    result.Duration = timer.Elapsed;

                    status.BuildStepsResults.Add(result);

                    // Stop execution for normal build  steps after failure
                    if (!result.Succeeded)
                    {
                        break;
                    }
                }
                catch (Exception exception)
                {
                    // Stop execution for normal build steps after failure
                    status.BuildStepsResults.Add(BuildStepResult.Exception(step, exception));
                    break;
                }
            }

            // Execute Cleanup (Even if there are failures)
            // * In opposite order of the run steps (Only run the cleanup steps, for steps that ran)
            // * can't be cancelled, cleanup must always run
            foreach (var step in cleanupSteps)
            {
                context.BuildProgress?.Update($"{title} (Cleanup)", step.Description + "...", 1.0F);

                try
                {
                    timer.Restart();
                    var result = step.CleanupStep(context);
                    timer.Stop();

                    result.Duration = timer.Elapsed;

                    // All clean steps must run even if there are failures
                    status.BuildStepsResults.Add(result);
                }
                catch (Exception exception)
                {
                    // All clean steps must run even if there are failures
                    status.BuildStepsResults.Add(BuildStepResult.Exception(step, exception));
                }
            }
        }
示例#6
0
 public BuildStepResult CleanupStep(BuildContext context) => BuildStepResult.Success(this);
 /// <summary>
 /// Construct <see cref="BuildStepResult"/> from this <see cref="IBuildStep"/> that represent an exception during execution.
 /// </summary>
 /// <param name="exception">The exception.</param>
 /// <returns>A new <see cref="BuildStepResult"/> instance.</returns>
 public BuildStepResult Exception(Exception exception) => BuildStepResult.Exception(this, exception);