public async Task <List <GitHubActionsRun> > GetGitHubActionRuns(string clientId, string clientSecret, TableStorageConfiguration tableStorageConfig, string owner, string repo, string workflowName, string workflowId, bool useCache) { List <GitHubActionsRun> runs = new List <GitHubActionsRun>(); Newtonsoft.Json.Linq.JArray list = null; if (useCache == true) { //Get the builds from Azure storage AzureTableStorageDA daTableStorage = new AzureTableStorageDA(); list = daTableStorage.GetTableStorageItemsFromStorage(tableStorageConfig, tableStorageConfig.TableGitHubRuns, PartitionKeys.CreateBuildWorkflowPartitionKey(owner, repo, workflowName)); } else { //Get the builds from the GitHub API GitHubAPIAccess api = new GitHubAPIAccess(); list = await api.GetGitHubActionRunsJArray(clientId, clientSecret, owner, repo, workflowId); } if (list != null) { runs = JsonConvert.DeserializeObject <List <GitHubActionsRun> >(list.ToString()); //sort the final list runs = runs.OrderBy(o => o.created_at).ToList(); } return(runs); }
public async Task <List <AzureDevOpsBuild> > GetAzureDevOpsBuilds(string patToken, TableStorageConfiguration tableStorageConfig, string organization, string project, string buildName, bool useCache) { List <AzureDevOpsBuild> builds = new List <AzureDevOpsBuild>(); Newtonsoft.Json.Linq.JArray list = null; if (useCache == true) { //Get the builds from Azure storage AzureTableStorageDA daTableStorage = new AzureTableStorageDA(); list = daTableStorage.GetTableStorageItemsFromStorage(tableStorageConfig, tableStorageConfig.TableAzureDevOpsBuilds, PartitionKeys.CreateBuildWorkflowPartitionKey(organization, project, buildName)); } else { //Get the builds from the Azure DevOps API AzureDevOpsAPIAccess api = new AzureDevOpsAPIAccess(); list = await api.GetAzureDevOpsBuildsJArray(patToken, organization, project); } if (list != null) { builds = JsonConvert.DeserializeObject <List <AzureDevOpsBuild> >(list.ToString()); //We need to do some post processing and loop over the list to construct a usable url foreach (AzureDevOpsBuild item in builds) { item.url = $"https://dev.azure.com/{organization}/{project}/_build/results?buildId={item.id}&view=results"; } //sort the final list builds = builds.OrderBy(o => o.queueTime).ToList(); } return(builds); }
public async Task <GitHubPR> GetGitHubPullRequest(string clientId, string clientSecret, TableStorageConfiguration tableStorageConfig, string owner, string repo, string branch, bool useCache) { List <GitHubPR> prs = new List <GitHubPR>(); Newtonsoft.Json.Linq.JArray list; if (useCache == true) { //Get the pull requests from Azure storage AzureTableStorageDA daTableStorage = new AzureTableStorageDA(); list = daTableStorage.GetTableStorageItemsFromStorage(tableStorageConfig, tableStorageConfig.TableGitHubPRs, PartitionKeys.CreateGitHubPRPartitionKey(owner, repo)); } else { //Get the pull requests from the GitHub API GitHubAPIAccess api = new GitHubAPIAccess(); list = await api.GetGitHubPullRequestsJArray(clientId, clientSecret, owner, repo, branch); } if (list != null) { prs = JsonConvert.DeserializeObject <List <GitHubPR> >(list.ToString()); } //Find the PR id GitHubPR pr = null; foreach (GitHubPR item in prs) { if (item.head.@ref == branch) { pr = item; break; } } return(pr); }
public async Task <List <GitHubPRCommit> > GetGitHubPullRequestCommits(string clientId, string clientSecret, TableStorageConfiguration tableStorageConfig, string owner, string repo, string pull_number, bool useCache) { Newtonsoft.Json.Linq.JArray list; if (useCache == true) { //Get the commits from Azure storage AzureTableStorageDA daTableStorage = new AzureTableStorageDA(); list = daTableStorage.GetTableStorageItemsFromStorage(tableStorageConfig, tableStorageConfig.TableGitHubPRCommits, PartitionKeys.CreateGitHubPRCommitPartitionKey(owner, repo, pull_number)); } else { //Get the commits from the GitHub API GitHubAPIAccess api = new GitHubAPIAccess(); list = await api.GetGitHubPullRequestCommitsJArray(clientId, clientSecret, owner, repo, pull_number); } List <GitHubPRCommit> commits = JsonConvert.DeserializeObject <List <GitHubPRCommit> >(list.ToString()); return(commits); }
public async Task <bool> UpdateChangeFailureRate(TableStorageConfiguration tableStorageConfig, string organization_owner, string project_repo, string buildName_workflowName, int percentComplete, int numberOfDays) { //Gets a list of change failure rate builds AzureTableStorageDA daTableStorage = new AzureTableStorageDA(); string partitionKey = PartitionKeys.CreateBuildWorkflowPartitionKey(organization_owner, project_repo, buildName_workflowName); Newtonsoft.Json.Linq.JArray list = daTableStorage.GetTableStorageItemsFromStorage(tableStorageConfig, tableStorageConfig.TableChangeFailureRate, partitionKey); List <ChangeFailureRateBuild> initialBuilds = JsonConvert.DeserializeObject <List <ChangeFailureRateBuild> >(list.ToString()); //Get the list of items we are going to process, within the date/day range List <ChangeFailureRateBuild> builds = new List <ChangeFailureRateBuild>(); foreach (ChangeFailureRateBuild item in initialBuilds) { if (item.StartTime > DateTime.Now.AddDays(-numberOfDays)) { builds.Add(item); } } Tuple <List <ChangeFailureRateBuild>, List <ChangeFailureRateBuild> > positiveAndNegativeBuilds = GetPositiveAndNegativeLists(percentComplete, builds); List <ChangeFailureRateBuild> positiveBuilds = positiveAndNegativeBuilds.Item1; List <ChangeFailureRateBuild> negativeBuilds = positiveAndNegativeBuilds.Item2; //Make the updates TableStorageCommonDA tableChangeFailureRateDA = new TableStorageCommonDA(tableStorageConfig, tableStorageConfig.TableChangeFailureRate); foreach (ChangeFailureRateBuild item in positiveBuilds) { item.DeploymentWasSuccessful = true; await daTableStorage.UpdateChangeFailureRate(tableChangeFailureRateDA, item, partitionKey, true); } foreach (ChangeFailureRateBuild item in negativeBuilds) { item.DeploymentWasSuccessful = false; await daTableStorage.UpdateChangeFailureRate(tableChangeFailureRateDA, item, partitionKey, true); } return(true); }
public async Task <List <AzureDevOpsPRCommit> > GetAzureDevOpsPullRequestCommits(string patToken, TableStorageConfiguration tableStorageConfig, string organization, string project, string repository, string pullRequestId, bool useCache) { Newtonsoft.Json.Linq.JArray list; if (useCache == true) { //Get the commits from Azure storage AzureTableStorageDA daTableStorage = new AzureTableStorageDA(); list = daTableStorage.GetTableStorageItemsFromStorage(tableStorageConfig, tableStorageConfig.TableAzureDevOpsPRCommits, PartitionKeys.CreateAzureDevOpsPRCommitPartitionKey(organization, project, pullRequestId)); } else { //Get the commits from the Azure DevOps API AzureDevOpsAPIAccess api = new AzureDevOpsAPIAccess(); list = await api.GetAzureDevOpsPullRequestCommitsJArray(patToken, organization, project, repository, pullRequestId); } List <AzureDevOpsPRCommit> commits = JsonConvert.DeserializeObject <List <AzureDevOpsPRCommit> >(list.ToString()); return(commits); }
public async Task <AzureDevOpsPR> GetAzureDevOpsPullRequest(string patToken, TableStorageConfiguration tableStorageConfig, string organization, string project, string repository, string branch, bool useCache) { List <AzureDevOpsPR> prs = new List <AzureDevOpsPR>(); Newtonsoft.Json.Linq.JArray list; if (useCache == true) { //Get the pull requests from Azure storage AzureTableStorageDA daTableStorage = new AzureTableStorageDA(); list = daTableStorage.GetTableStorageItemsFromStorage(tableStorageConfig, tableStorageConfig.TableAzureDevOpsPRs, PartitionKeys.CreateGitHubPRPartitionKey(organization, project)); } else { //Get the pull requests from the Azure DevOps API AzureDevOpsAPIAccess api = new AzureDevOpsAPIAccess(); list = await api.GetAzureDevOpsPullRequestsJArray(patToken, organization, project, repository); } if (list != null) { prs = JsonConvert.DeserializeObject <List <AzureDevOpsPR> >(list.ToString()); } //Find the PR id AzureDevOpsPR pr = null; foreach (AzureDevOpsPR item in prs) { if (item.sourceRefName == branch) { pr = item; break; } } return(pr); }
public MeanTimeToRestoreModel GetAzureMeanTimeToRestore(bool getSampleData, TableStorageConfiguration tableStorageConfig, DevOpsPlatform targetDevOpsPlatform, string resourceGroup, int numberOfDays, int maxNumberOfItems) { ListUtility <MeanTimeToRestoreEvent> utility = new ListUtility <MeanTimeToRestoreEvent>(); if (getSampleData == false) { //If the user didn't specify a resource group, it comes in as null and causes havoc. Setting it as "" helps, it if (resourceGroup == null) { resourceGroup = ""; } //Pull the events from the table storage AzureTableStorageDA daTableStorage = new AzureTableStorageDA(); Newtonsoft.Json.Linq.JArray list = daTableStorage.GetTableStorageItemsFromStorage(tableStorageConfig, tableStorageConfig.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(); List <KeyValuePair <DateTime, TimeSpan> > dateList = ConvertEventsToDateList(events); float averageMTTR = mttr.ProcessMeanTimeToRestore(dateList, numberOfDays); //Calculate the SLA metric SLA slaMetric = new SLA(); float sla = slaMetric.ProcessSLA(dateList, numberOfDays); //Filter the list for the UI, 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, SLA = sla, SLADescription = slaMetric.GetSLARating(sla) }; return(model); } else { //Get sample data MeanTimeToRestore mttr = new MeanTimeToRestore(); List <MeanTimeToRestoreEvent> sampleEvents = GetSampleMTTREvents(resourceGroup); List <KeyValuePair <DateTime, TimeSpan> > dateList = ConvertEventsToDateList(sampleEvents); float averageMTTR = mttr.ProcessMeanTimeToRestore(dateList, numberOfDays); SLA slaMetric = new SLA(); float sla = slaMetric.ProcessSLA(dateList, numberOfDays); MeanTimeToRestoreModel model = new MeanTimeToRestoreModel { TargetDevOpsPlatform = targetDevOpsPlatform, ResourceGroup = resourceGroup, MeanTimeToRestoreEvents = sampleEvents, MTTRAverageDurationInHours = averageMTTR, MTTRAverageDurationDescription = mttr.GetMeanTimeToRestoreRating(averageMTTR), NumberOfDays = numberOfDays, MaxNumberOfItems = sampleEvents.Count, TotalItems = sampleEvents.Count, SLA = sla, SLADescription = slaMetric.GetSLARating(sla) }; return(model); } }
public ChangeFailureRateModel GetChangeFailureRate(bool getSampleData, TableStorageConfiguration tableStorageConfig, 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.GetTableStorageItemsFromStorage(tableStorageConfig, tableStorageConfig.TableChangeFailureRate, PartitionKeys.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); } }