Breaking change in release.json files
There was a break in the format (top-level properties added) we use for the standalone release.json files. It broke my tools. Can it be backed out?
Before: https://github.com/dotnet/core/blob/main/release-notes/9.0/9.0.4/release.json After: https://github.com/dotnet/core/blob/main/release-notes/9.0/9.0.5/release.json
Affected 8.0 as well. I didn't check 10.0.
Do we have a test for validating JSON correctness? We must not. We should just adopt the tools I've been working on since they caught this. I wasn't running them recently so I only noticed it now.
One could argue that additions are not breaks. Here is how my OM is configured, which explains the behavior.
https://github.com/richlander/distroessed/blob/16b9ea1a335ebd440dc3de2e7b10559e00ca324b/src/DotnetRelease/PatchReleaseOverviewRecords.cs#L6
This is what the behavior looks like:
Unhandled exception. System.Text.Json.JsonException: The JSON property 'latest-release' could not be mapped to any .NET member contained in type 'DotnetRelease.PatchReleaseOverview'.
at System.Text.Json.ThrowHelper.ThrowJsonException_UnmappedJsonProperty(Type type, String unmappedPropertyName)
at System.Text.Json.JsonSerializer.LookupProperty(Object obj, ReadOnlySpan`1 unescapedPropertyName, ReadStack& state, JsonSerializerOptions options, Boolean& useExtensionProperty, Boolean createExtensionProperty)
at System.Text.Json.Serialization.Converters.ObjectWithParameterizedConstructorConverter`1.TryLookupConstructorParameter(ReadOnlySpan`1 unescapedPropertyName, ReadStack& state, JsonSerializerOptions options, JsonPropertyInfo& jsonPropertyInfo, JsonParameterInfo& jsonParameterInfo)
at System.Text.Json.Serialization.Converters.ObjectWithParameterizedConstructorConverter`1.ReadConstructorArgumentsWithContinuation(ReadStack& state, Utf8JsonReader& reader, JsonSerializerOptions options)
at System.Text.Json.Serialization.Converters.ObjectWithParameterizedConstructorConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, T& value, JsonSerializerOptions options, ReadStack& state)
at System.Text.Json.Serialization.Metadata.JsonTypeInfo`1.ContinueDeserialize(ReadBufferState& bufferState, JsonReaderState& jsonReaderState, ReadStack& readStack, T& value)
at System.Text.Json.Serialization.Metadata.JsonTypeInfo`1.DeserializeAsync(Stream utf8Json, CancellationToken cancellationToken)
at Program.<Main>$(String[] args) in /home/rich/git/distroessed/src/UpdateIndexes/Program.cs:line 54
at Program.<Main>$(String[] args) in /home/rich/git/distroessed/src/UpdateIndexes/Program.cs:line 57
at Program.<Main>$(String[] args) in /home/rich/git/distroessed/src/UpdateIndexes/Program.cs:line 65
at Program.<Main>(String[] args)
These files need to have a very conservative approach. I'm using the tools with normal behavior.
There are a few issues at play. I want to make sure to catalog them.
{
"channel-version": "9.0",
"release-date": "2025-04-08",
"release-version": "9.0.4",
"security": true,
"releases": [
{
"release-date": "2025-04-08",
"release-version": "9.0.4",
"security": true,
"cve-list": [
{
"cve-id": "CVE-2025-26682",
"cve-url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2025-26682"
}
],
"release-notes": "https://github.com/dotnet/core/blob/main/release-notes/9.0/9.0.4/9.0.4.md",
and
{
"channel-version": "9.0",
"latest-release": "9.0.5",
"latest-release-date": "2025-05-13",
"latest-runtime": "9.0.5",
"latest-sdk": "9.0.300",
"support-phase": "active",
"release-type": "sts",
"lifecycle-policy": "https://aka.ms/dotnetcoresupport",
"release":
{
"release-date": "2025-05-13",
"release-version": "9.0.5",
"security": true,
"cve-list": [
{
"cve-id": "CVE-2025-26646",
"cve-url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2025-26646"
}
],
"release-notes": "https://github.com/dotnet/core/blob/main/release-notes/9.0/9.0.5/9.0.5.md",
Issues at play:
- Different root properties
releases: []changed torelease: {}- The root
securityboolean is present at root and then not. It is impossible to write software will value types when they dissappear. If anyone is using that value and it isn't present, it will always befalse. Removing booleans is the worst kind of breaking change since it is a silent breaking change. It actually just broke me since I was using the root boolean by accident.
We should consider removing the top-level security booleans for supported releases. It is quite likely better to break consumers than leave them in place.
I think we only have a linter validation and our website uploader helps validate some things, but it is not thorough.