-
Notifications
You must be signed in to change notification settings - Fork 187
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for missing build processing
- Loading branch information
Showing
13 changed files
with
407 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
108 changes: 108 additions & 0 deletions
108
...-witness/Azure.Sdk.Tools.PipelineWitness/AzurePipelines/MissingAzurePipelineRunsWorker.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
using System; | ||
using System.Linq; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Azure.Sdk.Tools.PipelineWitness.Configuration; | ||
using Azure.Sdk.Tools.PipelineWitness.Services; | ||
using Azure.Sdk.Tools.PipelineWitness.Services.WorkTokens; | ||
using Microsoft.Extensions.Logging; | ||
using Microsoft.Extensions.Options; | ||
using Microsoft.TeamFoundation.Build.WebApi; | ||
using Microsoft.VisualStudio.Services.WebApi; | ||
|
||
namespace Azure.Sdk.Tools.PipelineWitness.AzurePipelines | ||
{ | ||
public class MissingAzurePipelineRunsWorker : PeriodicLockingBackgroundService | ||
{ | ||
private readonly ILogger<MissingAzurePipelineRunsWorker> logger; | ||
private readonly AzurePipelinesProcessor runProcessor; | ||
private readonly BuildCompleteQueue buildCompleteQueue; | ||
private readonly IOptions<PipelineWitnessSettings> options; | ||
private readonly BuildHttpClient buildClient; | ||
|
||
public MissingAzurePipelineRunsWorker( | ||
ILogger<MissingAzurePipelineRunsWorker> logger, | ||
AzurePipelinesProcessor runProcessor, | ||
IAsyncLockProvider asyncLockProvider, | ||
VssConnection vssConnection, | ||
BuildCompleteQueue buildCompleteQueue, | ||
IOptions<PipelineWitnessSettings> options) | ||
: base( | ||
logger, | ||
asyncLockProvider, | ||
options.Value.MissingPipelineRunsWorker) | ||
{ | ||
this.logger = logger; | ||
this.runProcessor = runProcessor; | ||
this.buildCompleteQueue = buildCompleteQueue; | ||
this.options = options; | ||
|
||
if (vssConnection == null) | ||
{ | ||
throw new ArgumentNullException(nameof(vssConnection)); | ||
} | ||
|
||
this.buildClient = vssConnection.GetClient<EnhancedBuildHttpClient>(); | ||
} | ||
|
||
protected override async Task ProcessAsync(CancellationToken cancellationToken) | ||
{ | ||
var settings = this.options.Value; | ||
|
||
// search for builds that completed within this window | ||
var buildMinTime = DateTimeOffset.UtcNow.Subtract(settings.MissingPipelineRunsWorker.LookbackPeriod); | ||
var buildMaxTime = DateTimeOffset.UtcNow.Subtract(TimeSpan.FromHours(1)); | ||
|
||
foreach (string project in settings.Projects) | ||
{ | ||
var knownBlobs = await this.runProcessor.GetBuildBlobNamesAsync(project, buildMinTime, buildMaxTime, cancellationToken); | ||
|
||
string continuationToken = null; | ||
do | ||
{ | ||
var completedBuilds = await this.buildClient.GetBuildsAsync2( | ||
project, | ||
minFinishTime: buildMinTime.DateTime, | ||
maxFinishTime: buildMaxTime.DateTime, | ||
statusFilter: BuildStatus.Completed, | ||
continuationToken: continuationToken, | ||
cancellationToken: cancellationToken); | ||
|
||
var skipCount = 0; | ||
var enqueueCount = 0; | ||
foreach (var build in completedBuilds) | ||
{ | ||
var blobName = this.runProcessor.GetBuildBlobName(build); | ||
|
||
if (knownBlobs.Contains(blobName, StringComparer.InvariantCultureIgnoreCase)) | ||
{ | ||
skipCount++; | ||
continue; | ||
} | ||
|
||
var queueMessage = new BuildCompleteQueueMessage | ||
{ | ||
Account = settings.Account, | ||
ProjectId = build.Project.Id, | ||
BuildId = build.Id | ||
}; | ||
|
||
this.logger.LogInformation("Enqueuing missing build {Project} {BuildId} for processing", build.Project.Name, build.Id); | ||
await this.buildCompleteQueue.EnqueueMessageAsync(queueMessage); | ||
enqueueCount++; | ||
} | ||
|
||
this.logger.LogInformation("Enqueued {EnqueueCount} missing builds, skipped {SkipCount} existing builds in project {Project}", enqueueCount, skipCount, project); | ||
|
||
continuationToken = completedBuilds.ContinuationToken; | ||
} while(!string.IsNullOrEmpty(continuationToken)); | ||
} | ||
} | ||
|
||
protected override Task ProcessExceptionAsync(Exception ex) | ||
{ | ||
this.logger.LogError(ex, "Error processing missing builds"); | ||
return Task.CompletedTask; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
50 changes: 50 additions & 0 deletions
50
...s/pipeline-witness/Azure.Sdk.Tools.PipelineWitness/Configuration/PostConfigureSettings.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
using System; | ||
using System.Linq; | ||
using System.Net.Http; | ||
using System.Net.Http.Json; | ||
using System.Text.RegularExpressions; | ||
using System.Threading; | ||
using Microsoft.Extensions.Logging; | ||
using Microsoft.Extensions.Options; | ||
|
||
namespace Azure.Sdk.Tools.PipelineWitness.Configuration; | ||
|
||
public class PostConfigureSettings : IPostConfigureOptions<PipelineWitnessSettings> | ||
{ | ||
private readonly ILogger logger; | ||
|
||
public PostConfigureSettings(ILogger<PostConfigureSettings> logger) | ||
{ | ||
this.logger = logger; | ||
} | ||
|
||
public void PostConfigure(string name, PipelineWitnessSettings options) | ||
{ | ||
if (options.GitHubRepositories == null || options.GitHubRepositories.Length == 0) | ||
{ | ||
options.GitHubRepositories = []; | ||
|
||
if (string.IsNullOrEmpty(options.GitHubRepositoriesSource)) | ||
{ | ||
this.logger.LogWarning("No GitHubRepositories or GitHubRepositoriesSource configured"); | ||
return; | ||
} | ||
|
||
try | ||
{ | ||
this.logger.LogInformation("Replacing settings property GitHubRepositories with values from {Source}", options.GitHubRepositoriesSource); | ||
using var client = new HttpClient(); | ||
|
||
options.GitHubRepositories = client.GetFromJsonAsync<string[]>(options.GitHubRepositoriesSource) | ||
.ConfigureAwait(true) | ||
.GetAwaiter() | ||
.GetResult(); | ||
} | ||
catch (Exception ex) | ||
{ | ||
this.logger.LogError(ex, "Error loading repository list from source"); | ||
return; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.