At the end of each release cycle, we update our Major Version (branding version of build assets) & TFM (Target Framework Moniker) in main, in preparation for the next major release. This doc describes the process of doing those updates, which can include many subtle gotchas in the aspnetcore repo.
In the event that we do a minor release (e.g. 3.1), the guidance in this document still applies (but with all instances of MajorVersion replaced by MinorVersion).
Typically, we will update the Major Version before updating the TFM. This is because updating Major Version only requires a logical agreement that main is no longer the place for work on the previous major release, while updating the TFM requires waiting for dotnet/runtime to update their TFM so that we can ingest that change. For an example, this is the PR where we updated our branding from 6.0.0 to 7.0.0 (note that branding does not have to happen in a dependency update PR - this particular branding exercise needed to include some reaction to runtime changes).
- In eng/Versions.props:
- Increment
AspNetCoreMajorVersionby 1. - Change
PreReleaseVersionIterationto1. - Change
PreReleaseVersionLabeltoalpha. - Change
PreReleaseBrandingLabeltoAlpha $(PreReleaseVersionIteration).
- Increment
- In src/Framework/test/TestData.cs, update
ListedTargetingPackAssembliesby incrementing the AssemblyVersion of all aspnetcore assemblies by 1 major version. Once dotnet/runtime updates their AssemblyVersions, we also need to update those in this file. They typically make that change at the same time as their TFM update, but we change our AssemblyVersions as soon as we update branding. - Add entries to NuGet.config for the new Major Version's feed. This just means copying the current feeds (e.g.
dotnet7anddotnet7-transport) and adding entries for the new feeds (dotnet8anddotnet8-transport). Make an effort to remove old feeds here at the same time. - In src/ProjectTemplates/Shared/TemplatePackageInstaller.cs, add entries to
_templatePackagesforMicrosoft.DotNet.Web.ProjectTemplatesandMicrosoft.DotNet.Web.Spa.ProjectTemplatesmatching the new version. - In eng/targets/CSharp.Common.props for the previous release branch, modify the
<LangVersion>to be a hardcoded version instead ofpreview. (e.g. If main is being updated to 8.0.0 modify the<LangVersion>in the release/7.0 branch). See https://docs.microsoft.com/dotnet/csharp/language-reference/configure-language-version#defaults to find what language version to use.
- CI must be green.
- Assets produced by the build (packages, installers) should have the new branding version (e.g. if you have just updated
MajorVersionto8, packages should be branded8.0.0-alpha.1.{BuildNumber}). - Assemblies produced by the build should have the new
AssemblyVersion(e.g. if you have just updatedMajorVersionto8, Assemblies should haveAssemblyVersion8.0.0.0).
Once dotnet/runtime has updated their TFM, we update ours in the dependency update PR ingesting that change. We won't be able to ingest new dotnet/runtime dependencies in main until this is done. For an example, this is the PR where we updated our TFM to net7.0. This step can be tricky - we have workarounds in eng/tools/GenerateFiles/Directory.Build.targets.in to make the build work before we get an SDK containing runtime references with the new TFM. We copy the KnownFrameworkReference, KnownRuntimePack, and KnownAppHostPack from the previous TFM, give them the incoming runtime dependency versions, and give them the new TFM (these TFMs no-op most of the time - they only apply during this period when we're using an SDK that doesn't know about the new TFM). These workarounds allow us to build against the new TFM before we get an SDK with a reference to it, but there are often problems that arise in this area. The best way to debug build errors related to FrameworkReferences it to get a binlog of a failing project (dotnet build /bl) and look at the inputs to the task that failed. Confirm that the Known___ items look as expected (there is an entry with the current TFM & the current dotnet/runtime dependency version), and look at the source code of the task in dotnet/sdk for hints.
- In eng/Versions.props, increment
DefaultNetCoreTargetFrameworkby 1. - Do a global repo search for the current version string, and update almost everything by 1 (e.g. find
net7, replace withnet8). See the PR linked above for examples - this shouldn't be done blindly, but on a case-by-case basis. Most things should be updated, and most choices should be obvious.- Exceptions to this are eng/tools/RepoTasks/RepoTasks.csproj, eng/tools/RepoTasks/RepoTasks.tasks, and eng/tools/HelixTestRunner/HelixTestRunner.csproj. These build without the workarounds from eng/tools/GenerateFiles/Directory.Build.targets.in, and need to be kept at the previous TFM until we get an SDK containing a runtime with the new TFM. Generally this means we have to hard-code the previous TFM for these files, rather than using
DefaultNetCoreTargetFramework.
- Exceptions to this are eng/tools/RepoTasks/RepoTasks.csproj, eng/tools/RepoTasks/RepoTasks.tasks, and eng/tools/HelixTestRunner/HelixTestRunner.csproj. These build without the workarounds from eng/tools/GenerateFiles/Directory.Build.targets.in, and need to be kept at the previous TFM until we get an SDK containing a runtime with the new TFM. Generally this means we have to hard-code the previous TFM for these files, rather than using
- Add a reference to the new
SiteExtensionspackage for the previous Major Version.- Add references to src/SiteExtensions/LoggingAggregate/src/Microsoft.AspNetCore.AzureAppServices.SiteExtension/Microsoft.AspNetCore.AzureAppServices.SiteExtension.csproj to
Microsoft.AspNetCore.AzureAppServices.SiteExtension.{PreviousMajorVersion}.0.x64andMicrosoft.AspNetCore.AzureAppServices.SiteExtension.{PreviousMajorVersion}.0.x86. - Add entries in eng/Versions.props similar to these - the version should be from the latest released build of .Net.
- Add entries in eng/Dependencies.props similar to these.
- Add references to src/SiteExtensions/LoggingAggregate/src/Microsoft.AspNetCore.AzureAppServices.SiteExtension/Microsoft.AspNetCore.AzureAppServices.SiteExtension.csproj to
- Update AssemblyVersions for dotnet/runtime assemblies in src/Framework/test/TestData.cs.
- Update dotnet/spa-templates
- Create a
release/{n}.0branch in dotnet/spa-template based off ofmain, wherenis the MajorVersion we are updating from (not the one we are updating to). - Create a PR like this one updating the current release branch in
aspnetcoreto reference the new release branch you just created in dotnet/spa-templates. - Create a PR like this one updating the branding & TFM in the
mainbranch of dotnet/spa-templates.
- Do not merge this until the PR from the previous step is merged.
- Create a
- Update template precedence
- Create & merge a PR like this one in dotnet/spa-templates updating
precedenceandidentityelements in all template.json files. - Create a PR like this one in dotnet/aspnetcore that updates the spa-templates submodule, and updates the
precedence,identity, and (if it exists)thirdPartyNoticeselements in all template.json files. - Make sure the new aka.ms link you're referencing in
thirdPartyNoticesexists.
- Create & merge a PR like this one in dotnet/spa-templates updating
- In src/Framework/AspNetCoreAnalyzers/test/Verifiers/CSharpRouteHandlerCodeFixVerifier.cs, update the references to
ReferenceAssemblies.Net.Netx0with the latest version.
- CI must be green.
- Packages produced by the build should be placing assemblies in a folder named after the new TFM.
Typically we update the SDK we use in main every Monday. Once we have one that contains Microsoft.Netcore.App entries with the new TFM, we can update eng/tools/RepoTasks/RepoTasks.csproj, eng/tools/RepoTasks/RepoTasks.tasks, and eng/tools/HelixTestRunner/HelixTestRunner.csproj to use DefaultNetCoreTargetFramework again rather than hard-coding the previous TFM.