diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
index 9d2285ddbf..81b8f26417 100644
--- a/.config/dotnet-tools.json
+++ b/.config/dotnet-tools.json
@@ -3,7 +3,7 @@
"isRoot": true,
"tools": {
"microsoft.dnceng.secretmanager": {
- "version": "1.1.0-beta.24420.1",
+ "version": "1.1.0-beta.24460.1",
"commands": [
"secret-manager"
]
@@ -15,7 +15,7 @@
]
},
"microsoft.dnceng.configuration.bootstrap": {
- "version": "1.1.0-beta.24420.1",
+ "version": "1.1.0-beta.24460.1",
"commands": [
"bootstrap-dnceng-configuration"
]
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index 064556356b..2a0c7eb80e 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -91,37 +91,37 @@
-
+
https://github.com/dotnet/arcade
- 80264e60280e2815e7d65871081ccac04a32445c
+ 8c08d889b3c0b3f19398faceaccd74d0f184a3fb
-
+
https://github.com/dotnet/arcade
- 80264e60280e2815e7d65871081ccac04a32445c
+ 8c08d889b3c0b3f19398faceaccd74d0f184a3fb
-
+
https://github.com/dotnet/arcade
- 80264e60280e2815e7d65871081ccac04a32445c
+ 8c08d889b3c0b3f19398faceaccd74d0f184a3fb
-
+
https://github.com/dotnet/arcade
- 80264e60280e2815e7d65871081ccac04a32445c
+ 8c08d889b3c0b3f19398faceaccd74d0f184a3fb
-
+
https://github.com/dotnet/arcade
- 80264e60280e2815e7d65871081ccac04a32445c
+ 8c08d889b3c0b3f19398faceaccd74d0f184a3fb
-
+
https://github.com/dotnet/arcade
- 80264e60280e2815e7d65871081ccac04a32445c
+ 8c08d889b3c0b3f19398faceaccd74d0f184a3fb
-
+
https://github.com/dotnet/dnceng
- a0d339b12f248ca5b42d3a53a49c6b09ef1db579
+ c74bfc3484389b8f365dcab61ecd63d506d3575a
-
+
https://github.com/dotnet/dnceng
- a0d339b12f248ca5b42d3a53a49c6b09ef1db579
+ c74bfc3484389b8f365dcab61ecd63d506d3575a
diff --git a/eng/Versions.props b/eng/Versions.props
index 6b2f39315b..3db801c824 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -9,11 +9,11 @@
true
1.0.0-preview.1
- 8.0.0-beta.24426.2
- 8.0.0-beta.24426.2
- 8.0.0-beta.24426.2
- 8.0.0-beta.24426.2
- 8.0.0-beta.24426.2
+ 8.0.0-beta.24463.3
+ 8.0.0-beta.24463.3
+ 8.0.0-beta.24463.3
+ 8.0.0-beta.24463.3
+ 8.0.0-beta.24463.3
17.4.1
1.1.0-beta.24376.1
1.1.0-beta.24376.1
@@ -37,8 +37,8 @@
1.1.0-beta.24376.1
1.1.0-beta.24376.1
1.1.0-beta.24376.1
- 1.1.0-beta.24420.1
- 1.1.0-beta.24420.1
+ 1.1.0-beta.24460.1
+ 1.1.0-beta.24460.1
diff --git a/eng/deployment/product-construction-service-deploy.ps1 b/eng/deployment/product-construction-service-deploy.ps1
index 1c4ac33fbc..c152c04cd1 100644
--- a/eng/deployment/product-construction-service-deploy.ps1
+++ b/eng/deployment/product-construction-service-deploy.ps1
@@ -15,9 +15,9 @@ param(
$containerapp = az containerapp show -g $resourceGroupName -n $containerappName | ConvertFrom-Json
$pcsUrl = "https://$($containerapp.properties.configuration.ingress.fqdn)"
-$pcsStatusUrl = $pcsUrl + "/status"
-$pcsStopUrl = $pcsStatusUrl + "/stop"
-$pcsStartUrl = $pcsStatusUrl + "/start"
+$pcsStatusUrl = $pcsUrl + "/api/status"
+$pcsStopUrl = $pcsStatusUrl + "/stop?api-version=2020-02-20"
+$pcsStartUrl = $pcsStatusUrl + "/start?api-version=2020-02-20"
$authenticationHeader = @{
"Authorization" = "Bearer $token"
}
diff --git a/global.json b/global.json
index 6cb5cb8183..9c61800f19 100644
--- a/global.json
+++ b/global.json
@@ -15,6 +15,6 @@
}
},
"msbuild-sdks": {
- "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24426.2"
+ "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24463.3"
}
}
diff --git a/src/Microsoft.DotNet.Darc/DarcLib/GitHubClient.cs b/src/Microsoft.DotNet.Darc/DarcLib/GitHubClient.cs
index 8e6f2c30fc..d8ada19fea 100644
--- a/src/Microsoft.DotNet.Darc/DarcLib/GitHubClient.cs
+++ b/src/Microsoft.DotNet.Darc/DarcLib/GitHubClient.cs
@@ -1015,7 +1015,7 @@ private async Task> GetChecksFromChecksApiAsync(string owner, strin
CheckStatus.Queued or CheckStatus.InProgress => CheckState.Pending,
CheckStatus.Completed => (run.Conclusion?.Value) switch
{
- CheckConclusion.Success => CheckState.Success,
+ CheckConclusion.Success or CheckConclusion.Skipped => CheckState.Success,
CheckConclusion.ActionRequired or CheckConclusion.Cancelled or CheckConclusion.Failure or CheckConclusion.Neutral or CheckConclusion.TimedOut => CheckState.Failure,
_ => CheckState.None,
},
diff --git a/src/ProductConstructionService/ProductConstructionService.Api/Controllers/StatusController.cs b/src/ProductConstructionService/ProductConstructionService.Api/Controllers/StatusController.cs
index 5b531a9ba6..8b989c9300 100644
--- a/src/ProductConstructionService/ProductConstructionService.Api/Controllers/StatusController.cs
+++ b/src/ProductConstructionService/ProductConstructionService.Api/Controllers/StatusController.cs
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using Microsoft.AspNetCore.ApiVersioning;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.OpenApi.Extensions;
@@ -10,6 +11,7 @@
namespace ProductConstructionService.Api.Controllers;
[Route("status")]
+[ApiVersion("2020-02-20")]
public class StatusController(WorkItemScopeManager workItemScopeManager)
: ControllerBase
{
diff --git a/src/ProductConstructionService/ProductConstructionService.Client/Generated/ProductConstructionServiceApi.cs b/src/ProductConstructionService/ProductConstructionService.Client/Generated/ProductConstructionServiceApi.cs
index 73f5d9ded6..f593a21f9a 100644
--- a/src/ProductConstructionService/ProductConstructionService.Client/Generated/ProductConstructionServiceApi.cs
+++ b/src/ProductConstructionService/ProductConstructionService.Client/Generated/ProductConstructionServiceApi.cs
@@ -35,6 +35,7 @@ public partial interface IProductConstructionServiceApi
IChannels Channels { get; }
IPipelines Pipelines { get; }
IRepository Repository { get; }
+ IStatus Status { get; }
ISubscriptions Subscriptions { get; }
}
@@ -129,6 +130,8 @@ public HttpPipeline Pipeline
public IRepository Repository { get; }
+ public IStatus Status { get; }
+
public ISubscriptions Subscriptions { get; }
@@ -149,6 +152,7 @@ public ProductConstructionServiceApi(ProductConstructionServiceApiOptions option
Channels = new Channels(this);
Pipelines = new Pipelines(this);
Repository = new Repository(this);
+ Status = new Status(this);
Subscriptions = new Subscriptions(this);
SerializerSettings = new JsonSerializerSettings
{
diff --git a/src/ProductConstructionService/ProductConstructionService.Client/Generated/Status.cs b/src/ProductConstructionService/ProductConstructionService.Client/Generated/Status.cs
new file mode 100644
index 0000000000..42d7a5fcfb
--- /dev/null
+++ b/src/ProductConstructionService/ProductConstructionService.Client/Generated/Status.cs
@@ -0,0 +1,222 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.IO;
+using System.Threading;
+using System.Threading.Tasks;
+using Azure;
+using Azure.Core;
+
+
+
+namespace ProductConstructionService.Client
+{
+ public partial interface IStatus
+ {
+ Task StopPcsWorkItemProcessorAsync(
+ CancellationToken cancellationToken = default
+ );
+
+ Task StartPcsWorkItemProcessorAsync(
+ CancellationToken cancellationToken = default
+ );
+
+ Task GetPcsWorkItemProcessorStatusAsync(
+ CancellationToken cancellationToken = default
+ );
+
+ }
+
+ internal partial class Status : IServiceOperations, IStatus
+ {
+ public Status(ProductConstructionServiceApi client)
+ {
+ Client = client ?? throw new ArgumentNullException(nameof(client));
+ }
+
+ public ProductConstructionServiceApi Client { get; }
+
+ partial void HandleFailedRequest(RestApiException ex);
+
+ partial void HandleFailedStopPcsWorkItemProcessorRequest(RestApiException ex);
+
+ public async Task StopPcsWorkItemProcessorAsync(
+ CancellationToken cancellationToken = default
+ )
+ {
+
+ const string apiVersion = "2020-02-20";
+
+ var _baseUri = Client.Options.BaseUri;
+ var _url = new RequestUriBuilder();
+ _url.Reset(_baseUri);
+ _url.AppendPath(
+ "/api/status/stop",
+ false);
+
+ _url.AppendQuery("api-version", Client.Serialize(apiVersion));
+
+
+ using (var _req = Client.Pipeline.CreateRequest())
+ {
+ _req.Uri = _url;
+ _req.Method = RequestMethod.Put;
+
+ using (var _res = await Client.SendAsync(_req, cancellationToken).ConfigureAwait(false))
+ {
+ if (_res.Status < 200 || _res.Status >= 300)
+ {
+ await OnStopPcsWorkItemProcessorFailed(_req, _res).ConfigureAwait(false);
+ }
+
+
+ return;
+ }
+ }
+ }
+
+ internal async Task OnStopPcsWorkItemProcessorFailed(Request req, Response res)
+ {
+ string content = null;
+ if (res.ContentStream != null)
+ {
+ using (var reader = new StreamReader(res.ContentStream))
+ {
+ content = await reader.ReadToEndAsync().ConfigureAwait(false);
+ }
+ }
+
+ var ex = new RestApiException(
+ req,
+ res,
+ content,
+ Client.Deserialize(content)
+ );
+ HandleFailedStopPcsWorkItemProcessorRequest(ex);
+ HandleFailedRequest(ex);
+ Client.OnFailedRequest(ex);
+ throw ex;
+ }
+
+ partial void HandleFailedStartPcsWorkItemProcessorRequest(RestApiException ex);
+
+ public async Task StartPcsWorkItemProcessorAsync(
+ CancellationToken cancellationToken = default
+ )
+ {
+
+ const string apiVersion = "2020-02-20";
+
+ var _baseUri = Client.Options.BaseUri;
+ var _url = new RequestUriBuilder();
+ _url.Reset(_baseUri);
+ _url.AppendPath(
+ "/api/status/start",
+ false);
+
+ _url.AppendQuery("api-version", Client.Serialize(apiVersion));
+
+
+ using (var _req = Client.Pipeline.CreateRequest())
+ {
+ _req.Uri = _url;
+ _req.Method = RequestMethod.Put;
+
+ using (var _res = await Client.SendAsync(_req, cancellationToken).ConfigureAwait(false))
+ {
+ if (_res.Status < 200 || _res.Status >= 300)
+ {
+ await OnStartPcsWorkItemProcessorFailed(_req, _res).ConfigureAwait(false);
+ }
+
+
+ return;
+ }
+ }
+ }
+
+ internal async Task OnStartPcsWorkItemProcessorFailed(Request req, Response res)
+ {
+ string content = null;
+ if (res.ContentStream != null)
+ {
+ using (var reader = new StreamReader(res.ContentStream))
+ {
+ content = await reader.ReadToEndAsync().ConfigureAwait(false);
+ }
+ }
+
+ var ex = new RestApiException(
+ req,
+ res,
+ content,
+ Client.Deserialize(content)
+ );
+ HandleFailedStartPcsWorkItemProcessorRequest(ex);
+ HandleFailedRequest(ex);
+ Client.OnFailedRequest(ex);
+ throw ex;
+ }
+
+ partial void HandleFailedGetPcsWorkItemProcessorStatusRequest(RestApiException ex);
+
+ public async Task GetPcsWorkItemProcessorStatusAsync(
+ CancellationToken cancellationToken = default
+ )
+ {
+
+ const string apiVersion = "2020-02-20";
+
+ var _baseUri = Client.Options.BaseUri;
+ var _url = new RequestUriBuilder();
+ _url.Reset(_baseUri);
+ _url.AppendPath(
+ "/api/status",
+ false);
+
+ _url.AppendQuery("api-version", Client.Serialize(apiVersion));
+
+
+ using (var _req = Client.Pipeline.CreateRequest())
+ {
+ _req.Uri = _url;
+ _req.Method = RequestMethod.Get;
+
+ using (var _res = await Client.SendAsync(_req, cancellationToken).ConfigureAwait(false))
+ {
+ if (_res.Status < 200 || _res.Status >= 300)
+ {
+ await OnGetPcsWorkItemProcessorStatusFailed(_req, _res).ConfigureAwait(false);
+ }
+
+
+ return;
+ }
+ }
+ }
+
+ internal async Task OnGetPcsWorkItemProcessorStatusFailed(Request req, Response res)
+ {
+ string content = null;
+ if (res.ContentStream != null)
+ {
+ using (var reader = new StreamReader(res.ContentStream))
+ {
+ content = await reader.ReadToEndAsync().ConfigureAwait(false);
+ }
+ }
+
+ var ex = new RestApiException(
+ req,
+ res,
+ content,
+ Client.Deserialize(content)
+ );
+ HandleFailedGetPcsWorkItemProcessorStatusRequest(ex);
+ HandleFailedRequest(ex);
+ Client.OnFailedRequest(ex);
+ throw ex;
+ }
+ }
+}
diff --git a/src/ProductConstructionService/ProductConstructionService.Common/MetricRecorder.cs b/src/ProductConstructionService/ProductConstructionService.Common/MetricRecorder.cs
index 179c2211ab..28334df97b 100644
--- a/src/ProductConstructionService/ProductConstructionService.Common/MetricRecorder.cs
+++ b/src/ProductConstructionService/ProductConstructionService.Common/MetricRecorder.cs
@@ -8,7 +8,7 @@ namespace ProductConstructionService.Common;
public interface IMetricRecorder
{
- void QueueMessageReceived(QueueMessage message, TimeSpan delay);
+ void QueueMessageReceived(QueueMessage message, int delayInSeconds);
}
public class MetricRecorder : IMetricRecorder
@@ -24,9 +24,9 @@ public MetricRecorder(IMeterFactory meterFactory)
_queueWaitTimeCounter = meter.CreateCounter(WaitTimeMetricName);
}
- public void QueueMessageReceived(QueueMessage message, TimeSpan delay)
+ public void QueueMessageReceived(QueueMessage message, int delayInSeconds)
{
- TimeSpan timeInQueue = DateTimeOffset.UtcNow - message.InsertedOn!.Value - delay;
- _queueWaitTimeCounter.Add((int)timeInQueue.TotalSeconds);
+ TimeSpan timeInQueue = DateTimeOffset.UtcNow - message.InsertedOn!.Value;
+ _queueWaitTimeCounter.Add((int)timeInQueue.TotalSeconds - delayInSeconds);
}
}
diff --git a/src/ProductConstructionService/ProductConstructionService.WorkItems/WorkItem.cs b/src/ProductConstructionService/ProductConstructionService.WorkItems/WorkItem.cs
index 7c5b7cd9fd..becb8b2fc9 100644
--- a/src/ProductConstructionService/ProductConstructionService.WorkItems/WorkItem.cs
+++ b/src/ProductConstructionService/ProductConstructionService.WorkItems/WorkItem.cs
@@ -16,5 +16,5 @@ public abstract class WorkItem
/// Period of time before the WorkItem becomes visible in the queue.
///
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault | JsonIgnoreCondition.WhenWritingNull)]
- public TimeSpan? Delay { get; internal set; }
+ public int? Delay { get; internal set; }
}
diff --git a/src/ProductConstructionService/ProductConstructionService.WorkItems/WorkItemConsumer.cs b/src/ProductConstructionService/ProductConstructionService.WorkItems/WorkItemConsumer.cs
index 76e80caf0e..2f791e9866 100644
--- a/src/ProductConstructionService/ProductConstructionService.WorkItems/WorkItemConsumer.cs
+++ b/src/ProductConstructionService/ProductConstructionService.WorkItems/WorkItemConsumer.cs
@@ -70,17 +70,14 @@ private async Task ReadAndProcessWorkItemAsync(QueueClient queueClient, WorkItem
}
string workItemType;
- TimeSpan? delay;
+ int? delay;
JsonNode node;
try
{
node = JsonNode.Parse(message.Body)!;
workItemType = node["type"]!.ToString();
- var d = node["delay"]?.GetValue();
- delay = d.HasValue
- ? TimeSpan.FromSeconds(d.Value)
- : null;
+ delay = node["delay"]?.GetValue();
}
catch (Exception ex)
{
@@ -89,7 +86,7 @@ private async Task ReadAndProcessWorkItemAsync(QueueClient queueClient, WorkItem
return;
}
- _metricRecorder.QueueMessageReceived(message, delay ?? default);
+ _metricRecorder.QueueMessageReceived(message, delay ?? 0);
try
{
diff --git a/src/ProductConstructionService/ProductConstructionService.WorkItems/WorkItemProducer.cs b/src/ProductConstructionService/ProductConstructionService.WorkItems/WorkItemProducer.cs
index 620db1d715..2f3a449839 100644
--- a/src/ProductConstructionService/ProductConstructionService.WorkItems/WorkItemProducer.cs
+++ b/src/ProductConstructionService/ProductConstructionService.WorkItems/WorkItemProducer.cs
@@ -31,7 +31,7 @@ public async Task ProduceWorkItemAsync(T payload, TimeSpan delay =
if (delay != default)
{
- payload.Delay = delay;
+ payload.Delay = (int)delay.TotalSeconds;
}
var json = JsonSerializer.Serialize(payload, WorkItemConfiguration.JsonSerializerOptions);
diff --git a/test/ProductConstructionService.ScenarioTests/ScenarioTestBase.cs b/test/ProductConstructionService.ScenarioTests/ScenarioTestBase.cs
index 0cbd2f579c..c0208da50f 100644
--- a/test/ProductConstructionService.ScenarioTests/ScenarioTestBase.cs
+++ b/test/ProductConstructionService.ScenarioTests/ScenarioTestBase.cs
@@ -55,7 +55,7 @@ public void SetTestParameters(TestParameters parameters)
{
Octokit.Repository repo = await GitHubApi.Repository.Get(_parameters.GitHubTestOrg, targetRepo);
- var attempts = 20;
+ var attempts = 40;
while (attempts-- > 0)
{
IReadOnlyList prs = await GitHubApi.PullRequest.GetAllForRepository(repo.Id, new Octokit.PullRequestRequest
@@ -85,7 +85,7 @@ public void SetTestParameters(TestParameters parameters)
throw new ScenarioTestException($"No pull request was created in {targetRepo} targeting {targetBranch}");
}
- private async Task WaitForUpdatedPullRequestAsync(string targetRepo, string targetBranch, int attempts = 20)
+ private async Task WaitForUpdatedPullRequestAsync(string targetRepo, string targetBranch, int attempts = 40)
{
Octokit.Repository repo = await GitHubApi.Repository.Get(_parameters.GitHubTestOrg, targetRepo);
Octokit.PullRequest pr = await WaitForPullRequestAsync(targetRepo, targetBranch);
@@ -106,7 +106,7 @@ public void SetTestParameters(TestParameters parameters)
throw new ScenarioTestException($"The created pull request for {targetRepo} targeting {targetBranch} was not updated with subsequent subscriptions after creation");
}
- private async Task WaitForMergedPullRequestAsync(string targetRepo, string targetBranch, int attempts = 20)
+ private async Task WaitForMergedPullRequestAsync(string targetRepo, string targetBranch, int attempts = 40)
{
Octokit.Repository repo = await GitHubApi.Repository.Get(_parameters.GitHubTestOrg, targetRepo);
Octokit.PullRequest pr = await WaitForPullRequestAsync(targetRepo, targetBranch);
@@ -132,7 +132,7 @@ private async Task GetAzDoPullRequestIdAsync(string targetRepoName, string
var searchBaseUrl = GetAzDoRepoUrl(targetRepoName);
IEnumerable prs = new List();
- var attempts = 20;
+ var attempts = 40;
while (attempts-- > 0)
{
try
@@ -195,7 +195,7 @@ private async Task> GetAzDoPullRequestAsync(in
throw new Exception($"{nameof(expectedPRTitle)} must be defined for AzDo PRs that require an update");
}
- for (var tries = 20; tries > 0; tries--)
+ for (var tries = 40; tries > 0; tries--)
{
PullRequest pr = await AzDoClient.GetPullRequestAsync($"{apiBaseUrl}/pullRequests/{pullRequestId}");
var trimmedTitle = Regex.Replace(pr.Title, @"\s+", " ");
@@ -891,7 +891,7 @@ protected async Task GetRepositoryPolicies(string repoUri, string branch
return await RunDarcAsync("get-repository-policies", "--all", "--repo", repoUri, "--branch", branchName);
}
- protected async Task WaitForMergedPullRequestAsync(string targetRepo, string targetBranch, Octokit.PullRequest pr, Octokit.Repository repo, int attempts = 20)
+ protected async Task WaitForMergedPullRequestAsync(string targetRepo, string targetBranch, Octokit.PullRequest pr, Octokit.Repository repo, int attempts = 40)
{
while (attempts-- > 0)
{