Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adding v0 release to feed #530

Merged
merged 3 commits into from
May 16, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
13 changes: 10 additions & 3 deletions GenerateToolingFeed/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,15 @@ public class Constants
{ "arm64" ,"arm64" }
};

public const string FeedAllVersions = "cli-feed-v3.json";
public const string FeedV4FormatAllVersions = "cli-feed-v4.json";
public const string FeedV1AndV2Only = "cli-feed-v3-2.json";
public const string CliFeedV3 = "cli-feed-v3.json";
public const string CliFeedV4 = "cli-feed-v4.json";
public const string CliFeedV32 = "cli-feed-v3-2.json";

public static readonly IDictionary<string, string> ReleaseVersionSuffix = new Dictionary<string, string>()
{
{
"v0", "-inprocess"
}
};
}
}
4 changes: 2 additions & 2 deletions GenerateToolingFeed/FeedEntryUpdaterFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ namespace GenerateToolingFeed
{
internal static class FeedEntryUpdaterFactory
{
public static IFeedEntryUpdater GetFeedEntryUpdater(FeedFormat format)
public static IFeedEntryUpdater GetFeedEntryUpdater(FeedFormat format, string tag)
{
switch (format)
{
case FeedFormat.V3:
return new V3FormatFeedEntryUpdater();
case FeedFormat.V4:
return new V4FormatFeedEntryUpdater();
return new V4FormatFeedEntryUpdater(tag);
default:
throw new InvalidOperationException($"Unidentified feed format '{format}'");
}
Expand Down
55 changes: 38 additions & 17 deletions GenerateToolingFeed/Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,51 @@ public class Helper
{
public static System.Net.Http.HttpClient HttpClient => _lazyClient.Value;

public static string GetDownloadLink(string os, string architecture, string cliVersion, bool isMinified = false)
public static string newReleaseVersion = string.Empty;

public static string GetDownloadLink(string os, string architecture, string cliVersion, bool isMinified = false, string linkSuffix = "")
{
string rid = string.Empty;
if (isMinified)
{
rid = "min.";
}
rid += GetRuntimeIdentifier(false, os, architecture);
var url = $"https://functionscdn.azureedge.net/public/{cliVersion}/Azure.Functions.Cli.{rid}.{cliVersion}.zip";
string rid = isMinified ? "min." : string.Empty;

// bypassing validation for now
rid += GetRuntimeIdentifier(false, os, architecture);
var url = $"https://functionscdn.azureedge.net/public/{cliVersion}/Azure.Functions.Cli.{rid}.{cliVersion}{linkSuffix}.zip";

if (!IsValidDownloadLink(url))
string bypassDownloadLinkValidation = Environment.GetEnvironmentVariable("bypassDownloadLinkValidation");
if (bypassDownloadLinkValidation != "1" && !IsValidDownloadLink(url))
{
throw new Exception($"{url} is not valid or no found. Cannot generate cli feed file");
}
return url;
}

public static string GetReleaseVersion(JToken jToken, int majorReleaseVersion)
public static void UpdateCoreToolsReferences(V4FormatCliEntry[] cliEntries, string coreToolsArtifactsDirectory, string cliVersion, string linkSuffix)
{
foreach (var cliEntry in cliEntries)
{
bool minified = ShouldBeMinified(cliEntry);

cliEntry.sha2 = GetShaFileContent(cliEntry.OS, cliEntry.Architecture, cliVersion, coreToolsArtifactsDirectory, minified);
cliEntry.downloadLink = GetDownloadLink(cliEntry.OS, cliEntry.Architecture, cliVersion, minified, linkSuffix);
}
}

public static bool ShouldBeMinified(V4FormatCliEntry cliEntry)
{
return !string.IsNullOrEmpty(cliEntry.size)
&& string.Equals(cliEntry.size, "minified", StringComparison.OrdinalIgnoreCase);
}

public static string GetNewReleaseVersion(JToken jToken, int majorReleaseVersion)
{
if (!string.IsNullOrEmpty(newReleaseVersion))
{
return newReleaseVersion;
}

List<String> versions = new List<string>();
foreach (JProperty item in jToken)
{
string name = item.Name;
string name = item.Name.Split("-").First();
if (name.StartsWith($"{majorReleaseVersion}."))
{
versions.Add(item.Name);
Expand All @@ -57,7 +77,8 @@ public static string GetReleaseVersion(JToken jToken, int majorReleaseVersion)
}).Where(v => v != null);
var maxVersion = nuGetVersions.OrderByDescending(p => p).FirstOrDefault();
Version releaseVersion = new Version(maxVersion.Major, maxVersion.Minor + 1, 0);
return releaseVersion.ToString();
newReleaseVersion = releaseVersion.ToString();
return newReleaseVersion;
}

public static string GetShaFileContent(string os, string architecture, string cliVersion, string filePath, bool isMinified = false)
Expand Down Expand Up @@ -166,11 +187,11 @@ public static string GetReleaseVersionFromTag(JObject json, string tag)
return releaseVersion;
}

public static string GetTagFromMajorVersion(int majorVersion) => majorVersion switch
public static List<string> GetTagsFromMajorVersion(int majorVersion) => majorVersion switch
{
2 => "v2",
3 => "v3",
4 => "v4",
2 => ["v2"],
3 => ["v3"],
4 => ["v4", "v0"],
_ => throw new ArgumentNullException($"{majorVersion} is not a supported version.", nameof(majorVersion))
};
}
Expand Down
67 changes: 31 additions & 36 deletions GenerateToolingFeed/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ class Program
{
private static readonly Dictionary<string, FeedFormat> _feedNameToFormat = new Dictionary<string, FeedFormat>()
{
{ Constants.FeedAllVersions, FeedFormat.V3 },
{ Constants.FeedV1AndV2Only, FeedFormat.V3 },
{ Constants.FeedV4FormatAllVersions, FeedFormat.V4 }
{ Constants.CliFeedV3, FeedFormat.V3 }, // update this feed for Functions v2 only.
{ Constants.CliFeedV32, FeedFormat.V3 }, // update this feed for Functions v2 and v3
{ Constants.CliFeedV4, FeedFormat.V4 }, // update v4 format feed for Functions v2, v3 and v4
};

static void Main(string[] args)
Expand All @@ -28,14 +28,14 @@ static void Main(string[] args)
// update this feed for Functions v2 only.
if (ver.Major == 2)
{
GenerateNewFeed(Constants.FeedV1AndV2Only, coreToolsInfo);
GenerateNewFeed(Constants.CliFeedV32, coreToolsInfo);
}

// update this feed for Functions v2 and v3
GenerateNewFeed(Constants.FeedAllVersions, coreToolsInfo);
GenerateNewFeed(Constants.CliFeedV3, coreToolsInfo);

// update v4 format feed for Functions v2 and v3
GenerateNewFeed(Constants.FeedV4FormatAllVersions, coreToolsInfo);
// update v4 format feed for Functions v2, v3 and v4
GenerateNewFeed(Constants.CliFeedV4, coreToolsInfo);
}
else
{
Expand Down Expand Up @@ -66,50 +66,53 @@ private static bool TryUpdateFeedWithNewToolsAndTemplates(JObject feed, FeedForm
{
try
{
// Get a cloned object to not modify the exisiting release
JObject currentReleaseEntryJson = GetCurrentReleaseEntry(feed, coreToolsInfo.MajorVersion).DeepClone() as JObject;
JObject newReleaseEntryJson = GetNewReleaseEntryJson(currentReleaseEntryJson, format, coreToolsInfo);
return TryAddNewReleaseToFeed(feed, newReleaseEntryJson, coreToolsInfo.MajorVersion);
List<string> tags = Helper.GetTagsFromMajorVersion(coreToolsInfo.MajorVersion);

bool result = true;
foreach (string tag in tags)
{
string releaseVersion = Helper.GetReleaseVersionFromTag(feed, tag);

// Get a cloned object to not modify the exisiting release
JObject currentReleaseEntryJson = feed["releases"][releaseVersion].DeepClone() as JObject;

JObject newReleaseEntryJson = GetNewReleaseEntryJson(currentReleaseEntryJson, format, coreToolsInfo, tag);

result &= TryAddNewReleaseToFeed(feed, newReleaseEntryJson, coreToolsInfo.MajorVersion, tag);
}
return result;
}
catch
{
return false;
}
}

private static JObject GetNewReleaseEntryJson(JObject currentReleaseEntry, FeedFormat format, CoreToolsInfo coreToolsInfo)
private static JObject GetNewReleaseEntryJson(JObject currentReleaseEntry, FeedFormat format, CoreToolsInfo coreToolsInfo, string tag)
{
IFeedEntryUpdater feedEntryUpdater = FeedEntryUpdaterFactory.GetFeedEntryUpdater(format);
IFeedEntryUpdater feedEntryUpdater = FeedEntryUpdaterFactory.GetFeedEntryUpdater(format, tag);
return feedEntryUpdater.GetUpdatedFeedEntry(currentReleaseEntry, coreToolsInfo);
}

private static bool TryAddNewReleaseToFeed(JObject feed, JObject newRelease, int majorVersion)
private static bool TryAddNewReleaseToFeed(JObject feed, JObject newRelease, int majorVersion, string tag)
{
JObject feedReleases = feed["releases"] as JObject;
string newReleaseVersion = Helper.GetReleaseVersion(feedReleases, majorVersion);
string newReleaseVersion = Helper.GetNewReleaseVersion(feedReleases, majorVersion);

if (newReleaseVersion == null)
{
return false;
}

string versionSuffix = Constants.ReleaseVersionSuffix.ContainsKey(tag) ? Constants.ReleaseVersionSuffix[tag] : string.Empty;
newReleaseVersion = $"{newReleaseVersion}{versionSuffix}";

feedReleases.Add(newReleaseVersion, newRelease);
UpdateFeedTagToNewVersion(feed, majorVersion, newReleaseVersion);
string prereleaseTag = $"{tag}-prerelease";
feed["tags"][prereleaseTag]["release"] = newReleaseVersion;
return true;
}

private static void UpdateFeedTagToNewVersion(JObject feed, int majorVersion, string newVersion)
{
string prereleaseTag = majorVersion switch
{
2 => "v2-prerelease",
3 => "v3-prerelease",
4 => "v4-prerelease",
_ => throw new ArgumentException($"Major version {majorVersion} is not supported.", nameof(majorVersion))
};
feed["tags"][prereleaseTag]["release"] = newVersion;
}

private static void WriteToJsonFile(JObject content, string path)
{
string feedString = JsonConvert.SerializeObject(content, Formatting.Indented);
Expand All @@ -125,14 +128,6 @@ private static JObject GetFeedJSON(string feedName)
return JObject.Parse(feedContent);
}

private static JObject GetCurrentReleaseEntry(JObject feed, int majorVersion)
{
string tag = Helper.GetTagFromMajorVersion(majorVersion);
string releaseVersion = Helper.GetReleaseVersionFromTag(feed, tag);

return feed["releases"][releaseVersion] as JObject;
}

private static string GetCliVersion(string path)
{
string cliVersion = string.Empty;
Expand Down
54 changes: 27 additions & 27 deletions GenerateToolingFeed/V4Format/V4FormatFeedEntryUpdater.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ namespace GenerateToolingFeed.V4Format
{
internal class V4FormatFeedEntryUpdater : IFeedEntryUpdater
{
private static readonly IDictionary<string, string> _dotnetToItemTemplates = new Dictionary<string, string>()
private readonly string _tag;

private readonly IDictionary<string, string> _dotnetToItemTemplates = new Dictionary<string, string>()
{
{ "net8", "Microsoft.Azure.WebJobs.ItemTemplates" },
{ "net8-isolated", "Microsoft.Azure.Functions.Worker.ItemTemplates.NetCore" },
{ "net7-isolated", "Microsoft.Azure.Functions.Worker.ItemTemplates.NetCore" },
{ "net6-isolated", "Microsoft.Azure.Functions.Worker.ItemTemplates.NetCore"},
Expand All @@ -19,8 +22,9 @@ internal class V4FormatFeedEntryUpdater : IFeedEntryUpdater
{ "netfx-isolated", "Microsoft.Azure.Functions.Worker.ItemTemplates.NetFx" }
};

private static readonly IDictionary<string, string> _dotnetToProjectTemplates = new Dictionary<string, string>()
private readonly IDictionary<string, string> _dotnetToProjectTemplates = new Dictionary<string, string>()
{
{ "net8", "Microsoft.Azure.WebJobs.ProjectTemplates" },
{ "net8-isolated", "Microsoft.Azure.Functions.Worker.ProjectTemplates" },
{ "net7-isolated", "Microsoft.Azure.Functions.Worker.ProjectTemplates" },
{ "net6-isolated", "Microsoft.Azure.Functions.Worker.ProjectTemplates" },
Expand All @@ -30,38 +34,34 @@ internal class V4FormatFeedEntryUpdater : IFeedEntryUpdater
{ "netcore2", "Microsoft.Azure.WebJobs.ProjectTemplates" },
{ "netframework", "Microsoft.Azure.WebJobs.ProjectTemplates" },
{ "netfx-isolated", "Microsoft.Azure.Functions.Worker.ProjectTemplates" }
};

};

private readonly IDictionary<string, string> _linkSuffix = new Dictionary<string, string>()
{
{
"v0", "_net8.0"
}
};

public V4FormatFeedEntryUpdater(string tag)
{
_tag = tag;
}

public JObject GetUpdatedFeedEntry(JObject feed, CoreToolsInfo coreToolsInfo)
{
V4FormatFeedEntry feedEntry = feed.ToObject<V4FormatFeedEntry>();

UpdateCoreToolsReferences(feedEntry.coreTools, coreToolsInfo.ArtifactsDirectory, coreToolsInfo.Version);
string linkSuffix = _linkSuffix.ContainsKey(_tag) ? _linkSuffix[_tag] : string.Empty;
soninaren marked this conversation as resolved.
Show resolved Hide resolved
Helper.UpdateCoreToolsReferences(feedEntry.coreTools, coreToolsInfo.ArtifactsDirectory, coreToolsInfo.Version, linkSuffix);
UpdateDotnetTemplatesToLatest(feedEntry.workerRuntimes, coreToolsInfo.MajorVersion);

Helper.MergeObjectToJToken(feed, feedEntry);

return feed;
}

private static void UpdateCoreToolsReferences(V4FormatCliEntry[] cliEntries, string coreToolsArtifactsDirectory, string cliVersion)
{
foreach (var cliEntry in cliEntries)
{
bool minified = ShouldBeMinified(cliEntry);

cliEntry.sha2 = Helper.GetShaFileContent(cliEntry.OS, cliEntry.Architecture, cliVersion, coreToolsArtifactsDirectory, minified);
cliEntry.downloadLink = Helper.GetDownloadLink(cliEntry.OS, cliEntry.Architecture, cliVersion, minified);
}
}

private static bool ShouldBeMinified(V4FormatCliEntry cliEntry)
{
return !string.IsNullOrEmpty(cliEntry.size)
&& string.Equals(cliEntry.size, "minified", StringComparison.OrdinalIgnoreCase);
}

private static void UpdateDotnetTemplatesToLatest(IDictionary<string, IDictionary<string, object>> workerRuntimes, int coreToolsMajor)
private void UpdateDotnetTemplatesToLatest(IDictionary<string, IDictionary<string, object>> workerRuntimes, int coreToolsMajor)
{
if (!workerRuntimes.TryGetValue("dotnet", out IDictionary<string, object> dotnetInfo))
{
Expand All @@ -78,10 +78,10 @@ private static void UpdateDotnetTemplatesToLatest(IDictionary<string, IDictionar
if (!_dotnetToItemTemplates.TryGetValue(dotnetEntryLabel, out string itemTemplates))
{
throw new Exception($"Cannot find the template package: Unidentified dotnet label '{dotnetEntryLabel}'.");
}
dotnetEntry.itemTemplates = Helper.GetTemplateUrl($"{itemTemplates}", coreToolsMajor);
}
dotnetEntry.itemTemplates = Helper.GetTemplateUrl($"{itemTemplates}", coreToolsMajor);
if (!_dotnetToProjectTemplates.TryGetValue(dotnetEntryLabel, out string projecTemplate))
{
throw new Exception($"Cannot find the template package: Unidentified dotnet label '{dotnetEntryLabel}'.");
Expand Down
Loading
Loading