diff --git a/src/Microsoft.DotNet.Darc/Darc/Helpers/LocalSettings.cs b/src/Microsoft.DotNet.Darc/Darc/Helpers/LocalSettings.cs
index 7d2b688ea1..b80f68c855 100644
--- a/src/Microsoft.DotNet.Darc/Darc/Helpers/LocalSettings.cs
+++ b/src/Microsoft.DotNet.Darc/Darc/Helpers/LocalSettings.cs
@@ -2,9 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System;
-using System.IO;
using Microsoft.DotNet.Darc.Options;
-using Microsoft.DotNet.DarcLib;
using Microsoft.DotNet.Maestro.Client;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
@@ -42,26 +40,6 @@ public static LocalSettings LoadSettingsFile()
return JsonConvert.DeserializeObject
(settings);
}
- private static LocalSettings LoadSettingsFile(ICommandLineOptions options)
- {
- try
- {
- return LoadSettingsFile();
- }
- catch (Exception exc) when (exc is DirectoryNotFoundException || exc is FileNotFoundException)
- {
- if (string.IsNullOrEmpty(options.AzureDevOpsPat) && string.IsNullOrEmpty(options.GitHubPat))
- {
- throw new DarcException("Please make sure to run darc authenticate and set" +
- " 'github_token' or 'azure_devops_token' or append" +
- "'-p ' [--github-pat | " +
- "--azdev-pat ] to your command");
- }
- }
-
- return null;
- }
-
///
/// Retrieve the settings from the combination of the command line
/// options and the user's darc settings file.
@@ -75,7 +53,7 @@ public static LocalSettings GetSettings(ICommandLineOptions options, ILogger log
try
{
- localSettings = LoadSettingsFile(options);
+ localSettings = LoadSettingsFile();
}
catch (Exception e)
{
diff --git a/src/Microsoft.DotNet.Darc/Darc/Models/PopUps/AuthenticateEditorPopUp.cs b/src/Microsoft.DotNet.Darc/Darc/Models/PopUps/AuthenticateEditorPopUp.cs
index 539474e8d9..8414f3f6c1 100644
--- a/src/Microsoft.DotNet.Darc/Darc/Models/PopUps/AuthenticateEditorPopUp.cs
+++ b/src/Microsoft.DotNet.Darc/Darc/Models/PopUps/AuthenticateEditorPopUp.cs
@@ -6,7 +6,7 @@
using Microsoft.DotNet.Darc.Helpers;
using Microsoft.Extensions.Logging;
-namespace Microsoft.DotNet.Darc.Models;
+namespace Microsoft.DotNet.Darc.Models.PopUps;
internal class AuthenticateEditorPopUp : EditorPopUp
{
@@ -21,6 +21,7 @@ public AuthenticateEditorPopUp(string path, ILogger logger)
: base(path)
{
_logger = logger;
+
try
{
// Load current settings
@@ -31,13 +32,15 @@ public AuthenticateEditorPopUp(string path, ILogger logger)
// Failed to load the settings file. Quite possible it just doesn't exist.
// In this case, just initialize the settings to empty
_logger.LogTrace($"Couldn't load or locate the settings file ({e.Message}). Initializing an empty settings file");
- settings = new LocalSettings();
}
+ settings ??= new LocalSettings();
+
// Initialize line contents.
Contents =
[
- new("[DEPRECATED] BAR tokens (formerly created at https://maestro.dot.net/Account/Tokens) are now deprecated.", isComment: true),
+ new("[DEPRECATED]", isComment: true),
+ new("BAR tokens (formerly created at https://maestro.dot.net/Account/Tokens) are now deprecated.", isComment: true),
new("Interactive sign-in through a security group is now enabled.", isComment: true),
new("See https://github.com/dotnet/arcade/blob/main/Documentation/Darc.md#setting-up-your-darc-client for more information.", isComment: true),
new($"{BarPasswordElement}={GetCurrentSettingForDisplay(settings.BuildAssetRegistryToken, string.Empty, true)}"),
@@ -45,8 +48,11 @@ public AuthenticateEditorPopUp(string path, ILogger logger)
new("Create new GitHub personal access tokens at https://github.com/settings/tokens (no scopes needed but needs SSO enabled on the PAT)", isComment: true),
new($"{GithubTokenElement}={GetCurrentSettingForDisplay(settings.GitHubToken, string.Empty, true)}"),
new(string.Empty),
- new("Create new Azure Dev Ops tokens using the PatGeneratorTool https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-eng/NuGet/Microsoft.DncEng.PatGeneratorTool", isComment: true),
- new("with the `dotnet pat-generator --scopes build_execute code --organizations dnceng devdiv --expires-in 180` command", isComment: true),
+ new("[OPTIONAL]", isComment: true),
+ new("Set an Azure DevOps token (or leave empty to use local credentials)", isComment: true),
+ new("Create an AzDO PAT with the Build.Execute and Code.Read scopes at ", isComment: true),
+ new("Or use the PatGeneratorTool https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-eng/NuGet/Microsoft.DncEng.PatGeneratorTool", isComment: true),
+ new("with the `dotnet pat-generator --scopes build_execute code --organizations dnceng devdiv --expires-in 7` command", isComment: true),
new($"{AzureDevOpsTokenElement}={GetCurrentSettingForDisplay(settings.AzureDevOpsToken, string.Empty, true)}"),
new(string.Empty),
new($"{BarBaseUriElement}={GetCurrentSettingForDisplay(settings.BuildAssetRegistryBaseUri, "", false)}"),
@@ -61,7 +67,7 @@ public override int ProcessContents(IList contents)
{
foreach (Line line in contents)
{
- string[] keyValue = line.Text.Split("=");
+ var keyValue = line.Text.Split("=");
switch (keyValue[0])
{
diff --git a/src/Microsoft.DotNet.Darc/Darc/Operations/AddBuildToChannelOperation.cs b/src/Microsoft.DotNet.Darc/Darc/Operations/AddBuildToChannelOperation.cs
index 5f63fff42b..06d9081768 100644
--- a/src/Microsoft.DotNet.Darc/Darc/Operations/AddBuildToChannelOperation.cs
+++ b/src/Microsoft.DotNet.Darc/Darc/Operations/AddBuildToChannelOperation.cs
@@ -223,7 +223,7 @@ private async Task PromoteBuildAsync(Build build, List targetChann
return Constants.ErrorCode;
}
- var azdoClient = Provider.GetRequiredService();
+ var azdoClient = Provider.GetRequiredService();
var targetAzdoBuildStatus = await ValidateAzDOBuildAsync(azdoClient, build.AzureDevOpsAccount, build.AzureDevOpsProject, build.AzureDevOpsBuildId.Value)
.ConfigureAwait(false);
@@ -321,7 +321,7 @@ private async Task PromoteBuildAsync(Build build, List targetChann
}
}
- private async Task ValidateAzDOBuildAsync(AzureDevOpsClient azdoClient, string azureDevOpsAccount, string azureDevOpsProject, int azureDevOpsBuildId)
+ private async Task ValidateAzDOBuildAsync(IAzureDevOpsClient azdoClient, string azureDevOpsAccount, string azureDevOpsProject, int azureDevOpsBuildId)
{
try
{
diff --git a/src/Microsoft.DotNet.Darc/Darc/Operations/AuthenticateOperation.cs b/src/Microsoft.DotNet.Darc/Darc/Operations/AuthenticateOperation.cs
index e1b1c14fb2..dbe2dc6849 100644
--- a/src/Microsoft.DotNet.Darc/Darc/Operations/AuthenticateOperation.cs
+++ b/src/Microsoft.DotNet.Darc/Darc/Operations/AuthenticateOperation.cs
@@ -1,14 +1,14 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using Microsoft.DotNet.Darc.Helpers;
-using Microsoft.DotNet.Darc.Models;
-using Microsoft.DotNet.Darc.Options;
-using Microsoft.Extensions.Logging;
using System;
using System.IO;
using System.Threading.Tasks;
using Maestro.Common.AppCredentials;
+using Microsoft.DotNet.Darc.Helpers;
+using Microsoft.DotNet.Darc.Models.PopUps;
+using Microsoft.DotNet.Darc.Options;
+using Microsoft.Extensions.Logging;
namespace Microsoft.DotNet.Darc.Operations;
diff --git a/src/Microsoft.DotNet.Darc/Darc/Operations/Operation.cs b/src/Microsoft.DotNet.Darc/Darc/Operations/Operation.cs
index ec4b81b84a..dbf00aae9b 100644
--- a/src/Microsoft.DotNet.Darc/Darc/Operations/Operation.cs
+++ b/src/Microsoft.DotNet.Darc/Darc/Operations/Operation.cs
@@ -58,25 +58,10 @@ protected Operation(ICommandLineOptions options, IServiceCollection? services =
services.TryAddSingleton(sp => sp.GetRequiredService());
services.TryAddTransient(sp => sp.GetRequiredService>());
services.TryAddTransient();
- services.Configure(o =>
- {
- o["default"] = new AzureDevOpsCredentialResolverOptions
- {
- Token = options.AzureDevOpsPat,
- FederatedToken = options.FederatedToken,
- DisableInteractiveAuth = options.IsCi,
- };
- });
- services.TryAddSingleton();
- services.TryAddSingleton(s =>
- new AzureDevOpsClient(
- s.GetRequiredService(),
- s.GetRequiredService(),
- s.GetRequiredService())
- );
- services.TryAddSingleton(s =>
- s.GetRequiredService()
- );
+ services.TryAddSingleton();
+ services.TryAddSingleton();
+ services.TryAddTransient(sp => sp.GetRequiredService>());
+ services.AddSingleton(_ => options.GetAzdoTokenProvider());
services.TryAddSingleton(_ => new RemoteTokenProvider(options.AzureDevOpsPat, options.GitHubPat));
Provider = services.BuildServiceProvider();
diff --git a/src/Microsoft.DotNet.Darc/Darc/Options/CommandLineOptions.cs b/src/Microsoft.DotNet.Darc/Darc/Options/CommandLineOptions.cs
index cfb1f56b3a..c8bd4b10c7 100644
--- a/src/Microsoft.DotNet.Darc/Darc/Options/CommandLineOptions.cs
+++ b/src/Microsoft.DotNet.Darc/Darc/Options/CommandLineOptions.cs
@@ -27,7 +27,7 @@ public abstract class CommandLineOptions : ICommandLineOptions
[RedactFromLogging]
public string GitHubPat { get; set; }
- [Option("azdev-pat", HelpText = "Token used to authenticate to Azure DevOps.")]
+ [Option("azdev-pat", HelpText = "Optional token used to authenticate to Azure DevOps. When not provided, local credentials are used.")]
[RedactFromLogging]
public string AzureDevOpsPat { get; set; }
@@ -67,7 +67,6 @@ public IAzureDevOpsTokenProvider GetAzdoTokenProvider()
["default"] = new AzureDevOpsCredentialResolverOptions
{
Token = AzureDevOpsPat,
- FederatedToken = FederatedToken,
DisableInteractiveAuth = IsCi,
}
};
diff --git a/src/Microsoft.DotNet.Darc/DarcLib/AzureDevOpsClient.cs b/src/Microsoft.DotNet.Darc/DarcLib/AzureDevOpsClient.cs
index 701e667f04..d154ce7019 100644
--- a/src/Microsoft.DotNet.Darc/DarcLib/AzureDevOpsClient.cs
+++ b/src/Microsoft.DotNet.Darc/DarcLib/AzureDevOpsClient.cs
@@ -59,11 +59,6 @@ public AzureDevOpsClient(IAzureDevOpsTokenProvider tokenProvider, IProcessManage
{
}
- public AzureDevOpsClient(IAzureDevOpsTokenProvider tokenProvider, IProcessManager processManager, ILogger logger)
- : this(tokenProvider, processManager, (ILogger)logger)
- {
- }
-
public AzureDevOpsClient(IAzureDevOpsTokenProvider tokenProvider, IProcessManager processManager, ILogger logger, string temporaryRepositoryPath)
: base(tokenProvider, processManager, temporaryRepositoryPath, null, logger)
{
diff --git a/src/Microsoft.DotNet.Darc/DarcLib/IAzureDevOpsClient.cs b/src/Microsoft.DotNet.Darc/DarcLib/IAzureDevOpsClient.cs
index b7d3374c86..03bae3b0d1 100644
--- a/src/Microsoft.DotNet.Darc/DarcLib/IAzureDevOpsClient.cs
+++ b/src/Microsoft.DotNet.Darc/DarcLib/IAzureDevOpsClient.cs
@@ -54,6 +54,15 @@ public interface IAzureDevOpsClient
/// AzureDevOpsBuild
Task GetBuildAsync(string accountName, string projectName, long buildId);
+ ///
+ /// Fetches artifacts belonging to a given AzDO build.
+ ///
+ /// Azure DevOps account name
+ /// Project name
+ /// Id of the build to be retrieved
+ /// List of build artifacts
+ Task> GetBuildArtifactsAsync(string accountName, string projectName, int buildId, int maxRetries = 15);
+
///
/// Gets a specified Artifact feed with their pacckages in an Azure DevOps account.
///
@@ -120,8 +129,27 @@ public interface IAzureDevOpsClient
Task GetReleaseDefinitionAsync(string accountName, string projectName, long releaseDefinitionId);
///
- /// Trigger a new release using the release definition informed. No change is performed
- /// on the release definition - it is used as is.
+ /// Queue a new build on the specified build definition with the given queue time variables.
+ ///
+ /// Account where the project is hosted.
+ /// Project where the build definition is.
+ /// ID of the build definition where a build should be queued.
+ /// Queue time variables as a Dictionary of (variable name, value).
+ /// Template parameters as a Dictionary of (variable name, value).
+ /// Pipeline resources as a Dictionary of (pipeline resource name, build number).
+ Task StartNewBuildAsync(
+ string accountName,
+ string projectName,
+ int buildDefinitionId,
+ string sourceBranch,
+ string sourceVersion,
+ Dictionary queueTimeVariables = null,
+ Dictionary templateParameters = null,
+ Dictionary pipelineResources = null);
+
+ ///
+ /// Trigger a new release using the release definition informed. No change is performed
+ /// on the release definition - it is used as is.
///
/// Azure DevOps account name
/// Project name
diff --git a/src/ProductConstructionService/ProductConstructionService.Api/appsettings.Development.json b/src/ProductConstructionService/ProductConstructionService.Api/appsettings.Development.json
index c73303efd3..d0ba399962 100644
--- a/src/ProductConstructionService/ProductConstructionService.Api/appsettings.Development.json
+++ b/src/ProductConstructionService/ProductConstructionService.Api/appsettings.Development.json
@@ -25,5 +25,8 @@
"Database": "engineeringdata",
"KustoClusterUri": "https://engdata.westus2.kusto.windows.net",
"UseAzCliAuthentication": true
+ },
+ "AzureDevOps": {
+ "default": {}
}
}
diff --git a/test/FeedCleaner.Tests/FeedCleanerServiceTests.cs b/test/FeedCleaner.Tests/FeedCleanerServiceTests.cs
index 96d19266a8..fdc7379b31 100644
--- a/test/FeedCleaner.Tests/FeedCleanerServiceTests.cs
+++ b/test/FeedCleaner.Tests/FeedCleanerServiceTests.cs
@@ -63,7 +63,7 @@ public void FeedCleanerServiceTests_SetUp()
];
}
);
- services.AddAzureDevOpsTokenProvider();
+ services.AddSingleton();
services.Configure(
(options) =>
{