From 2a950ed4e90f28b29ef052dcc52766b945643b58 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 29 Sep 2026 05:47:53 +0000 Subject: [PATCH] Verify SQL Server lifecycle dates and add SQL Server 2025 All mainstream and extended support end dates checked against Microsoft sources. SQL Server 2025 added (mainstream ends 2031-01-06, extended 2036-01-06), so the lifecycle rule now evaluates 2025 instead of reporting it as not measurable. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01E3EExwndy8Z22EK2Qpt6BK --- .../Lifecycle/support-lifecycle.json | 4 ++-- .../SupportLifecycleRuleTests.cs | 20 ++++++++++++++++--- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/SQLInsight.Rules/Lifecycle/support-lifecycle.json b/src/SQLInsight.Rules/Lifecycle/support-lifecycle.json index a39809f..27d3a50 100644 --- a/src/SQLInsight.Rules/Lifecycle/support-lifecycle.json +++ b/src/SQLInsight.Rules/Lifecycle/support-lifecycle.json @@ -1,6 +1,6 @@ { "source": "https://learn.microsoft.com/lifecycle/products/?terms=SQL%20Server", - "comment": "End of mainstream and extended support per release. null means not yet published in the catalog.", + "comment": "End of mainstream and extended support per release (Fixed Lifecycle Policy, RTM/latest service pack). Verified 2026-09-29 against Microsoft Lifecycle and Microsoft SQL Server blog announcements. null means not yet published. Extended Security Updates (paid) are deliberately not included: an instance on ESU is still out of standard support.", "releases": [ { "release": "SqlServer2000", "mainstreamEnd": "2008-04-08", "extendedEnd": "2013-04-09" }, { "release": "SqlServer2005", "mainstreamEnd": "2011-04-12", "extendedEnd": "2016-04-12" }, @@ -12,6 +12,6 @@ { "release": "SqlServer2017", "mainstreamEnd": "2022-10-11", "extendedEnd": "2027-10-12" }, { "release": "SqlServer2019", "mainstreamEnd": "2025-02-28", "extendedEnd": "2030-01-08" }, { "release": "SqlServer2022", "mainstreamEnd": "2028-01-11", "extendedEnd": "2033-01-11" }, - { "release": "SqlServer2025", "mainstreamEnd": null, "extendedEnd": null } + { "release": "SqlServer2025", "mainstreamEnd": "2031-01-06", "extendedEnd": "2036-01-06" } ] } diff --git a/tests/SQLInsight.Rules.Tests/SupportLifecycleRuleTests.cs b/tests/SQLInsight.Rules.Tests/SupportLifecycleRuleTests.cs index 40a4dcc..3ed9541 100644 --- a/tests/SQLInsight.Rules.Tests/SupportLifecycleRuleTests.cs +++ b/tests/SQLInsight.Rules.Tests/SupportLifecycleRuleTests.cs @@ -58,10 +58,20 @@ public class SupportLifecycleRuleTests } [Fact] - public void Release_without_published_dates_is_not_measurable() + public void Sql2025_is_in_mainstream_support() { var evaluation = Rule.Evaluate(TestInstances.Context("17.0.1000.7", Today)); + Assert.Equal(RuleOutcome.Passed, evaluation.Outcome); + } + + [Fact] + public void Release_without_published_dates_is_not_measurable() + { + var catalog = new SupportLifecycleCatalog([new SupportLifecycle(SqlServerRelease.SqlServer2025, null, null)]); + + var evaluation = new SupportLifecycleRule(catalog).Evaluate(TestInstances.Context("17.0.1000.7", Today)); + Assert.Equal(RuleOutcome.NotMeasurable, evaluation.Outcome); } @@ -81,13 +91,17 @@ public class SupportLifecycleRuleTests } [Fact] - public void Catalog_covers_every_known_release() + public void Catalog_has_dates_for_every_known_release() { var catalog = SupportLifecycleCatalog.LoadEmbedded(); foreach (var release in Enum.GetValues().Where(r => r != SqlServerRelease.Unknown)) { - Assert.NotNull(catalog.Find(release)); + var lifecycle = catalog.Find(release); + Assert.NotNull(lifecycle); + Assert.NotNull(lifecycle.MainstreamEnd); + Assert.NotNull(lifecycle.ExtendedEnd); + Assert.True(lifecycle.ExtendedEnd > lifecycle.MainstreamEnd, $"{release}: extended must end after mainstream"); } } }