Beispiel #1
0
        public BuildReport Run()
        {
            BuildReport report         = new BuildReport();
            Project     projectToBuild = projectRegistry.GetProject(projectId);

            Log(Level.Info, "Starting the build runner");
            lock (this)
            {
                // construct a graph of build stages
                foreach (BuildStage stage in projectToBuild.BuildStages)
                {
                    BuildDependencyGraph(stage);
                }

                Log(Level.Debug, "Constructed build stages dependency graph");
            }

            while (true)
            {
                Log(Level.Debug, "New cycle started");

                lock (this)
                {
                    // retrieve the fresh info about stage statuses
                    foreach (BuildStage stage in stagesOrdered)
                    {
                        StageStatus status = GetStageStatus(stage);

                        if (status.Outcome == BuildOutcome.InProgress)
                        {
                            status.StageRunner.UpdateStatus(status);
                        }

                        Log(Level.Info, "Build stage '{0}' status: {1}", status.Stage.StageId, status.Outcome);
                    }
                }

                // check if the traffic buildTrafficSignals has signalled the runner to stop
                BuildTrafficCopSignal signal = buildTrafficSignals.WaitForControlSignal(TimeSpan.Zero);
                if (signal == BuildTrafficCopSignal.Stop)
                {
                    break;
                }

                bool stagesPending = false;

                lock (this)
                {
                    // check if any of the stages can be started
                    foreach (BuildStage stage in stagesOrdered)
                    {
                        StageStatus status = stagesStatuses[stage.StageId];
                        if (status.Outcome == BuildOutcome.Initial)
                        {
                            bool someDependenciesFailed    = false;
                            bool allDependenciesSuccessful = true;

                            // check dependecy stages
                            foreach (BuildStage dependency in stage.DependsOn)
                            {
                                StageStatus dependencyStatus = GetStageStatus(dependency);

                                if (dependencyStatus.Outcome == BuildOutcome.Failed)
                                {
                                    // this stage will not be executed, so go to the next one
                                    someDependenciesFailed    = true;
                                    allDependenciesSuccessful = false;
                                    break;
                                }
                                else if (dependencyStatus.Outcome == BuildOutcome.Successful)
                                {
                                    continue;
                                }

                                allDependenciesSuccessful = false;
                            }

                            if (someDependenciesFailed)
                            {
                                status.MarkAsNotExecuted();
                            }
                            else if (allDependenciesSuccessful)
                            {
                                // we can start this stage
                                Log(Level.Info, "Starting stage '{0}'", status.Stage.StageId);

                                IStageRunner stageRunner = this.buildStageRunnerFactory.CreateStageRunner(status.Stage);
                                status.PrepareToStart(stageRunner);
                                stageRunner.StartStage();
                                // update the status immediatelly
                                stageRunner.UpdateStatus(status);

                                stagesPending = true;
                            }
                            else
                            {
                                stagesPending = true;
                            }
                        }
                    }
                }

                if (stagesPending)
                {
                    Log(Level.Debug, "Some build stages are still pending");
                }
                else
                {
                    Log(Level.Debug, "The build has been executed");
                    break;
                }

                Log(Level.Debug, "Waiting for the traffic cop");

                // check if the traffic buildTrafficSignals has signalled the runner to stop
                signal = buildTrafficSignals.WaitForControlSignal(pollPeriod);
                if (signal == BuildTrafficCopSignal.Stop)
                {
                    break;
                }
            }

            Log(Level.Info, "Stopping the build runner");

            foreach (BuildStage stage in stagesOrdered)
            {
                BuildStageReport stageReport = new BuildStageReport();
                stageReport.StageOutcome = GetStageStatus(stage).Outcome;
                report.StageReports.Add(stage.StageId, stageReport);
            }

            return(report);
        }