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

Extract release report #7

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
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
118 changes: 7 additions & 111 deletions src/Distroessed/Program.cs
Original file line number Diff line number Diff line change
@@ -1,36 +1,23 @@
using DotnetRelease;
using EndOfLifeDate;

if (args.Length is 0 || !int.TryParse(args[0], out int majorVersion))
{
ReportInvalidArgs();
return;
}

string? baseUrl = args.Length > 1 ? args[1] : null;

string version = $"{majorVersion}.0";
string baseDefaultURL = "https://raw.githubusercontent.com/dotnet/core/main/release-notes/";
string baseUrl = args.Length > 1 ? args[1] : baseDefaultURL;
bool preferWeb = baseUrl.StartsWith("https");
HttpClient client= new();
DateOnly threeMonthsDate = DateOnly.FromDateTime(DateTime.UtcNow.AddMonths(3));
string supportMatrixUrl, releaseUrl;
string supportMatrixUrl = ReleaseNotes.GetUri(ReleaseNotes.SupportedOS, version, baseUrl);
string releaseUrl = ReleaseNotes.GetUri(ReleaseNotes.Releases, version, baseUrl);
bool preferWeb = supportMatrixUrl.StartsWith("https");
SupportedOSMatrix? matrix = null;
MajorReleaseOverview? majorRelease = null;
ReportOverview report = new(DateTime.UtcNow, version, []);

if (preferWeb)
{
supportMatrixUrl = $"{baseUrl}/{version}/supported-os.json";
releaseUrl = $"{baseUrl}/{version}/releases.json";
}
else
{
supportMatrixUrl = Path.Combine(baseUrl, version,"supported-os.json");
releaseUrl = Path.Combine(baseUrl, version,"releases.json");
}

if (preferWeb)
{
HttpClient client = new();
matrix = await ReleaseNotes.GetSupportedOSes(client, supportMatrixUrl);
majorRelease = await ReleaseNotes.GetMajorRelease(client, releaseUrl);
}
Expand All @@ -40,98 +27,7 @@
majorRelease = await ReleaseNotes.GetMajorRelease(File.OpenRead(releaseUrl));
}

DateOnly initialRelease = majorRelease?.Releases.FirstOrDefault(r => r.ReleaseVersion.Equals($"{majorVersion}.0.0"))?.ReleaseDate ?? DateOnly.MaxValue;
DateOnly eolDate = majorRelease?.EolDate ?? DateOnly.MaxValue;

foreach (SupportFamily family in matrix?.Families ?? throw new Exception())
{
ReportFamily reportFamily = new(family.Name, []);
report.Families.Add(reportFamily);

foreach (SupportDistribution distro in family.Distributions)
{
IList<SupportCycle>? cycles;
List<string> activeReleases = [];
List<string> unsupportedActiveRelease = [];
List<string> soonEolReleases = [];
List<string> supportedUnActiveReleases = [];
List<string> missingReleases = [];

try
{
cycles = await EndOfLifeDate.Product.GetProduct(client, distro.Id);
if (cycles is null)
{
continue;
}
}
catch (HttpRequestException)
{
Console.WriteLine($"No data found at endoflife.date for: {distro.Id}");
Console.WriteLine();
continue;
}

foreach (SupportCycle cycle in cycles)
{
SupportInfo support = cycle.GetSupportInfo();
// dotnet statements
bool isSupported = distro.SupportedVersions.Contains(cycle.Cycle);
bool isUnsupported = distro.UnsupportedVersions?.Contains(cycle.Cycle) ?? false;
// EndofLife.Date statement
bool isActive = support.IsActive;
bool hasOverlappingLifecycle = initialRelease <= support.EolDate && cycle.ReleaseDate <= eolDate;

if (isActive)
{
activeReleases.Add(cycle.Cycle);
}

/*
Cases (EOLDate, dotnet):
1. (Active, Supported)
2. (Active, Unsupported)
3. (OverlappingLifecycle, Unlisted)
4. (EOL, Supported)
5. (Active - EolSoon, Supported)
// these are not covered
6. (Unlisted, Listed)
7. (EOL, Unsupported | Unlisted)
8. (Listed, Unlisted)
*/

// Case 1
if (isActive && isSupported)
{
// nothing to do
}
// Case 2
else if (isActive && isUnsupported)
{
unsupportedActiveRelease.Add(cycle.Cycle);
}
// Case 3
else if (hasOverlappingLifecycle && !isSupported && !isUnsupported)
{
missingReleases.Add(cycle.Cycle);
}
// Case 4
else if (!isActive && isSupported)
{
supportedUnActiveReleases.Add(cycle.Cycle);
}

if (isActive && support.EolDate < threeMonthsDate)
{
soonEolReleases.Add(cycle.Cycle);
}
}

ReportDistribution reportDistribution = new(distro.Name, activeReleases, unsupportedActiveRelease, soonEolReleases, supportedUnActiveReleases, missingReleases);
reportFamily.Distributions.Add(reportDistribution);
}
}

var report = await ReleaseReportGenerator.GetReportOverviewAsync(matrix, majorRelease);
var reportJson = ReleaseReport.WriteReport(report);

Console.WriteLine(reportJson);
Expand Down
3 changes: 1 addition & 2 deletions src/Distroessed/distroessed.csproj
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<ItemGroup>
<ProjectReference Include="..\DotnetRelease\DotnetRelease.csproj" />
<ProjectReference Include="..\EndOfLifeDate\EndOfLifeDate.csproj" />
<ProjectReference Include="..\ReleaseReport\ReleaseReport.csproj" />
</ItemGroup>

<PropertyGroup>
Expand Down
10 changes: 10 additions & 0 deletions src/DotnetRelease/PatchReleaseOverviewRecords.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ public record RuntimeComponent(
JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
string VSVersion,

[property: Description("The version of Visual Studio on MacOS that includes this component version."),
JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
string VSMacVersion,

[property: Description("The files that are available for this component.")]
IList<ComponentFile> Files,

Expand All @@ -100,9 +104,15 @@ public record SdkComponent(
[property: Description("The version of Visual Studio that includes this component version.")]
string VSVersion,

[property: Description("The version of Visual Studio on MacOS that includes this component version.")]
string VSMacVersion,

[property: Description("The minimum version of Visual Studio that supports this component version.")]
string VSSupport,

[property: Description("The minimum version of Visual Studio on MacOS that supports this component version.")]
string VSMacSupport,

[property: Description("The version of C# included in the component."),
JsonPropertyName("csharp-version")]
string CSharpVersion,
Expand Down
10 changes: 10 additions & 0 deletions src/DotnetRelease/ReleaseNotes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ public class ReleaseNotes

public static string Releases { get; private set; } = "releases.json";

public static string PatchRelease { get; private set; } = "release.json";

public static string SupportedOS { get; private set; } = "supported-os.json";

public static string PreviewDirectory { get; private set; } = "preview";
Expand Down Expand Up @@ -77,6 +79,14 @@ public static ReleaseName GetReleaseName(string version)
return new(name, "preview", true);
}
}

public static string GetUri(string fileName, string version, string? baseUri = null)
{
baseUri ??= GitHubBaseUri;
return baseUri.StartsWith("https")
? $"{baseUri}/{version}/{fileName}"
: Path.Combine(baseUri, version, fileName);
}
}

public record ReleaseName(string Name, string Folder, bool IsPreview);
2 changes: 1 addition & 1 deletion src/DotnetRelease/ReleaseReportRecords.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ public record ReportOverview(DateTime Timestamp, string Version, IList<ReportFam

public record ReportFamily(string Name, IList<ReportDistribution> Distributions);

public record ReportDistribution(string Name, IList<string> ActiveReleases, IList<string> ActiveReleasesUnsupported, IList<string> ActiveReleasesEOLSoon, IList<string> NotActiveReleasesSupported, IList<string> ReleasesMissing);
public record ReportDistribution(string Name, IList<string> ActiveReleases, IList<string> ActiveReleasesUnsupported, IList<string> ActiveReleasesEOLSoon, IList<string> NotActiveReleasesSupported, IList<string> NotActiveReleasesUnsupported, IList<string> ReleasesMissing);
1 change: 0 additions & 1 deletion src/DotnetRelease/SerializerContext.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System.Text.Json;
using System.Text.Json.Serialization;

namespace DotnetRelease;
Expand Down
4 changes: 0 additions & 4 deletions src/DotnetRelease/SupportedOS.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
using System.Net.Http.Json;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace DotnetRelease;

public class SupportedOS
Expand Down
4 changes: 1 addition & 3 deletions src/LinuxPackagesMd/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@

if (!packageJson.EndsWith(".json"))
{
packageJson = preferWeb ?
$"{baseUrl}/{version}/os-packages.json" :
Path.Combine(baseUrl, version,"os-packages.json");
packageJson = ReleaseNotes.GetUri(ReleaseNotes.OSPackages, version, baseUrl);
}

string file = "os-packages.md";
Expand Down
2 changes: 1 addition & 1 deletion src/MarkdownHelpers/BreakBuffer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ namespace MarkdownHelpers;

public class BreakBuffer(StringBuilder builder, int index = 0)
{
StringBuilder _builder = builder;
readonly StringBuilder _builder = builder;
int _index = index;

public void Append(string value)
Expand Down
2 changes: 0 additions & 2 deletions src/MarkdownHelpers/Link.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
using System.Collections.Specialized;

namespace MarkdownHelpers;

public class Link(int startingIndex = 0)
Expand Down
8 changes: 1 addition & 7 deletions src/MarkdownHelpers/Table.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Common;
using System.IO.Compression;
using System.Text;
using Microsoft.VisualBasic.FileIO;

namespace MarkdownHelpers;

public class Table(IWriter writer, int[] columns)
{
private readonly IWriter _writer = writer;
private int[] _columns = columns;
private readonly int[] _columns = columns;
private readonly int _columnMax = columns.Length - 1;
private int _column = 0;
private int _realLength = 0;
Expand Down
14 changes: 14 additions & 0 deletions src/ReleaseReport/ReleaseReport.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

<ItemGroup>
<ProjectReference Include="..\DotnetRelease\DotnetRelease.csproj" />
<ProjectReference Include="..\EndOfLifeDate\EndOfLifeDate.csproj" />
</ItemGroup>

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>
116 changes: 116 additions & 0 deletions src/ReleaseReport/ReleaseReportGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
using DotnetRelease;
using EndOfLifeDate;

public class ReleaseReportGenerator
{
public static async Task<ReportOverview> GetReportOverviewAsync(SupportedOSMatrix? matrix, MajorReleaseOverview? majorRelease)
{
string version = matrix?.ChannelVersion
?? majorRelease?.ChannelVersion
?? "0.0";
HttpClient client = new();
DateOnly threeMonthsDate = DateOnly.FromDateTime(DateTime.UtcNow.AddMonths(3));
DateOnly initialRelease = majorRelease?.Releases.FirstOrDefault(r => r.ReleaseVersion.Equals($"{version}.0"))?.ReleaseDate ?? DateOnly.MaxValue;
DateOnly eolDate = majorRelease?.EolDate ?? DateOnly.MaxValue;
ReportOverview report = new(DateTime.UtcNow, version, []);

foreach (SupportFamily family in matrix?.Families ?? throw new Exception())
{
ReportFamily reportFamily = new(family.Name, []);
report.Families.Add(reportFamily);

foreach (SupportDistribution distro in family.Distributions)
{
IList<SupportCycle>? cycles;
List<string> activeReleases = [];
List<string> unsupportedActiveRelease = [];
List<string> soonEolReleases = [];
List<string> supportedUnActiveReleases = [];
List<string> unsupportedUnActiveReleases = [];
List<string> missingReleases = [];

try
{
cycles = await EndOfLifeDate.Product.GetProduct(client, distro.Id);
if (cycles is null)
{
continue;
}
}
catch (HttpRequestException)
{
Console.WriteLine($"No data found at endoflife.date for: {distro.Id}");
Console.WriteLine();
continue;
}

foreach (SupportCycle cycle in cycles)
{
SupportInfo support = cycle.GetSupportInfo();
// dotnet statements
bool isSupported = distro.SupportedVersions.Contains(cycle.Cycle);
bool isUnsupported = distro.UnsupportedVersions?.Contains(cycle.Cycle) ?? false;
// EndofLife.Date statement
bool isActive = support.IsActive;
bool hasOverlappingLifecycle = initialRelease <= support.EolDate && cycle.ReleaseDate <= eolDate;

if (isActive)
{
activeReleases.Add(cycle.Cycle);
}

/*
Cases (EOLDate, dotnet):
1. (Active, Supported)
2. (Active, Unsupported)
3. (OverlappingLifecycle, Unlisted)
4. (EOL, Supported)
5. (EOL, Unsupported)
6. (Active - EolSoon, Supported)
// these are not covered
7. (Listed, Unlisted)
8. (EOL, Unlisted)
9. (Unlisted, Listed)
*/

// Case 1
if (isActive && isSupported)
{
// nothing to do
}
// Case 2
else if (isActive && isUnsupported)
{
unsupportedActiveRelease.Add(cycle.Cycle);
}
// Case 3
else if (hasOverlappingLifecycle && !isSupported && !isUnsupported)
{
missingReleases.Add(cycle.Cycle);
}
// Case 4
else if (!isActive && isSupported)
{
supportedUnActiveReleases.Add(cycle.Cycle);
}
// Case 5
else if (!isActive && isUnsupported)
{
unsupportedUnActiveReleases.Add(cycle.Cycle);
}

// Case 6
if (isActive && support.EolDate < threeMonthsDate)
{
soonEolReleases.Add(cycle.Cycle);
}
}

ReportDistribution reportDistribution = new(distro.Name, activeReleases, unsupportedActiveRelease, soonEolReleases, supportedUnActiveReleases, unsupportedUnActiveReleases, missingReleases);
reportFamily.Distributions.Add(reportDistribution);
}
}

return report;
}
}
Loading