Skip to content

Updating release notes publishing #10143

@richlander

Description

@richlander

We have published release notes and announcements in JSON, markdown, and HTML formats for many years. We hope that's been useful! We are going to expand and improve our publishing model to address some persistent challenges, deliver on outstanding improvement requests, and enable direct LLM consumption.

There are multiple kinds of version numbers in the .NET ecosystem and that are used to describe releases in release notes. A major part of the new plan is being more intentional about exposing runtime, SDK, and other version numbers throughout the graph. Various users in various workflows will naturally reason about different kinds of version numbers and we want all of them to be usable and effective. These version numbers are thought of as "currency", a key to a certain lock, to mix metaphors.

We will publish new content in the official locations with a preview label for a few months to gather and to adapt to feedback before any schema-oriented formats are locked in for production use. We'll start publishing the new provisional formats soon. Assuming a positive response, we'll separately announce when the new formats are considered ready for production use, intended for the first half of 2026.

The following sections describes a plan for various aspects of our publishing activities. It doesn't go deep into intended formats or the specific information they will contain. It also doesn't describe best practices for using the release notes we publish. Those can be documented later. The intent is describe the problems we aim to solve and our general approach to resolving them. It's also context that can be linked to as the project progresses.

Release index

We publish a releases-index.json file as the root of our release notes information graph. Some users read this JSON file to learn the latest patch version numbers, while others navigate deeper into the graph. Both are legitimate patterns. However, we've found that our approach has fundamental flaws.

Problems:

  • Exposing patch versions in multiple files that need to agree is incompatible with using a Content Delivery Network (CDN) that employs standard caching (expiration / TTL).
  • The release index file is a critical live site resource driving 100s of GBs of downloads a month, yet we manually update it multiple times a month, including for previews.

We intend to establish a new alternative graph structure in a new set of JSON files, while continuing to update the existing ones for compatibility.

Relevant characteristics of the planned new graph:

  • Fast changing currency (like patch version numbers) are exposed in (at most) a single location in the graph.
  • The root index file is updated (at most) once a year (to add the presence of a new major release).

SDK releases

The release notes (markdown and JSON) are oriented on runtime versions. It is difficult to find release notes for a given SDK version. We need to develop a publishing model that makes it easy to walk up to release notes with an SDK version number and discover the matching release notes. For many users, SDK patch versions are the primary currency they hold.

Example:

There are two problems:

  • You need to know the runtime release associated with that SDK version to find the SDK release notes.
  • The "good" release (the latest one) doesn't get its own SDK release notes.

If you dutifully follow the links via the web browser, you'll never notice this. If you want programatic access to release notes, this runtime-first modeling approach gets in the way and requires readers to do their own book keeping to compensate.

CVE transparency

We recently announced the .NET Security Group. The group is a recognition of how important we think it is to reliably, securely, and broadly deploy vulnerability fixes. That can only be done in partnership with others. Members of that group have asked us to do a better job publishing CVE information and to go beyond the announcements we publish.

The new information will be published in terms of the new CVE schema. It will include git commit links and other information. cve.json files will be referenced within the new graph structure, one per month (not per version).

Units

.NET versions are the sole unit we use for release notes. You need to know a fair bit about the .NET ecosystem to reason about reading release notes. You might look at .NET 7 release notes and be surprised that they end well before .NET 6 release notes. There is very little obvious to help folks unitiated with our ecosystem to understand its state at any one moment. This can equally be a problem with deeply familiar with .NET. For example, it is very hard to determine which .NET patches were shipped three months ago.

We should adopt time as a second unit, publishing release notes in terms of a historical monthly archive. This would enable easy access to release activities for any given month, including which CVEs were released across all supported versions.

File size

We've always published JSON release notes in large files, one per major release. There are scenarios where this is very useful, however, it is expected that most of the time that only the latest patch release is needed. In those cases, large files are a waste.

$ dotnet run app.cs 
https://builds.dotnet.microsoft.com/dotnet/release-metadata/6.0/releases.json - 1.53 MB
https://builds.dotnet.microsoft.com/dotnet/release-metadata/7.0/releases.json - 1.00 MB
https://builds.dotnet.microsoft.com/dotnet/release-metadata/8.0/releases.json - 1.16 MB
https://builds.dotnet.microsoft.com/dotnet/release-metadata/9.0/releases.json - 0.71 MB
https://builds.dotnet.microsoft.com/dotnet/release-metadata/10.0/releases.json - 0.39 MB

That's the output of a simple file-based app listing the size of the last several releases.json files. 1.5 MB of JSON is a lot to download and (more importantly) deserialize.

We've been experimenting with a release.json file per patch release. We've never productized that or provided users a good way to access those files. These files should also be included in the new graph.

Information modeling

An important question is how to model all of this information. There will be much more than we have today.

Today, we have a two-level graph, with one "navigational" file (releases-index.json) and the rest are "information domain" files (releases.json).

One of our challenges is that our singular graph navigation file has too much information, leading to navigation side-effects. As we add more nodes to navigate in the graph, the custom schema we've been using would be better replaced by an well-regarded schema intended for establishing a graph. An existing schema would fill in the navigational layer we need and make us more careful as we consider exposing domain-specific data within it.

Hypermedia formats are intended to describe nodes and relationships in an information document. We can use a hypermedia format for the graph and home-grown schemas for the rich data we want to share. That enables us to focus on the domain we understand most.

The Hypermedia Application Language (HAL) was chosen because it is a simple and established hypermedia schema. The HAL syntax is extremely minimal. It's more like a lexicon to use within a larger schema. HAL can be described as being more about a convention than supplying an extended syntax for every use case.

HAL has the following useful concepts and standardized formats:

  • Resource identity
  • Links to other resources
  • Embedded payload
  • Exposing partial views of other resources, which may enable skipping a networking class

Per this proposal, we'll need to model time and versions, SDKs and runtimes, and other things. These characteristics are required to expose all of those concepts in a uniform way and to represent arbitrary relationships. That's what hypermedia formats are good at.

LLM consumption

It would be very useful if LLMs are able to access the .NET release notes information graph directly and answer user questions. In fact, we've been experimenting with this at length and have seen good results.

Our early experiments used the following:

  • llms.txt to provide instructions to LLMs on how to access the graph
  • HAL to describe the graph.
  • Raw formats (using raw.githubusercontent.com links) and fully-qualified URLs (to avoid chat/code assistant firewall rules).

HAL was chosen because it is effective and the simplest hypermedia format we could find. llms.txt was chosen because we believe it or something similar will become a standard. Stripe already uses it for their docs, for example. Raw formats were chosen for the same reason that Stripe delivers raw content via all the referenced links. Props to Stripe for a good direction.

The goal is that you should be able to ask questions like:

  • "Please look at my repo. Am I using any .NET versions that are EOL?"
  • "Please show me code diffs for the .NET CVEs this month and explain how they resolve the vulnerability."

In our experiements, we've been asking questions like that with the addition of "Start with {base_url}/llms.txt."

Automation

All of the discussed files and graphs will be generated and updated via automation. The files should never need a manual update.

Client libraries

Client libraries will be provided to make it easy to navigate the graph. An object model will also be provided so that it easy to consume the JSON formats with System.Text.Json. The object model will be configured for source generation.

Summary

We're 10 years into our current model of release notes. We've learned a lot about what is required to offer markdown and JSON release notes at industrial scale. Now is a good time to apply those learnings in a coordinated way for the next 10 years of release note consumptions.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions