public async Task <DeploymentFrequencyModel> GetAzureDevOpsDeploymentFrequency(bool getSampleData, string patToken, TableStorageAuth tableStorageAuth,
                                                                                       string organization, string project, string branch, string buildName,
                                                                                       int numberOfDays, int maxNumberOfItems, bool useCache)
        {
            ListUtility <Build> utility             = new ListUtility <Build>();
            DeploymentFrequency deploymentFrequency = new DeploymentFrequency();

            if (getSampleData == false)
            {
                //Get a list of builds
                BuildsDA buildsDA = new BuildsDA();
                List <AzureDevOpsBuild> azureDevOpsBuilds = await buildsDA.GetAzureDevOpsBuilds(patToken, tableStorageAuth, organization, project, buildName, useCache);

                if (azureDevOpsBuilds != null)
                {
                    //Translate the Azure DevOps build to a generic build object
                    List <Build> builds = new List <Build>();
                    foreach (AzureDevOpsBuild item in azureDevOpsBuilds)
                    {
                        //Only return completed builds on the target branch, within the targeted date range
                        if (item.status == "completed" && item.sourceBranch == branch && item.queueTime > DateTime.Now.AddDays(-numberOfDays))
                        {
                            builds.Add(
                                new Build
                            {
                                Id                   = item.id,
                                Branch               = item.sourceBranch,
                                BuildNumber          = item.buildNumber,
                                StartTime            = item.queueTime,
                                EndTime              = item.finishTime,
                                BuildDurationPercent = item.buildDurationPercent,
                                Status               = item.status,
                                Url                  = item.url
                            }
                                );
                        }
                    }

                    //Get the total builds used in the calculation
                    int buildTotal = builds.Count;

                    //then build the calcuation, loading the dates into a date array
                    List <KeyValuePair <DateTime, DateTime> > dateList = new List <KeyValuePair <DateTime, DateTime> >();
                    foreach (Build item in builds)
                    {
                        KeyValuePair <DateTime, DateTime> newItem = new KeyValuePair <DateTime, DateTime>(item.StartTime, item.EndTime);
                        dateList.Add(newItem);
                    }

                    //then build the calcuation, loading the dates into a date array
                    float deploymentsPerDay;
                    deploymentsPerDay = deploymentFrequency.ProcessDeploymentFrequency(dateList, numberOfDays);

                    //Filter the results to return the last n (maxNumberOfItems), to return to the UI
                    builds = utility.GetLastNItems(builds, maxNumberOfItems);
                    //Find the max build duration
                    float maxBuildDuration = 0f;
                    foreach (Build item in builds)
                    {
                        if (item.BuildDuration > maxBuildDuration)
                        {
                            maxBuildDuration = item.BuildDuration;
                        }
                    }
                    //Calculate the percent scaling
                    foreach (Build item in builds)
                    {
                        float interiumResult = ((item.BuildDuration / maxBuildDuration) * 100f);
                        item.BuildDurationPercent = Scaling.ScaleNumberToRange(interiumResult, 0, 100, 20, 100);
                    }

                    //Return the completed model
                    DeploymentFrequencyModel model = new DeploymentFrequencyModel
                    {
                        TargetDevOpsPlatform               = DevOpsPlatform.AzureDevOps,
                        DeploymentName                     = buildName,
                        BuildList                          = builds,
                        DeploymentsPerDayMetric            = deploymentsPerDay,
                        DeploymentsPerDayMetricDescription = deploymentFrequency.GetDeploymentFrequencyRating(deploymentsPerDay),
                        NumberOfDays                       = numberOfDays,
                        MaxNumberOfItems                   = builds.Count,
                        TotalItems                         = buildTotal
                    };
                    return(model);
                }
                else
                {
                    return(null);
                }
            }
            else
            {
                //Get sample data
                List <Build>             builds = utility.GetLastNItems(GetSampleAzureDevOpsBuilds(), maxNumberOfItems);
                DeploymentFrequencyModel model  = new DeploymentFrequencyModel
                {
                    TargetDevOpsPlatform               = DevOpsPlatform.AzureDevOps,
                    DeploymentName                     = buildName,
                    BuildList                          = builds,
                    DeploymentsPerDayMetric            = 10f,
                    DeploymentsPerDayMetricDescription = "Elite",
                    NumberOfDays                       = numberOfDays,
                    MaxNumberOfItems                   = builds.Count,
                    TotalItems                         = builds.Count
                };
                return(model);
            }
        }
        public async Task <DeploymentFrequencyModel> GetGitHubDeploymentFrequency(bool getSampleData, string clientId, string clientSecret, TableStorageAuth tableStorageAuth,
                                                                                  string owner, string repo, string branch, string workflowName, string workflowId,
                                                                                  int numberOfDays, int maxNumberOfItems, bool useCache)
        {
            ListUtility <Build> utility             = new ListUtility <Build>();
            DeploymentFrequency deploymentFrequency = new DeploymentFrequency();

            if (getSampleData == false)
            {
                //Get a list of builds
                BuildsDA buildsDA = new BuildsDA();
                List <GitHubActionsRun> gitHubRuns = await buildsDA.GetGitHubActionRuns(clientId, clientSecret, tableStorageAuth, owner, repo, workflowName, workflowId, useCache);

                if (gitHubRuns != null)
                {
                    //Translate the GitHub build to a generic build object
                    List <Build> builds = new List <Build>();
                    foreach (GitHubActionsRun item in gitHubRuns)
                    {
                        //Only return completed builds on the target branch, within the targeted date range
                        if (item.status == "completed" && item.head_branch == branch && item.created_at > DateTime.Now.AddDays(-numberOfDays))
                        {
                            builds.Add(
                                new Build
                            {
                                Id                   = item.run_number,
                                Branch               = item.head_branch,
                                BuildNumber          = item.run_number,
                                StartTime            = item.created_at,
                                EndTime              = item.updated_at,
                                BuildDurationPercent = item.buildDurationPercent,
                                Status               = item.status,
                                Url                  = item.html_url
                            }
                                );
                        }
                    }

                    //Get the total builds used in the calculation
                    int buildTotal = builds.Count;

                    //then build the calcuation, loading the dates into a date array
                    List <KeyValuePair <DateTime, DateTime> > dateList = new List <KeyValuePair <DateTime, DateTime> >();
                    foreach (Build item in builds)
                    {
                        KeyValuePair <DateTime, DateTime> newItem = new KeyValuePair <DateTime, DateTime>(item.StartTime, item.EndTime);
                        dateList.Add(newItem);
                    }

                    //then build the calcuation, loading the dates into a date array
                    float deploymentsPerDay;
                    deploymentsPerDay = deploymentFrequency.ProcessDeploymentFrequency(dateList, numberOfDays);

                    //Filter the results to return the last n (maxNumberOfItems), to return to the UI
                    builds = utility.GetLastNItems(builds, maxNumberOfItems);
                    //Find the max build duration
                    float maxBuildDuration = 0f;
                    foreach (Build item in builds)
                    {
                        if (item.BuildDuration > maxBuildDuration)
                        {
                            maxBuildDuration = item.BuildDuration;
                        }
                    }
                    //Calculate the percent scaling
                    foreach (Build item in builds)
                    {
                        float interiumResult = ((item.BuildDuration / maxBuildDuration) * 100f);
                        item.BuildDurationPercent = Scaling.ScaleNumberToRange(interiumResult, 0, 100, 20, 100);
                    }

                    //Return the completed model
                    DeploymentFrequencyModel model = new DeploymentFrequencyModel
                    {
                        TargetDevOpsPlatform               = DevOpsPlatform.GitHub,
                        DeploymentName                     = workflowName,
                        BuildList                          = builds,
                        DeploymentsPerDayMetric            = deploymentsPerDay,
                        DeploymentsPerDayMetricDescription = deploymentFrequency.GetDeploymentFrequencyRating(deploymentsPerDay),
                        NumberOfDays                       = numberOfDays,
                        MaxNumberOfItems                   = builds.Count,
                        TotalItems                         = buildTotal
                    };
                    return(model);
                }
                else
                {
                    return(null);
                }
            }
            else
            {
                List <Build>             builds = utility.GetLastNItems(GetSampleGitHubBuilds(), maxNumberOfItems);
                DeploymentFrequencyModel model  = new DeploymentFrequencyModel
                {
                    TargetDevOpsPlatform               = DevOpsPlatform.GitHub,
                    DeploymentName                     = workflowName,
                    BuildList                          = builds,
                    DeploymentsPerDayMetric            = 10f,
                    DeploymentsPerDayMetricDescription = "Elite",
                    NumberOfDays                       = numberOfDays,
                    MaxNumberOfItems                   = builds.Count,
                    TotalItems                         = builds.Count
                };
                return(model);
            }
        }
예제 #3
0
        public ChangeFailureRateModel GetChangeFailureRate(bool getSampleData, TableStorageAuth tableStorageAuth,
                                                           DevOpsPlatform targetDevOpsPlatform, string organization_owner, string project_repo, string branch, string buildName_workflowName,
                                                           int numberOfDays, int maxNumberOfItems)
        {
            ListUtility <ChangeFailureRateBuild> utility = new ListUtility <ChangeFailureRateBuild>();
            ChangeFailureRate changeFailureRate          = new ChangeFailureRate();

            if (getSampleData == false)
            {
                //Gets a list of change failure rate builds from Azure storage
                AzureTableStorageDA           daTableStorage = new AzureTableStorageDA();
                Newtonsoft.Json.Linq.JArray   list           = daTableStorage.GetTableStorageItems(tableStorageAuth, tableStorageAuth.TableChangeFailureRate, daTableStorage.CreateBuildWorkflowPartitionKey(organization_owner, project_repo, buildName_workflowName));
                List <ChangeFailureRateBuild> initialBuilds  = JsonConvert.DeserializeObject <List <ChangeFailureRateBuild> >(list.ToString());

                //Build the date list and then generate the change failure rate metric
                List <ChangeFailureRateBuild>         builds   = new List <ChangeFailureRateBuild>();
                List <KeyValuePair <DateTime, bool> > dateList = new List <KeyValuePair <DateTime, bool> >();
                float maxBuildDuration = 0f;
                foreach (ChangeFailureRateBuild item in initialBuilds)
                {
                    if (item.Branch == branch && item.StartTime > DateTime.Now.AddDays(-numberOfDays))
                    {
                        //Special branch for Azure DevOps to construct the Url to each build
                        if (targetDevOpsPlatform == DevOpsPlatform.AzureDevOps)
                        {
                            item.Url = $"https://dev.azure.com/{organization_owner}/{project_repo}/_build/results?buildId={item.Id}&view=results";
                        }
                        builds.Add(item);
                    }
                }

                //then build the calcuation
                foreach (ChangeFailureRateBuild item in builds)
                {
                    KeyValuePair <DateTime, bool> newItem = new KeyValuePair <DateTime, bool>(item.StartTime, item.DeploymentWasSuccessful);
                    dateList.Add(newItem);
                }
                //calculate the metric on all of the results
                float changeFailureRateMetric = changeFailureRate.ProcessChangeFailureRate(dateList, numberOfDays);

                //Filter the results to return the last n (maxNumberOfItems)
                List <ChangeFailureRateBuild> uiBuilds = utility.GetLastNItems(builds, maxNumberOfItems);
                foreach (ChangeFailureRateBuild item in uiBuilds)
                {
                    if (item.BuildDuration > maxBuildDuration)
                    {
                        maxBuildDuration = item.BuildDuration;
                    }
                }
                //We need to do some post processing and loop over the list a couple times to find the max build duration, construct a usable url, and calculate a build duration percentage
                foreach (ChangeFailureRateBuild item in uiBuilds)
                {
                    float interiumResult = ((item.BuildDuration / maxBuildDuration) * 100f);
                    item.BuildDurationPercent = Scaling.ScaleNumberToRange(interiumResult, 0, 100, 20, 100);
                }

                ChangeFailureRateModel model = new ChangeFailureRateModel
                {
                    TargetDevOpsPlatform               = targetDevOpsPlatform,
                    DeploymentName                     = buildName_workflowName,
                    ChangeFailureRateBuildList         = uiBuilds,
                    ChangeFailureRateMetric            = changeFailureRateMetric,
                    ChangeFailureRateMetricDescription = changeFailureRate.GetChangeFailureRateRating(changeFailureRateMetric),
                    NumberOfDays     = numberOfDays,
                    MaxNumberOfItems = uiBuilds.Count,
                    TotalItems       = builds.Count
                };
                return(model);
            }
            else
            {
                //Get sample data
                List <ChangeFailureRateBuild> sampleBuilds = utility.GetLastNItems(GetSampleBuilds(), maxNumberOfItems);
                ChangeFailureRateModel        model        = new ChangeFailureRateModel
                {
                    TargetDevOpsPlatform               = targetDevOpsPlatform,
                    DeploymentName                     = buildName_workflowName,
                    ChangeFailureRateBuildList         = sampleBuilds,
                    ChangeFailureRateMetric            = 2f / 10f,
                    ChangeFailureRateMetricDescription = changeFailureRate.GetChangeFailureRateRating(2f / 10f),
                    NumberOfDays     = numberOfDays,
                    MaxNumberOfItems = sampleBuilds.Count,
                    TotalItems       = sampleBuilds.Count
                };
                return(model);
            }
        }
예제 #4
0
        public MeanTimeToRestoreModel GetAzureMeanTimeToRestore(bool getSampleData,
                                                                TableStorageAuth tableStorageAuth,
                                                                DevOpsPlatform targetDevOpsPlatform, string resourceGroup,
                                                                int numberOfDays, int maxNumberOfItems)
        {
            ListUtility <MeanTimeToRestoreEvent> utility = new ListUtility <MeanTimeToRestoreEvent>();

            if (getSampleData == false)
            {
                //Pull the events from the table storage
                AzureTableStorageDA         daTableStorage = new AzureTableStorageDA();
                Newtonsoft.Json.Linq.JArray list           = daTableStorage.GetTableStorageItems(tableStorageAuth, tableStorageAuth.TableMTTR, resourceGroup);
                List <AzureAlert>           alerts         = new List <AzureAlert>();
                foreach (JToken item in list)
                {
                    alerts.Add(
                        new AzureAlert
                    {
                        name = item["data"]["context"]["name"].ToString(),
                        resourceGroupName = item["data"]["context"]["resourceGroupName"].ToString(),
                        resourceName      = item["data"]["context"]["resourceName"].ToString(),
                        status            = item["data"]["status"].ToString(),
                        timestamp         = DateTime.Parse(item["data"]["context"]["timestamp"].ToString())
                    });
                }
                //sort the events by timestamp
                alerts = alerts.OrderBy(o => o.timestamp).ToList();

                //Compile the events,  looking for pairs, using the ordered data, and name, resource group name and resource name
                List <MeanTimeToRestoreEvent> events = new List <MeanTimeToRestoreEvent>();

                //Loop through first finding the activated alerts
                int i = 0;
                List <AzureAlert> startingAlerts = alerts.Where(o => o.status == "Activated").ToList();
                foreach (AzureAlert item in startingAlerts)
                {
                    if (item.timestamp > DateTime.Now.AddDays(-numberOfDays))
                    {
                        i++;
                        MeanTimeToRestoreEvent newEvent = new MeanTimeToRestoreEvent
                        {
                            Name          = item.name,
                            Resource      = item.resourceName,
                            ResourceGroup = item.resourceGroupName,
                            StartTime     = item.timestamp,
                            Status        = "inProgress",
                            ItemOrder     = i
                        };
                        events.Add(newEvent);
                    }
                }

                //Now loop through again, looking for the deactivated matching pair
                float             maxEventDuration = 0;
                List <AzureAlert> endingAlerts     = alerts.Where(o => o.status == "Deactivated").ToList();
                foreach (MeanTimeToRestoreEvent item in events)
                {
                    //Search for the next matching deactivated alert
                    int foundItemIndex = -1;
                    for (int j = 0; j <= endingAlerts.Count - 1; j++)
                    {
                        if (endingAlerts[j].name == item.Name &&
                            endingAlerts[j].resourceName == item.Resource &&
                            endingAlerts[j].resourceGroupName == item.ResourceGroup &&
                            endingAlerts[j].timestamp > item.StartTime)
                        {
                            item.EndTime   = endingAlerts[j].timestamp;
                            item.Status    = "completed";
                            foundItemIndex = j;
                            break;
                        }
                    }
                    if (foundItemIndex >= 0)
                    {
                        //Remove the found item from the list, so we don't use it again.
                        endingAlerts.RemoveAt(foundItemIndex);
                        if (item.MTTRDurationInHours > maxEventDuration)
                        {
                            maxEventDuration = item.MTTRDurationInHours;
                        }
                    }
                }

                //Calculate the MTTR metric
                MeanTimeToRestore mttr        = new MeanTimeToRestore();
                float             averageMTTR = CalculateMTTRDuration(events);

                //Filter and sort the final list (May not be needed due to the initial sort on the starting alerts)
                List <MeanTimeToRestoreEvent> uiEvents = utility.GetLastNItems(events, maxNumberOfItems);
                uiEvents = uiEvents.OrderBy(o => o.StartTime).ToList();

                //Finally, process the percent calculation
                foreach (MeanTimeToRestoreEvent item in uiEvents)
                {
                    float interiumResult = ((item.MTTRDurationInHours / maxEventDuration) * 100f);
                    item.MTTRDurationPercent = Scaling.ScaleNumberToRange(interiumResult, 0, 100, 20, 100);
                }

                //Pull together the results into a single model
                MeanTimeToRestoreModel model = new MeanTimeToRestoreModel
                {
                    TargetDevOpsPlatform           = targetDevOpsPlatform,
                    ResourceGroup                  = resourceGroup,
                    MeanTimeToRestoreEvents        = uiEvents,
                    MTTRAverageDurationInHours     = averageMTTR,
                    MTTRAverageDurationDescription = mttr.GetMeanTimeToRestoreRating(averageMTTR),
                    NumberOfDays     = numberOfDays,
                    MaxNumberOfItems = uiEvents.Count,
                    TotalItems       = events.Count
                };
                return(model);
            }
            else
            {
                //Get sample data
                MeanTimeToRestore             mttr         = new MeanTimeToRestore();
                float                         averageMTTR  = CalculateMTTRDuration(GetSampleMTTREvents(resourceGroup));
                List <MeanTimeToRestoreEvent> sampleEvents = GetSampleMTTREvents(resourceGroup);
                MeanTimeToRestoreModel        model        = new MeanTimeToRestoreModel
                {
                    TargetDevOpsPlatform           = targetDevOpsPlatform,
                    ResourceGroup                  = resourceGroup,
                    MeanTimeToRestoreEvents        = sampleEvents,
                    MTTRAverageDurationInHours     = averageMTTR,
                    MTTRAverageDurationDescription = mttr.GetMeanTimeToRestoreRating(averageMTTR),
                    NumberOfDays     = numberOfDays,
                    MaxNumberOfItems = sampleEvents.Count,
                    TotalItems       = sampleEvents.Count
                };
                return(model);
            }
        }
예제 #5
0
        public async Task <LeadTimeForChangesModel> GetGitHubLeadTimesForChanges(bool getSampleData, string clientId, string clientSecret, TableStorageAuth tableStorageAuth,
                                                                                 string owner, string repo, string mainBranch, string workflowName, string workflowId,
                                                                                 int numberOfDays, int maxNumberOfItems, bool useCache)
        {
            ListUtility <PullRequestModel> utility            = new ListUtility <PullRequestModel>();
            LeadTimeForChanges             leadTimeForChanges = new LeadTimeForChanges();
            List <PullRequestModel>        pullRequests       = new List <PullRequestModel>();

            if (getSampleData == false)
            {
                List <GitHubActionsRun> initialRuns = new List <GitHubActionsRun>();
                BuildsDA buildsDA = new BuildsDA();
                initialRuns = await buildsDA.GetGitHubActionRuns(clientId, clientSecret, tableStorageAuth, owner, repo, workflowName, workflowId, useCache);

                //Process all builds, filtering by main and feature branchs
                List <GitHubActionsRun> mainBranchRuns    = new List <GitHubActionsRun>();
                List <GitHubActionsRun> featureBranchRuns = new List <GitHubActionsRun>();
                List <string>           branches          = new List <string>();
                foreach (GitHubActionsRun item in initialRuns)
                {
                    if (item.status == "completed" && item.created_at > DateTime.Now.AddDays(-numberOfDays))
                    {
                        if (item.head_branch == mainBranch)
                        {
                            //Save the main branch
                            mainBranchRuns.Add(item);
                        }
                        else
                        {
                            //Save the feature branches
                            featureBranchRuns.Add(item);
                            //Record all unique branches
                            if (branches.Contains(item.head_branch) == false)
                            {
                                branches.Add(item.head_branch);
                            }
                        }
                    }
                }

                //Process the lead time for changes
                List <KeyValuePair <DateTime, TimeSpan> > leadTimeForChangesList = new List <KeyValuePair <DateTime, TimeSpan> >();
                foreach (string branch in branches)
                {
                    List <GitHubActionsRun> branchBuilds  = featureBranchRuns.Where(a => a.head_branch == branch).ToList();
                    PullRequestDA           pullRequestDA = new PullRequestDA();
                    GitHubPR pr = await pullRequestDA.GetGitHubPullRequest(clientId, clientSecret, tableStorageAuth, owner, repo, branch, useCache);

                    if (pr != null)
                    {
                        List <GitHubPRCommit> pullRequestCommits = await pullRequestDA.GetGitHubPullRequestCommits(clientId, clientSecret, tableStorageAuth, owner, repo, pr.number, useCache);

                        List <Commit> commits = new List <Commit>();
                        foreach (GitHubPRCommit item in pullRequestCommits)
                        {
                            commits.Add(new Commit
                            {
                                commitId = item.sha,
                                name     = item.commit.committer.name,
                                date     = item.commit.committer.date
                            });
                        }

                        DateTime minTime = DateTime.MaxValue;
                        DateTime maxTime = DateTime.MinValue;
                        foreach (GitHubPRCommit pullRequestCommit in pullRequestCommits)
                        {
                            if (minTime > pullRequestCommit.commit.committer.date)
                            {
                                minTime = pullRequestCommit.commit.committer.date;
                            }
                            if (maxTime < pullRequestCommit.commit.committer.date)
                            {
                                maxTime = pullRequestCommit.commit.committer.date;
                            }
                        }
                        foreach (GitHubActionsRun branchBuild in branchBuilds)
                        {
                            if (minTime > branchBuild.updated_at)
                            {
                                minTime = branchBuild.updated_at;
                            }
                            if (maxTime < branchBuild.updated_at)
                            {
                                maxTime = branchBuild.updated_at;
                            }
                        }

                        PullRequestModel pullRequest = new PullRequestModel
                        {
                            PullRequestId = pr.number,
                            Branch        = branch,
                            BuildCount    = branchBuilds.Count,
                            Commits       = commits,
                            StartDateTime = minTime,
                            EndDateTime   = maxTime,
                            Status        = pr.state,
                            Url           = $"https://github.com/{owner}/{repo}/pull/{pr.number}"
                        };
                        //Convert the pull request status to the standard UI status
                        if (pullRequest.Status == "closed")
                        {
                            pullRequest.Status = "completed";
                        }
                        else if (pullRequest.Status == "open")
                        {
                            pullRequest.Status = "inProgress";
                        }
                        else
                        {
                            pullRequest.Status = pullRequest.Status;
                        }

                        leadTimeForChangesList.Add(new KeyValuePair <DateTime, TimeSpan>(minTime, pullRequest.Duration));
                        pullRequests.Add(pullRequest);
                    }
                }

                //Calculate the lead time for changes value, in hours
                float leadTime = leadTimeForChanges.ProcessLeadTimeForChanges(leadTimeForChangesList, numberOfDays);

                List <PullRequestModel> uiPullRequests = utility.GetLastNItems(pullRequests, maxNumberOfItems);
                float maxPullRequestDuration           = 0f;
                foreach (PullRequestModel item in uiPullRequests)
                {
                    if (item.Duration.TotalMinutes > maxPullRequestDuration)
                    {
                        maxPullRequestDuration = (float)item.Duration.TotalMinutes;
                    }
                }
                foreach (PullRequestModel item in uiPullRequests)
                {
                    float interiumResult = (((float)item.Duration.TotalMinutes / maxPullRequestDuration) * 100f);
                    item.DurationPercent = Scaling.ScaleNumberToRange(interiumResult, 0, 100, 20, 100);
                }
                double totalHours = 0;
                foreach (GitHubActionsRun item in mainBranchRuns)
                {
                    totalHours += (item.updated_at - item.created_at).TotalHours;
                }
                float averageBuildHours = 0;
                if (mainBranchRuns.Count > 0)
                {
                    averageBuildHours = (float)totalHours / (float)mainBranchRuns.Count;
                }

                LeadTimeForChangesModel model = new LeadTimeForChangesModel
                {
                    ProjectName                         = repo,
                    TargetDevOpsPlatform                = DevOpsPlatform.GitHub,
                    AverageBuildHours                   = averageBuildHours,
                    AveragePullRequestHours             = leadTime,
                    LeadTimeForChangesMetric            = leadTime + averageBuildHours,
                    LeadTimeForChangesMetricDescription = leadTimeForChanges.GetLeadTimeForChangesRating(leadTime),
                    PullRequests                        = utility.GetLastNItems(pullRequests, maxNumberOfItems),
                    NumberOfDays                        = numberOfDays,
                    MaxNumberOfItems                    = uiPullRequests.Count,
                    TotalItems = pullRequests.Count
                };

                return(model);
            }
            else
            {
                List <PullRequestModel> samplePullRequests = utility.GetLastNItems(CreatePullRequestsSample(DevOpsPlatform.GitHub), maxNumberOfItems);
                LeadTimeForChangesModel model = new LeadTimeForChangesModel
                {
                    ProjectName                         = repo,
                    TargetDevOpsPlatform                = DevOpsPlatform.GitHub,
                    AverageBuildHours                   = 1f,
                    AveragePullRequestHours             = 20.33f,
                    LeadTimeForChangesMetric            = 20.33f + 1f,
                    LeadTimeForChangesMetricDescription = "Elite",
                    PullRequests                        = samplePullRequests,
                    NumberOfDays                        = numberOfDays,
                    MaxNumberOfItems                    = samplePullRequests.Count,
                    TotalItems = samplePullRequests.Count
                };

                return(model);
            }
        }
예제 #6
0
        public async Task <LeadTimeForChangesModel> GetAzureDevOpsLeadTimesForChanges(bool getSampleData, string patToken, TableStorageAuth tableStorageAuth,
                                                                                      string organization, string project, string repositoryId, string mainBranch, string buildName, int numberOfDays, int maxNumberOfItems, bool useCache)
        {
            ListUtility <PullRequestModel> utility            = new ListUtility <PullRequestModel>();
            LeadTimeForChanges             leadTimeForChanges = new LeadTimeForChanges();
            List <PullRequestModel>        pullRequests       = new List <PullRequestModel>();

            if (getSampleData == false)
            {
                List <AzureDevOpsBuild> initialBuilds = new List <AzureDevOpsBuild>();
                BuildsDA buildsDA = new BuildsDA();
                initialBuilds = await buildsDA.GetAzureDevOpsBuilds(patToken, tableStorageAuth, organization, project, buildName, useCache);

                //Process all builds, filtering by main and feature branchs
                List <AzureDevOpsBuild> mainBranchBuilds    = new List <AzureDevOpsBuild>();
                List <AzureDevOpsBuild> featureBranchBuilds = new List <AzureDevOpsBuild>();
                List <string>           branches            = new List <string>();
                foreach (AzureDevOpsBuild item in initialBuilds)
                {
                    if (item.status == "completed" && item.queueTime > DateTime.Now.AddDays(-numberOfDays))
                    {
                        if (item.sourceBranch == mainBranch)
                        {
                            //Save the main branch
                            mainBranchBuilds.Add(item);
                        }
                        else
                        {
                            //Save the feature branches
                            featureBranchBuilds.Add(item);
                            //Record all unique branches
                            if (branches.Contains(item.branch) == false)
                            {
                                branches.Add(item.branch);
                            }
                        }
                    }
                }

                //Process the lead time for changes
                List <KeyValuePair <DateTime, TimeSpan> > leadTimeForChangesList = new List <KeyValuePair <DateTime, TimeSpan> >();
                foreach (string branch in branches)
                {
                    List <AzureDevOpsBuild> branchBuilds  = featureBranchBuilds.Where(a => a.sourceBranch == branch).ToList();
                    PullRequestDA           pullRequestDA = new PullRequestDA();
                    AzureDevOpsPR           pr            = await pullRequestDA.GetAzureDevOpsPullRequest(patToken, tableStorageAuth, organization, project, repositoryId, branch, useCache);

                    if (pr != null)
                    {
                        List <AzureDevOpsPRCommit> pullRequestCommits = await pullRequestDA.GetAzureDevOpsPullRequestCommits(patToken, tableStorageAuth, organization, project, repositoryId, pr.PullRequestId, useCache);

                        List <Commit> commits = new List <Commit>();
                        foreach (AzureDevOpsPRCommit item in pullRequestCommits)
                        {
                            commits.Add(new Commit
                            {
                                commitId = item.commitId,
                                name     = item.committer.name,
                                date     = item.committer.date
                            });
                        }

                        DateTime minTime = DateTime.MaxValue;
                        DateTime maxTime = DateTime.MinValue;
                        foreach (AzureDevOpsPRCommit pullRequestCommit in pullRequestCommits)
                        {
                            if (minTime > pullRequestCommit.committer.date)
                            {
                                minTime = pullRequestCommit.committer.date;
                            }
                            if (maxTime < pullRequestCommit.committer.date)
                            {
                                maxTime = pullRequestCommit.committer.date;
                            }
                        }
                        foreach (AzureDevOpsBuild branchBuild in branchBuilds)
                        {
                            if (minTime > branchBuild.finishTime)
                            {
                                minTime = branchBuild.finishTime;
                            }
                            if (maxTime < branchBuild.finishTime)
                            {
                                maxTime = branchBuild.finishTime;
                            }
                        }
                        PullRequestModel pullRequest = new PullRequestModel
                        {
                            PullRequestId = pr.PullRequestId,
                            Branch        = branch,
                            BuildCount    = branchBuilds.Count,
                            Commits       = commits,
                            StartDateTime = minTime,
                            EndDateTime   = maxTime,
                            Status        = pr.status,
                            Url           = $"https://dev.azure.com/{organization}/{project}/_git/{repositoryId}/pullrequest/{pr.PullRequestId}"
                        };

                        leadTimeForChangesList.Add(new KeyValuePair <DateTime, TimeSpan>(minTime, pullRequest.Duration));
                        pullRequests.Add(pullRequest);
                    }
                }

                //Calculate the lead time for changes value, in hours
                float leadTime = leadTimeForChanges.ProcessLeadTimeForChanges(leadTimeForChangesList, numberOfDays);

                List <PullRequestModel> uiPullRequests = utility.GetLastNItems(pullRequests, maxNumberOfItems);
                float maxPullRequestDuration           = 0f;
                foreach (PullRequestModel item in uiPullRequests)
                {
                    if (item.Duration.TotalMinutes > maxPullRequestDuration)
                    {
                        maxPullRequestDuration = (float)item.Duration.TotalMinutes;
                    }
                }
                foreach (PullRequestModel item in uiPullRequests)
                {
                    float interiumResult = (((float)item.Duration.TotalMinutes / maxPullRequestDuration) * 100f);
                    item.DurationPercent = Scaling.ScaleNumberToRange(interiumResult, 0, 100, 20, 100);
                }
                double totalHours = 0;
                foreach (AzureDevOpsBuild item in mainBranchBuilds)
                {
                    totalHours += (item.finishTime - item.queueTime).TotalHours;
                }
                float averageBuildHours = 0;
                if (mainBranchBuilds.Count > 0)
                {
                    averageBuildHours = (float)totalHours / (float)mainBranchBuilds.Count;
                }

                LeadTimeForChangesModel model = new LeadTimeForChangesModel
                {
                    ProjectName                         = project,
                    TargetDevOpsPlatform                = DevOpsPlatform.AzureDevOps,
                    AverageBuildHours                   = averageBuildHours,
                    AveragePullRequestHours             = leadTime,
                    LeadTimeForChangesMetric            = leadTime + averageBuildHours,
                    LeadTimeForChangesMetricDescription = leadTimeForChanges.GetLeadTimeForChangesRating(leadTime),
                    PullRequests                        = uiPullRequests,
                    NumberOfDays                        = numberOfDays,
                    MaxNumberOfItems                    = uiPullRequests.Count,
                    TotalItems = pullRequests.Count
                };

                return(model);
            }
            else
            {
                //Get sample data
                List <PullRequestModel> samplePullRequests = utility.GetLastNItems(CreatePullRequestsSample(DevOpsPlatform.AzureDevOps), maxNumberOfItems);
                LeadTimeForChangesModel model = new LeadTimeForChangesModel
                {
                    ProjectName                         = project,
                    TargetDevOpsPlatform                = DevOpsPlatform.AzureDevOps,
                    AverageBuildHours                   = 1f,
                    AveragePullRequestHours             = 12f,
                    LeadTimeForChangesMetric            = 12f + 1f,
                    LeadTimeForChangesMetricDescription = "Elite",
                    PullRequests                        = samplePullRequests,
                    NumberOfDays                        = numberOfDays,
                    MaxNumberOfItems                    = samplePullRequests.Count,
                    TotalItems = samplePullRequests.Count
                };

                return(model);
            }
        }