Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,16 @@ public class BuildModelFactoryTests
#region Standard test values

private const string _testAzdoRepoUri = "https://[email protected]/dnceng/internal/_git/dotnet-buildtest";
private const string _normalizedTestAzdoRepoUri = "https://dev.azure.com/dnceng/internal/_git/dotnet-buildtest";
private const string _testBuildBranch = "foobranch";
private const string _testBuildCommit = "664996a16fa9228cfd7a55d767deb31f62a65f51";
private const string _testAzdoBuildId = "89999999";
private const string _testInitialLocation = "As they say....Location Location Location!";
private const string _testInitialLocation = "https://dnceng.visualstudio.com/project/_apis/build/builds/id/artifacts";
private const string _normalizedTestInitialLocation = "https://dev.azure.com/dnceng/project/_apis/build/builds/id/artifacts";
private static readonly string[] _defaultManifestBuildData = new string[]
{
$"InitialAssetsLocation={_testInitialLocation}"
$"InitialAssetsLocation={_testInitialLocation}",
$"AzureDevOpsRepository={_testAzdoRepoUri}"
};

#endregion
Expand Down Expand Up @@ -165,6 +168,8 @@ public void ManifestArtifactParsingTest()
package.Attributes.Should().Contain("Id", "test-package-a");
package.Attributes.Should().Contain("Version", "1.0.0");
});

model.Identity.Attributes.Should().Contain("AzureDevOpsRepository", _normalizedTestAzdoRepoUri);
}

/// <summary>
Expand Down Expand Up @@ -290,7 +295,7 @@ public void InitialLocationInformationAttributesAreAccepted(string attributeName
_taskLoggingHelper.HasLoggedErrors.Should().BeFalse();

// Check that the build model has the initial assets location
model.Identity.Attributes.Should().Contain(attributeName, _testInitialLocation);
model.Identity.Attributes.Should().Contain(attributeName, _normalizedTestInitialLocation);
}

#endregion
Expand Down
48 changes: 48 additions & 0 deletions src/Microsoft.DotNet.Build.Tasks.Feed/src/BuildModelFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Xml.Linq;

namespace Microsoft.DotNet.Build.Tasks.Feed
Expand Down Expand Up @@ -71,6 +73,11 @@ public BuildModelFactory(

private const string AssetsVirtualDir = "assets/";

private static readonly string AzureDevOpsHostPattern = @"dev\.azure\.com\";

private readonly Regex LegacyRepositoryUriPattern = new Regex(
@"^https://(?<account>[a-zA-Z0-9]+)\.visualstudio\.com/");

/// <summary>
/// Create a build manifest for packages, blobs, and associated signing information
/// </summary>
Expand Down Expand Up @@ -204,6 +211,9 @@ private BuildModel CreateModel(
{
_log.LogError("Missing 'location' property from ManifestBuildData");
}

NormalizeUrisInBuildData(attributes);

BuildModel buildModel = new BuildModel(
new BuildIdentity
{
Expand Down Expand Up @@ -241,5 +251,43 @@ private bool ManifestBuildDataHasLocationInformation(IDictionary<string, string>
{
return attributes.ContainsKey("Location") || attributes.ContainsKey("InitialAssetsLocation");
}

private void NormalizeUrisInBuildData(IDictionary<string, string> attributes)
{
foreach(var attribute in attributes.ToList())
{
attributes[attribute.Key] = NormalizeAzureDevOpsUrl(attribute.Value);
}
}

/// <summary>
// If repoUri includes the user in the account we remove it from URIs like
// https://[email protected]/dnceng/internal/_git/repo
// If the URL host is of the form "dnceng.visualstudio.com" like
// https://dnceng.visualstudio.com/internal/_git/repo we replace it to "dev.azure.com/dnceng"
// for consistency
/// </summary>
/// <param name="repoUri">The original url</param>
/// <returns>Transformed url</returns>
private string NormalizeAzureDevOpsUrl(string repoUri)
{
if (Uri.TryCreate(repoUri, UriKind.Absolute, out Uri parsedUri))
{
if (!string.IsNullOrEmpty(parsedUri.UserInfo))
{
repoUri = repoUri.Replace($"{parsedUri.UserInfo}@", string.Empty);
}

Match m = LegacyRepositoryUriPattern.Match(repoUri);

if (m.Success)
{
string replacementUri = $"{Regex.Unescape(AzureDevOpsHostPattern)}/{m.Groups["account"].Value}";
repoUri = repoUri.Replace(parsedUri.Host, replacementUri);
}
}

return repoUri;
}
}
}