Skip to content

Commit c3599a5

Browse files
authored
UniversalPackages: Adjust to upcoming changes in the Artifacts Cred Provider release structure (#655)
1 parent dbd0271 commit c3599a5

1 file changed

Lines changed: 46 additions & 29 deletions

File tree

src/UniversalPackages/DownloadUniversalPackages.cs

Lines changed: 46 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
namespace Microsoft.Build.UniversalPackages;
66

77
using System.Diagnostics;
8+
#if !NETFRAMEWORK
9+
using System.Formats.Tar;
10+
#endif
811
using System.IO;
912
using System.IO.Compression;
1013
#if NETFRAMEWORK
@@ -706,7 +709,7 @@ private string GetArtifactToolReleaseInfoUrl(string osName, string arch)
706709
releaseInfo.Value.DownloadUri,
707710
credentialProviderDir,
708711
GetArtifactsCredentialProviderRelativePath(),
709-
isZip: RuntimeInformation.IsOSPlatform(OSPlatform.Windows));
712+
isZip: releaseInfo.Value.DownloadUri.EndsWith(".zip", StringComparison.OrdinalIgnoreCase));
710713
if (!downloadResult)
711714
{
712715
return null;
@@ -754,38 +757,42 @@ private string GetArtifactToolReleaseInfoUrl(string osName, string arch)
754757
Log.LogMessage($"Current Artifacts Credential Provider version: {version}");
755758

756759
string rid;
757-
string fileExtension;
758760
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
759761
{
760762
rid = "win-x64";
761-
fileExtension = ".zip";
762763
}
763764
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
764765
{
765766
rid = RuntimeInformation.ProcessArchitecture == Architecture.Arm64
766767
? "linux-arm64"
767768
: "linux-x64";
768-
fileExtension = ".tar.gz";
769769
}
770770
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
771771
{
772772
rid = RuntimeInformation.ProcessArchitecture == Architecture.Arm64
773773
? "osx-arm64"
774774
: "osx-x64";
775-
fileExtension = ".zip";
776775
}
777776
else
778777
{
779778
Log.LogError($"Could not determine correct runtime to download the Artifact Credential Provider.");
780779
return null;
781780
}
782781

783-
string fileNamePattern = $@"Microsoft.Net(\d+).{rid}.NuGet.CredentialProvider{fileExtension}";
782+
// We currently only support zip on with .NET Framework.
783+
#if NETFRAMEWORK
784+
const string fileExtention = "zip";
785+
#else
786+
const string fileExtention = @"(zip|tar\.gz)";
787+
#endif
788+
string fileNamePattern = $@"Microsoft(\.Net(?<RuntimeVersion>\d+))?\.{rid}\.NuGet\.CredentialProvider\.{fileExtention}";
784789
Log.LogMessage(MessageImportance.Low, $"Looking for Artifacts Credential Provider asset with name: {fileNamePattern}");
785-
Regex fileNameRegex = new Regex(fileNamePattern, RegexOptions.IgnoreCase);
790+
Regex fileNameRegex = new Regex(fileNamePattern, RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture);
791+
792+
List<JsonElement> matchingAssets = new List<JsonElement>();
786793

787-
int maxNetVersion = 0;
788-
string? maxVersionDownloadUrl = null;
794+
int maxRuntimeVersion = 0;
795+
string? downloadUri = null;
789796
foreach (JsonElement asset in root.GetProperty("assets").EnumerateArray())
790797
{
791798
string? assetName = asset.GetProperty("name").GetString();
@@ -800,27 +807,38 @@ private string GetArtifactToolReleaseInfoUrl(string osName, string arch)
800807
continue;
801808
}
802809

803-
string netVersionStr = match.Groups[1].Value;
804-
if (!int.TryParse(netVersionStr, out int netVersion))
810+
Group runtimeVersionGroup = match.Groups["RuntimeVersion"];
811+
if (runtimeVersionGroup.Success)
805812
{
806-
continue;
807-
}
813+
if (!int.TryParse(runtimeVersionGroup.Value, out int runtimeVersion))
814+
{
815+
continue;
816+
}
808817

809-
if (netVersion > maxNetVersion)
818+
// Prefer the highest runtime version available.
819+
// Note: Starting in v2 the runtime version is no longer included in the asset name for self-contained flavors of the tool (names sense; it's self-contained).
820+
// Once v2 ships and is stable, this logic can be removed entirely in favor of the pattern without the version.
821+
if (runtimeVersion > maxRuntimeVersion)
822+
{
823+
maxRuntimeVersion = runtimeVersion;
824+
downloadUri = asset.GetProperty("browser_download_url").GetString();
825+
}
826+
}
827+
else
810828
{
811-
maxNetVersion = netVersion;
812-
maxVersionDownloadUrl = asset.GetProperty("browser_download_url").GetString();
829+
downloadUri = asset.GetProperty("browser_download_url").GetString();
830+
831+
// Newer releases do not have the runtime version in the name, so short circuit once we find one.
832+
break;
813833
}
814834
}
815835

816-
if (maxVersionDownloadUrl is null)
836+
if (downloadUri is null)
817837
{
818838
Log.LogError($"Unable to find a download url for the Artifact Credential Provider.");
819839
return null;
820840
}
821841

822-
string downloadUri = maxVersionDownloadUrl;
823-
824842
return (version, downloadUri);
825843
}
826844

@@ -878,19 +896,18 @@ private bool DownloadAndExtractArchive(string displayName, string downloadUri, s
878896
}
879897
else
880898
{
881-
// There is no built-in support for extracting tar.gz files, so fall back to the tar command.
882-
// Note: the tar command requires that the destination directory already exist.
899+
#if NETFRAMEWORK
900+
Log.LogError($"Extracting non-zip archives is not supported in this scenario.");
901+
return false;
902+
#else
883903
Directory.CreateDirectory(archiveExtractPath);
884-
int exitCode = ProcessHelper.Execute(
885-
"/bin/bash",
886-
$"-c \"tar -xzf \\\"{archiveDownloadPath}\\\" -C \\\"{archiveExtractPath}\\\"\"",
887-
processStdOut: message => Log.LogMessage(MessageImportance.Low, message),
888-
processStdErr: message => Log.LogError(message));
889-
if (exitCode != 0)
904+
905+
using (var archiveStream = File.OpenRead(archiveDownloadPath))
906+
using (var archiveGzipStream = new GZipStream(archiveStream, CompressionMode.Decompress))
890907
{
891-
Log.LogError($"Extracting Artifacts Credential Provider failed with exit code: {exitCode}");
892-
return false;
908+
TarFile.ExtractToDirectory(archiveGzipStream, archiveExtractPath, overwriteFiles: false);
893909
}
910+
#endif
894911
}
895912

896913
Log.LogMessage(MessageImportance.Low, "Extracted Artifacts Credential Provider");

0 commit comments

Comments
 (0)