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
21 changes: 21 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,27 @@ remedy for those is to upgrade.
| 6.2.x | ✅ |
| < 6.2 | ❌ |

### For how long

There is no fixed end-of-support date. The current line targets **.NET 10** (`net10.0`, and EF Core
10 for the EF Core packages), and the intention is to keep it maintained for as long as Microsoft
supports that .NET release (.NET 10 is LTS, supported until November 2028), or until a new major of
this package supersedes it, whichever comes first — majors here are cheap, and a new one has never
meant the old one lost fixes before its successor shipped. If that intention changes, it is recorded
here before anywhere else.

### If this project stops being maintained

This is a single-maintainer project, and that is the honest continuity risk. The signal would be
unambiguous: the repository archived, the packages marked deprecated on nuget.org, and a note here.
Published versions stay on nuget.org regardless (a package can be unlisted, not removed), the code
is MIT-licensed, and the release path needs nothing but this repository — forking is the intended
continuity mechanism, not a fallback.

Advisories are published as GitHub Security Advisories, which reach the GitHub Advisory Database
and from there `dotnet restore` (NuGetAudit): a consumer on an affected version sees a build
warning without subscribing to anything.

## Where this package sits

Useful context for judging impact, and for anyone doing supply-chain due diligence.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,45 @@ public sealed class SecurityPolicyConventionTests
private static readonly Regex UnsupportedRow =
new(@"^\|\s*<\s*(?<major>\d+)\.(?<minor>\d+)\s*\|\s*❌\s*\|", RegexOptions.Multiline);

/// <summary>"the current line targets **.NET 10**" — the number the horizon statement is anchored to.</summary>
private static readonly Regex TargetsDotNet =
new(@"targets \*\*\.NET (?<major>\d+)\*\*", RegexOptions.None);

[TestMethod]
public void SecurityPolicy_Exists()
{
Assert.IsTrue(SecurityPolicy.Exists, $"No SECURITY.md at the repository root ({SecurityPolicy.FullName}).");
}

/// <summary>
/// The support horizon is phrased against the .NET major the packages target, and that number
/// lives in the core project's TargetFramework. When the TFM moves to net11.0 the sentence has
/// to move with it, or the policy promises support against a release the package no longer
/// targets.
/// </summary>
[TestMethod]
public void TheSupportHorizon_NamesTheTargetedDotNetMajor()
{
var text = File.ReadAllText(SecurityPolicy.FullName);
var match = TargetsDotNet.Match(text);

Assert.IsTrue(
match.Success,
"SECURITY.md has no 'targets **.NET N**' sentence in its support horizon — a consumer doing "
+ "due diligence needs to know which platform line the support intention is tied to.");

var core = RepoLayout.PackableProjects.Single(project => project.PackageId == "CodoMetis.ValueRanges");
var tfm = core.Property("TargetFramework") ?? "";
var tfmMajor = Regex.Match(tfm, @"^net(?<major>\d+)\.").Groups["major"].Value;

Assert.IsFalse(string.IsNullOrEmpty(tfmMajor), $"Could not read a net<major>.<minor> TargetFramework from {core.File.Name} (got '{tfm}').");

Assert.AreEqual(
tfmMajor, match.Groups["major"].Value,
$"SECURITY.md says the current line targets .NET {match.Groups["major"].Value}, but "
+ $"{core.File.Name} targets {tfm}. Move the horizon statement with the TargetFramework.");
}

[TestMethod]
public void TheSupportedVersionsTable_NamesTheShippedMinor()
{
Expand Down
Loading