File: src\AzureDevOpsNugetFeedAssetPublisher.cs
Web Access
Project: src\src\Microsoft.DotNet.Build.Tasks.Feed\Microsoft.DotNet.Build.Tasks.Feed.csproj (Microsoft.DotNet.Build.Tasks.Feed)
// 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.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using Microsoft.Build.Utilities;
using Microsoft.DotNet.Build.Tasks.Feed.Model;
#if !NET472_OR_GREATER
using Microsoft.DotNet.Maestro.Client.Models;
using NuGet.Packaging;
using NuGet.Packaging.Core;
using Task = System.Threading.Tasks.Task;
 
namespace Microsoft.DotNet.Build.Tasks.Feed
{
    public class AzureDevOpsNugetFeedAssetPublisher : IAssetPublisher, IDisposable
    {
        private readonly TaskLoggingHelper _log;
        private readonly string _targetUrl;
        private readonly string _accessToken;
        private readonly PublishArtifactsInManifestBase _task;
        private readonly string _feedAccount;
        private readonly string _feedVisibility;
        private readonly string _feedName;
        private readonly HttpClient _httpClient;
 
        public AzureDevOpsNugetFeedAssetPublisher(TaskLoggingHelper log, string targetUrl, string accessToken, PublishArtifactsInManifestBase task)
        {
            _log = log;
            _targetUrl = targetUrl;
            _accessToken = accessToken;
            _task = task;
 
            var parsedUri = Regex.Match(_targetUrl, PublishingConstants.AzDoNuGetFeedPattern);
            if (!parsedUri.Success)
            {
                throw new ArgumentException(
                    $"Azure DevOps NuGetFeed was not in the expected format '{PublishingConstants.AzDoNuGetFeedPattern}'");
            }
            _feedAccount = parsedUri.Groups["account"].Value;
            _feedVisibility = parsedUri.Groups["visibility"].Value;
            _feedName = parsedUri.Groups["feed"].Value;
 
            _httpClient = new HttpClient(new HttpClientHandler {CheckCertificateRevocationList = true})
            {
                Timeout = GeneralUtils.NugetFeedPublisherHttpClientTimeout,
                DefaultRequestHeaders =
                {
                    Authorization = new AuthenticationHeaderValue(
                        "Basic",
                        Convert.ToBase64String(Encoding.ASCII.GetBytes($":{_accessToken}")))
                },
            };
        }
 
        public void Dispose()
        {
            _httpClient?.Dispose();
        }
 
        public LocationType LocationType => LocationType.NugetFeed;
 
        public async Task PublishAssetAsync(string file, string blobPath, PushOptions options, SemaphoreSlim clientThrottle = null)
        {
            if (!file.EndsWith(GeneralUtils.PackageSuffix, StringComparison.OrdinalIgnoreCase))
            {
                _log.LogWarning(
                    $"AzDO feed publishing not available for blobs. Blob '{file}' was not published.");
                return;
            }
 
            string id;
            string version;
            using (var packageReader = new PackageArchiveReader(file))
            {
                PackageIdentity packageIdentity = packageReader.GetIdentity();
                id = packageIdentity.Id;
                version = packageIdentity.Version.ToString();
            }
 
            try
            {
                var config = new TargetFeedConfig(default, _targetUrl, default, default);
                await _task.PushNugetPackageAsync(config, _httpClient, file, id, version, _feedAccount, _feedVisibility, _feedName);
            }
            catch (Exception e)
            {
                _log.LogErrorFromException(e);
            }
        }
    }
}
#else
public class AzureDevOpsNugetFeedAssetPublisher : Task
{
    public override bool Execute() => throw new NotSupportedException("AzureDevOpsNugetFeedAssetPublisher depends on Maestro.Client, which has discontinued support for desktop frameworks.");
}
#endif