Skip to content

Commit

Permalink
Use ProductVersion.txt where possible (#7837) (#7861)
Browse files Browse the repository at this point in the history
* Add ProductVersion.txt support where possible; get the version of the inner package from productVersion.txt, NOT from the specified version.  Allows "non-stable" outer container with "stable" inner contents

#7836
  • Loading branch information
MattGal authored Sep 9, 2021
1 parent 4063831 commit d17fe1b
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 8 deletions.
75 changes: 67 additions & 8 deletions src/Microsoft.DotNet.Helix/Sdk/FindDotNetCliPackage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Build.Framework;
using NuGet.Versioning;

namespace Microsoft.DotNet.Helix.Sdk
{
Expand Down Expand Up @@ -30,7 +31,7 @@ public class FindDotNetCliPackage : BaseTask
public string Runtime { get; set; }

/// <summary>
/// 'sdk', 'runtime' or 'aspnetcore-runtime'
/// 'sdk', 'runtime' or 'aspnetcore-runtime' (default is runtime)
/// </summary>
[Required]
public string PackageType { get; set; }
Expand All @@ -49,7 +50,7 @@ private async Task ExecuteAsync()
NormalizeParameters();
await ResolveVersionAsync();

string downloadUrl = GetDownloadUrl();
string downloadUrl = await GetDownloadUrlAsync();

Log.LogMessage($"Retrieved dotnet cli {PackageType} version {Version} package uri {downloadUrl}, testing...");

Expand Down Expand Up @@ -80,17 +81,75 @@ private async Task ExecuteAsync()
}
}

private string GetDownloadUrl()
private async Task<string> GetDownloadUrlAsync()
{
string extension = Runtime.StartsWith("win") ? "zip" : "tar.gz";
string effectiveVersion = await GetEffectiveVersion();

return PackageType switch
{
"sdk" => $"{DotNetCliAzureFeed}/Sdk/{Version}/dotnet-sdk-{Version}-{Runtime}.{extension}",
"aspnetcore-runtime" => $"{DotNetCliAzureFeed}/aspnetcore/Runtime/{Version}/aspnetcore-runtime-{Version}-{Runtime}.{extension}",
_ => $"{DotNetCliAzureFeed}/Runtime/{Version}/dotnet-runtime-{Version}-{Runtime}.{extension}"
"sdk" => $"{DotNetCliAzureFeed}/Sdk/{Version}/dotnet-sdk-{effectiveVersion}-{Runtime}.{extension}",
"aspnetcore-runtime" => $"{DotNetCliAzureFeed}/aspnetcore/Runtime/{Version}/aspnetcore-runtime-{effectiveVersion}-{Runtime}.{extension}",
_ => $"{DotNetCliAzureFeed}/Runtime/{Version}/dotnet-runtime-{effectiveVersion}-{Runtime}.{extension}"
};
}

private async Task<string> GetEffectiveVersion()
{
if (NuGetVersion.TryParse(Version, out NuGetVersion semanticVersion))
{
// Pared down version of the logic from https://github.com/dotnet/install-scripts/blob/main/src/dotnet-install.ps1
// If this functionality stops working, review changes made there.
// Current strategy is to start with a runtime-specific name then fall back to 'productVersion.txt'
string effectiveVersion = Version;

// Do nothing for older runtimes; the file won't exist
if (semanticVersion >= new NuGetVersion("5.0.0"))
{
var productVersionText = PackageType switch
{
"sdk" => await GetMatchingProductVersionTxtContents($"{DotNetCliAzureFeed}/Sdk/{Version}", "sdk-productVersion.txt"),
"aspnetcore-runtime" => await GetMatchingProductVersionTxtContents($"{DotNetCliAzureFeed}/aspnetcore/Runtime/{Version}", "aspnetcore-productVersion.txt"),
_ => await GetMatchingProductVersionTxtContents($"{DotNetCliAzureFeed}/Runtime/{Version}", "runtime-productVersion.txt")
};

if (!productVersionText.Equals(Version))
{
effectiveVersion = productVersionText;
Log.LogMessage($"Switched to effective .NET Core version '{productVersionText}' from matching productVersion.txt");
}
}
return effectiveVersion;
}
else
{
throw new ArgumentException($"'{Version}' is not a valid semantic version.");
}
}
private async Task<string> GetMatchingProductVersionTxtContents(string baseUri, string customVersionTextFileName)
{
using HttpResponseMessage specificResponse = await _client.GetAsync($"{baseUri}/{customVersionTextFileName}");
if (specificResponse.StatusCode == HttpStatusCode.NotFound)
{
using HttpResponseMessage genericResponse = await _client.GetAsync($"{baseUri}/productVersion.txt");
if (genericResponse.StatusCode != HttpStatusCode.NotFound)
{
genericResponse.EnsureSuccessStatusCode();
return (await genericResponse.Content.ReadAsStringAsync()).Trim();
}
else
{
Log.LogMessage(MessageImportance.Low, $"No *productVersion.txt files found for {Version} under {baseUri}");
}
}
else
{
specificResponse.EnsureSuccessStatusCode();
return (await specificResponse.Content.ReadAsStringAsync()).Trim();
}
return Version;
}

private void NormalizeParameters()
{
if (string.Equals(Channel, "lts", StringComparison.OrdinalIgnoreCase))
Expand Down Expand Up @@ -136,9 +195,9 @@ private async Task ResolveVersionAsync()
Log.LogMessage(MessageImportance.Low, "Resolving latest dotnet cli version.");
string latestVersionUrl = PackageType switch
{
"sdk" => $"{DotNetCliAzureFeed}/Sdk/{Channel}/latest.version",
"sdk" => $"{DotNetCliAzureFeed}/Sdk/{Channel}/latest.version",
"aspnetcore-runtime" => $"{DotNetCliAzureFeed}/aspnetcore/Runtime/{Channel}/latest.version",
_ => $"{DotNetCliAzureFeed}/Runtime/{Channel}/latest.version"
_ => $"{DotNetCliAzureFeed}/Runtime/{Channel}/latest.version"
};

Log.LogMessage(MessageImportance.Low, $"Resolving latest version from url {latestVersionUrl}");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<PackageReference Include="Microsoft.Build.Framework" Version="$(MicrosoftBuildFrameworkVersion)" />
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="$(MicrosoftBuildUtilitiesCoreVersion)" />
<PackageReference Include="Newtonsoft.Json" Version="$(NewtonsoftJsonVersion)" />
<PackageReference Include="NuGet.Versioning" Version="6.0.0-preview.4.230" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
</ItemGroup>

Expand Down

0 comments on commit d17fe1b

Please sign in to comment.