private async Task UploadBuild(Build build) { try { var uri = DevOpsUtil.GetBuildUri(build); if (build.Status != BuildStatus.Completed) { Logger.LogInformation($"Build is not completed {uri}"); return; } if (await IsBuildUploadedAsync(build.Id)) { Logger.LogInformation($"Build already uploaded {uri}"); return; } Logger.LogInformation($"Getting timeline {uri}"); var jobs = await GetJobCloneTimesAsync(build); if (jobs.Count == 0) { Logger.LogInformation("Found no jobs"); return; } Logger.LogInformation($"Uploading {uri}"); if (build.StartTime is null) { Logger.LogError("Found no start time"); return; } var buildStartTime = DateTimeOffset.Parse(build.StartTime); await DotNetUtil.DoWithTransactionAsync(SqlConnection, $"Upload Clone {build.Id}", async transaction => { foreach (var job in jobs) { await UploadJobCloneTime(transaction, build.Id, build.Definition.Id, buildStartTime, uri, job); } var minDuration = jobs.Min(x => x.Duration); var maxDuration = jobs.Max(x => x.Duration); var totalFetchSize = jobs.Sum(x => x.FetchSize); var minFetchSpeed = jobs.Min(x => x.MinFetchSpeed); var maxFetchSpeed = jobs.Max(x => x.MaxFetchSpeed); await UploadBuildCloneTime(transaction, build.Id, build.Definition.Id, minDuration, maxDuration, buildStartTime, uri, totalFetchSize, minFetchSpeed, maxFetchSpeed); }); Logger.LogInformation("Build upload complete"); } catch (Exception ex) { Logger.LogError($"Error {ex.Message}"); throw; } }
public Task <List <Build> > ListBuildsAsync( int count = 50, string?project = null, string?definition = null, string?repositoryName = null, string?branch = null, bool includePullRequests = false, string?before = null, string?after = null) { string?repositoryId = null; if (repositoryName is object) { repositoryId = $"{DotNetUtil.GitHubOrganization}/{repositoryName}"; } int[]? definitions = null; if (definition is object) { if (!DotNetUtil.TryGetDefinitionId(definition, out _, out var definitionId)) { throw new Exception($"Invalid definition name {definition}"); } definitions = new[] { definitionId }; } DateTimeOffset?beforeDateTimeOffset = null; if (before is object) { beforeDateTimeOffset = DateTimeOffset.Parse(before); } DateTimeOffset?afterDateTimeOffset = null; if (after is object) { afterDateTimeOffset = DateTimeOffset.Parse(after); } return(ListBuildsAsync( count: count, project: project, definitions: definitions, repositoryId: repositoryId, branch: branch, includePullRequests: includePullRequests, before: beforeDateTimeOffset, after: afterDateTimeOffset)); }
public async Task UploadBuild(Build build) { VerifyBuild(build); var uri = DevOpsUtil.GetBuildUri(build).ToString(); Logger.LogInformation($"Uploading {build.Id} - {uri}"); if (await IsBuildUploadedAsync(build.Id)) { Logger.LogInformation("Build already uploaded"); return; } var branchName = DotNetUtil.NormalizeBranchName(build.SourceBranch); var list = await GetNGenAssemblyDataAsync(build); await DotNetUtil.DoWithTransactionAsync(SqlConnection, $"Uploading {build.Id}", async transaction => { foreach (var ngenAssemblyData in list) { await UploadNGenAssemblyDataAsync(transaction, build.Id, branchName, uri, ngenAssemblyData); } }); }
public CloneTimeUtil(string sqlConnectionString, ILogger logger = null) { Logger = logger ?? DotNetUtil.CreateConsoleLogger(); DevOpsServer = new DevOpsServer("dnceng"); SqlConnection = new SqlConnection(sqlConnectionString); }
public GeneralUtil(string sqlConnectionString, ILogger logger = null) { Logger = logger ?? DotNetUtil.CreateConsoleLogger(); SqlConnection = new SqlConnection(sqlConnectionString); }
public NGenUtil(string personalAccessToken, string connectionString, ILogger logger = null) { Logger = logger ?? DotNetUtil.CreateConsoleLogger(); DevOpsServer = new DevOpsServer("devdiv", personalAccessToken); SqlConnection = new SqlConnection(connectionString); }
public async Task <List <Build> > ListBuildsAsync(BuildSearchOptionSet optionSet) { if (optionSet.BuildIds.Count > 0 && optionSet.Definitions.Count > 0) { OptionFailure("Cannot specify builds and definitions", optionSet); throw CreateBadOptionException(); } var project = optionSet.Project ?? BuildSearchOptionSet.DefaultProject; var searchCount = optionSet.SearchCount ?? BuildSearchOptionSet.DefaultSearchCount; var repository = optionSet.Repository; var branch = optionSet.Branch; var before = optionSet.Before; var after = optionSet.After; if (branch is object && !branch.StartsWith("refs")) { branch = $"refs/heads/{branch}"; } var builds = new List <Build>(); if (optionSet.BuildIds.Count > 0) { if (optionSet.Repository is object) { OptionFailure("Cannot specify builds and repository", optionSet); throw CreateBadOptionException(); } if (optionSet.Branch is object) { OptionFailure("Cannot specify builds and branch", optionSet); throw CreateBadOptionException(); } if (optionSet.SearchCount is object) { OptionFailure("Cannot specify builds and count", optionSet); throw CreateBadOptionException(); } foreach (var buildInfo in optionSet.BuildIds) { if (!TryGetBuildId(optionSet, buildInfo, out var buildProject, out var buildId)) { OptionFailure($"Cannot convert {buildInfo} to build id", optionSet); throw CreateBadOptionException(); } var build = await Server.GetBuildAsync(buildProject, buildId).ConfigureAwait(false); builds.Add(build); } } else if (optionSet.Definitions.Count > 0) { foreach (var definition in optionSet.Definitions) { if (!DotNetUtil.TryGetDefinitionId(definition, defaultProject: project, out var definitionProject, out var definitionId)) { OptionFailureDefinition(definition, optionSet); throw CreateBadOptionException(); } definitionProject ??= project; var collection = await ListBuildsAsync( definitionProject, searchCount, definitions : new[] { definitionId }, repositoryId : repository, branchName : branch, includePullRequests : optionSet.IncludePullRequests); builds.AddRange(collection); } } else { var collection = await ListBuildsAsync( project, searchCount, definitions : null, repositoryId : repository, branchName : branch, includePullRequests : optionSet.IncludePullRequests); builds.AddRange(collection); } // Exclude out the builds that are complicating results foreach (var excludedBuildId in optionSet.ExcludedBuildIds) { builds = builds.Where(x => x.Id != excludedBuildId).ToList(); } // When doing before / after comparisons always use QueueTime. The StartTime parameter // in REST refers to when the latest build attempt started, not the original. Using that // means the jobs returned can violate the before / after constraint. The queue time is // consistent though and can be reliably used for filtering if (before.HasValue) { builds = builds.Where(b => b.GetQueueTime() is DateTimeOffset d && d <= before.Value).ToList(); } if (after.HasValue) { builds = builds.Where(b => b.GetQueueTime() is DateTimeOffset d && d >= after.Value).ToList(); } return(builds); }