diff --git a/README.md b/README.md
index ff8e379..d1ae20c 100644
--- a/README.md
+++ b/README.md
@@ -241,6 +241,86 @@ SolutionCreator.Create(Path.Combine(Environment.CurrentDirectory, "solution1.sln
.Save();
```
+# Global.json Files
+You can create `global.json` files with the `GlobalJsonCreator` class to control SDK versions and MSBuild SDK references in your test projects.
+
+## Examples
+
+### Basic global.json with SDK version
+```C#
+GlobalJsonCreator.Create(
+ directory: Environment.CurrentDirectory,
+ sdkVersion: "8.0.100")
+ .Save();
+```
+
+This generates:
+```json
+{
+ "sdk": {
+ "version": "8.0.100"
+ }
+}
+```
+
+### With SDK roll-forward policy and prerelease
+```C#
+GlobalJsonCreator.Create(
+ directory: Environment.CurrentDirectory,
+ sdkVersion: "8.0.100",
+ rollForward: GlobalJsonSdkRollForward.LatestMinor,
+ allowPrerelease: true)
+ .Save();
+```
+
+This generates:
+```json
+{
+ "sdk": {
+ "version": "8.0.100",
+ "rollForward": "latestMinor",
+ "allowPrerelease": true
+ }
+}
+```
+
+### With MSBuild SDKs
+```C#
+GlobalJsonCreator.Create(
+ directory: Environment.CurrentDirectory,
+ sdkVersion: "8.0.100")
+ .MSBuildSdk("Microsoft.Build.NoTargets", "3.7.0")
+ .MSBuildSdk("Microsoft.Build.Traversal", "4.1.0")
+ .Save();
+```
+
+This generates:
+```json
+{
+ "sdk": {
+ "version": "8.0.100"
+ },
+ "msbuild-sdks": {
+ "Microsoft.Build.NoTargets": "3.7.0",
+ "Microsoft.Build.Traversal": "4.1.0"
+ }
+}
+```
+
+### Get JSON without saving
+```C#
+string json = GlobalJsonCreator.Create(
+ directory: Environment.CurrentDirectory,
+ sdkVersion: "8.0.100")
+ .MSBuildSdk("My.Custom.Sdk", "1.0.0")
+ .ToJson();
+
+// Or use implicit string conversion
+string json2 = GlobalJsonCreator.Create(
+ directory: Environment.CurrentDirectory,
+ sdkVersion: "8.0.100");
+```
+
# Package Repositories and Feeds
NuGet and MSBuild are very tightly coupled and a lot of times you need packages available when building projects. This API offers two solutions:
diff --git a/src/Microsoft.Build.Utilities.ProjectCreation.UnitTests/GlobalJsonTests.cs b/src/Microsoft.Build.Utilities.ProjectCreation.UnitTests/GlobalJsonTests.cs
new file mode 100644
index 0000000..260568d
--- /dev/null
+++ b/src/Microsoft.Build.Utilities.ProjectCreation.UnitTests/GlobalJsonTests.cs
@@ -0,0 +1,139 @@
+// Copyright (c) Jeff Kluge. All rights reserved.
+//
+// Licensed under the MIT license.
+
+using Shouldly;
+using System.IO;
+using Xunit;
+
+namespace Microsoft.Build.Utilities.ProjectCreation.UnitTests
+{
+ public class GlobalJsonTests : TestBase
+ {
+ public GlobalJsonTests()
+ {
+ TestDirectory = new DirectoryInfo(Path.Combine(TestRootPath, Path.GetRandomFileName()));
+ }
+
+ public DirectoryInfo TestDirectory { get; }
+
+ [Fact]
+ public void BasicGlobalJson()
+ {
+ GlobalJsonCreator globalJson = GlobalJsonCreator.Create(TestDirectory, "8.0.100")
+ .Save();
+
+ new FileInfo(globalJson.FullPath).ShouldExist();
+
+ string json = File.ReadAllText(globalJson.FullPath);
+
+ json.ShouldBe(
+@"{
+ ""sdk"": {
+ ""version"": ""8.0.100""
+ }
+}",
+StringCompareShould.IgnoreLineEndings);
+ }
+
+ [Fact]
+ public void GlobalJsonImplicitConversionToString()
+ {
+ string json = GlobalJsonCreator
+ .Create(TestDirectory, "8.0.100");
+
+ json.ShouldBe(
+@"{
+ ""sdk"": {
+ ""version"": ""8.0.100""
+ }
+}",
+StringCompareShould.IgnoreLineEndings);
+ }
+
+ [Fact]
+ public void GlobalJsonToJson()
+ {
+ string json = GlobalJsonCreator
+ .Create(TestDirectory, "8.0.100", rollForward: GlobalJsonSdkRollForward.LatestMinor)
+ .ToJson();
+
+ json.ShouldBe(
+@"{
+ ""sdk"": {
+ ""version"": ""8.0.100"",
+ ""rollForward"": ""latestMinor""
+ }
+}",
+StringCompareShould.IgnoreLineEndings);
+ }
+
+ [Fact]
+ public void GlobalJsonWithAllowPrerelease()
+ {
+ GlobalJsonCreator globalJson = GlobalJsonCreator
+ .Create(TestDirectory, "8.0.100", allowPrerelease: true)
+ .Save();
+
+ new FileInfo(globalJson.FullPath).ShouldExist();
+
+ string json = File.ReadAllText(globalJson.FullPath);
+
+ json.ShouldBe(
+@"{
+ ""sdk"": {
+ ""version"": ""8.0.100"",
+ ""allowPrerelease"": true
+ }
+}",
+StringCompareShould.IgnoreLineEndings);
+ }
+
+ [Fact]
+ public void GlobalJsonWithMsbuildSdks()
+ {
+ GlobalJsonCreator globalJson = GlobalJsonCreator
+ .Create(TestDirectory, "8.0.100")
+ .MSBuildSdk("Microsoft.Build.NoTargets", "3.7.0")
+ .MSBuildSdk("Microsoft.Build.Traversal", "4.1.0")
+ .Save();
+
+ new FileInfo(globalJson.FullPath).ShouldExist();
+
+ string json = File.ReadAllText(globalJson.FullPath);
+
+ json.ShouldBe(
+@"{
+ ""sdk"": {
+ ""version"": ""8.0.100""
+ },
+ ""msbuild-sdks"": {
+ ""Microsoft.Build.NoTargets"": ""3.7.0"",
+ ""Microsoft.Build.Traversal"": ""4.1.0""
+ }
+}",
+StringCompareShould.IgnoreLineEndings);
+ }
+
+ [Fact]
+ public void GlobalJsonWithRollForward()
+ {
+ GlobalJsonCreator globalJson = GlobalJsonCreator
+ .Create(TestDirectory, "10.0.100", GlobalJsonSdkRollForward.LatestMinor)
+ .Save();
+
+ new FileInfo(globalJson.FullPath).ShouldExist();
+
+ string json = File.ReadAllText(globalJson.FullPath);
+
+ json.ShouldBe(
+@"{
+ ""sdk"": {
+ ""version"": ""10.0.100"",
+ ""rollForward"": ""latestMinor""
+ }
+}",
+StringCompareShould.IgnoreLineEndings);
+ }
+ }
+}
diff --git a/src/Microsoft.Build.Utilities.ProjectCreation/GlobalJsonCreator.cs b/src/Microsoft.Build.Utilities.ProjectCreation/GlobalJsonCreator.cs
new file mode 100644
index 0000000..da7602c
--- /dev/null
+++ b/src/Microsoft.Build.Utilities.ProjectCreation/GlobalJsonCreator.cs
@@ -0,0 +1,169 @@
+// Copyright (c) Jeff Kluge. All rights reserved.
+//
+// Licensed under the MIT license.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace Microsoft.Build.Utilities.ProjectCreation
+{
+ ///
+ /// A fluent API for generating global.json files.
+ ///
+ public partial class GlobalJsonCreator
+ {
+ private readonly GlobalJson _globalJson;
+
+ private readonly JsonSerializerOptions _jsonSerializerOptions = new()
+ {
+ WriteIndented = true,
+ DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
+ PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
+ };
+
+ private GlobalJsonCreator(FileInfo fullPath, string sdkVersion, GlobalJsonSdkRollForward? rollForward, bool? allowPrerelease)
+ {
+ _globalJson = new GlobalJson(
+ fullPath,
+ new GlobalJsonSdk
+ {
+ Version = sdkVersion,
+ RollForward = rollForward,
+ AllowPrerelease = allowPrerelease,
+ });
+ }
+
+ ///
+ /// Gets the full path to the global.json file.
+ ///
+ public string FullPath => _globalJson.FullPath.FullName;
+
+ ///
+ /// Implicitly converts a to a string.
+ ///
+ /// The to convert.
+ public static implicit operator string(GlobalJsonCreator creator) => creator.ToJson();
+
+ ///
+ /// Creates a new instance.
+ ///
+ /// The directory where the global.json file will be saved.
+ /// The SDK version to use.
+ /// The optional SDK roll-forward policy.
+ /// Whether to allow prerelease SDK versions.
+ /// A object used to construct a global.json file.
+ public static GlobalJsonCreator Create(
+ DirectoryInfo directory,
+ string sdkVersion,
+ GlobalJsonSdkRollForward? rollForward = null,
+ bool? allowPrerelease = null)
+ {
+ if (string.IsNullOrWhiteSpace(sdkVersion))
+ {
+ throw new ArgumentNullException(nameof(sdkVersion));
+ }
+
+ FileInfo fullPath = new(Path.GetFullPath(Path.Combine(directory.FullName, "global.json")));
+
+ return new GlobalJsonCreator(fullPath, sdkVersion, rollForward, allowPrerelease);
+ }
+
+ ///
+ /// Creates a new instance.
+ ///
+ /// The directory where the global.json file will be saved.
+ /// The SDK version to use.
+ /// The optional SDK roll-forward policy.
+ /// Whether to allow prerelease SDK versions.
+ /// A object used to construct a global.json file.
+ public static GlobalJsonCreator Create(
+ string? directory,
+ string sdkVersion,
+ GlobalJsonSdkRollForward? rollForward = null,
+ bool? allowPrerelease = null)
+ {
+ if (string.IsNullOrWhiteSpace(directory))
+ {
+ throw new ArgumentNullException(nameof(directory));
+ }
+
+ return Create(new DirectoryInfo(directory), sdkVersion, rollForward, allowPrerelease);
+ }
+
+ ///
+ /// Adds an MSBuild SDK to the msbuild-sdks section of the global.json file.
+ ///
+ /// The name of the MSBuild SDK.
+ /// The version of the MSBuild SDK.
+ /// The current .
+ public GlobalJsonCreator MSBuildSdk(string name, string version)
+ {
+ if (string.IsNullOrWhiteSpace(name))
+ {
+ throw new ArgumentNullException(nameof(name));
+ }
+
+ if (string.IsNullOrWhiteSpace(version))
+ {
+ throw new ArgumentNullException(nameof(version));
+ }
+
+ _globalJson.MSBuildSdks ??= [];
+
+ _globalJson.MSBuildSdks[name] = version;
+
+ return this;
+ }
+
+ ///
+ /// Saves the global.json file.
+ ///
+ /// The current .
+ public GlobalJsonCreator Save()
+ {
+ _globalJson.FullPath.Directory!.Create();
+
+ string json = ToJson();
+
+ File.WriteAllText(_globalJson.FullPath.FullName, json, Encoding.UTF8);
+
+ return this;
+ }
+
+ ///
+ /// Gets the JSON representation of the global.json file.
+ ///
+ /// A JSON string representing the global.json file.
+ public string ToJson() => JsonSerializer.Serialize(_globalJson, _jsonSerializerOptions);
+
+ internal record GlobalJson
+ {
+ public GlobalJson(FileInfo fullPath, GlobalJsonSdk sdk)
+ {
+ FullPath = fullPath;
+ Sdk = sdk;
+ }
+
+ [JsonIgnore]
+ public FileInfo FullPath { get; init; }
+
+ public GlobalJsonSdk Sdk { get; init; }
+
+ [JsonPropertyName("msbuild-sdks")]
+ public Dictionary? MSBuildSdks { get; set; }
+ }
+
+ internal record GlobalJsonSdk
+ {
+ public required string Version { get; init; }
+
+ public GlobalJsonSdkRollForward? RollForward { get; init; }
+
+ public bool? AllowPrerelease { get; init; }
+ }
+ }
+}
diff --git a/src/Microsoft.Build.Utilities.ProjectCreation/GlobalJsonSdkRollForward.cs b/src/Microsoft.Build.Utilities.ProjectCreation/GlobalJsonSdkRollForward.cs
new file mode 100644
index 0000000..7e910c5
--- /dev/null
+++ b/src/Microsoft.Build.Utilities.ProjectCreation/GlobalJsonSdkRollForward.cs
@@ -0,0 +1,91 @@
+// Copyright (c) Jeff Kluge. All rights reserved.
+//
+// Licensed under the MIT license.
+
+using System;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace Microsoft.Build.Utilities.ProjectCreation
+{
+ ///
+ /// Specifies the SDK roll-forward policy for global.json.
+ ///
+ [JsonConverter(typeof(GlobalJsonSdkRollForwardJsonConverter))]
+ public enum GlobalJsonSdkRollForward
+ {
+ ///
+ /// Roll forward to the latest patch version.
+ ///
+ LatestPatch,
+
+ ///
+ /// Roll forward to the latest feature version.
+ ///
+ LatestFeature,
+
+ ///
+ /// Roll forward to the latest minor version.
+ ///
+ LatestMinor,
+
+ ///
+ /// Roll forward to the latest major version.
+ ///
+ LatestMajor,
+
+ ///
+ /// Disable roll-forward.
+ ///
+ Disable,
+ }
+
+#pragma warning disable SA1649 // File name should match first type name
+ internal class GlobalJsonSdkRollForwardJsonConverter : JsonConverter
+#pragma warning restore SA1649 // File name should match first type name
+ {
+ public override GlobalJsonSdkRollForward Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ string? value = reader.GetString();
+
+ return value?.Trim() switch
+ {
+ "latestPatch" => GlobalJsonSdkRollForward.LatestPatch,
+ "latestFeature" => GlobalJsonSdkRollForward.LatestFeature,
+ "latestMinor" => GlobalJsonSdkRollForward.LatestMinor,
+ "latestMajor" => GlobalJsonSdkRollForward.LatestMajor,
+ "disable" => GlobalJsonSdkRollForward.Disable,
+ _ => throw new JsonException($"Unexpected value '{value}' for {nameof(GlobalJsonSdkRollForward)}."),
+ };
+ }
+
+ public override void Write(Utf8JsonWriter writer, GlobalJsonSdkRollForward value, JsonSerializerOptions options)
+ {
+ switch (value)
+ {
+ case GlobalJsonSdkRollForward.LatestPatch:
+ writer.WriteStringValue("latestPatch");
+ break;
+
+ case GlobalJsonSdkRollForward.LatestFeature:
+ writer.WriteStringValue("latestFeature");
+ break;
+
+ case GlobalJsonSdkRollForward.LatestMinor:
+ writer.WriteStringValue("latestMinor");
+ break;
+
+ case GlobalJsonSdkRollForward.LatestMajor:
+ writer.WriteStringValue("latestMajor");
+ break;
+
+ case GlobalJsonSdkRollForward.Disable:
+ writer.WriteStringValue("disable");
+ break;
+
+ default:
+ throw new JsonException($"Unexpected value '{value}' for {nameof(GlobalJsonSdkRollForward)}.");
+ }
+ }
+ }
+}
diff --git a/src/Microsoft.Build.Utilities.ProjectCreation/IsExternalInit.cs b/src/Microsoft.Build.Utilities.ProjectCreation/IsExternalInit.cs
new file mode 100644
index 0000000..57c00da
--- /dev/null
+++ b/src/Microsoft.Build.Utilities.ProjectCreation/IsExternalInit.cs
@@ -0,0 +1,15 @@
+// Copyright (c) Jeff Kluge. All rights reserved.
+//
+// Licensed under the MIT license.
+
+#if NETFRAMEWORK
+namespace System.Runtime.CompilerServices
+{
+ ///
+ /// Reserved for compiler use. Enables init-only properties in records for .NET Framework.
+ ///
+ internal static class IsExternalInit
+ {
+ }
+}
+#endif
diff --git a/src/Microsoft.Build.Utilities.ProjectCreation/PolyfillAttributes.cs b/src/Microsoft.Build.Utilities.ProjectCreation/PolyfillAttributes.cs
new file mode 100644
index 0000000..9cdd2cf
--- /dev/null
+++ b/src/Microsoft.Build.Utilities.ProjectCreation/PolyfillAttributes.cs
@@ -0,0 +1,40 @@
+// Copyright (c) Jeff Kluge. All rights reserved.
+//
+// Licensed under the MIT license.
+
+#if NETFRAMEWORK
+
+#pragma warning disable SA1402 // File may only contain a single type
+#pragma warning disable SA1403 // File may only contain a single namespace
+#pragma warning disable SA1649 // File name should match first type name
+
+namespace System.Runtime.CompilerServices
+{
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
+ internal sealed class RequiredMemberAttribute : Attribute
+ {
+ }
+
+ [AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)]
+ internal sealed class CompilerFeatureRequiredAttribute : Attribute
+ {
+ public CompilerFeatureRequiredAttribute(string featureName)
+ {
+ FeatureName = featureName;
+ }
+
+ public string FeatureName { get; }
+
+ public bool IsOptional { get; init; }
+ }
+}
+
+namespace System.Diagnostics.CodeAnalysis
+{
+ [AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)]
+ internal sealed class SetsRequiredMembersAttribute : Attribute
+ {
+ }
+}
+
+#endif
diff --git a/src/Microsoft.Build.Utilities.ProjectCreation/PublicAPI/net10.0/PublicAPI.Unshipped.txt b/src/Microsoft.Build.Utilities.ProjectCreation/PublicAPI/net10.0/PublicAPI.Unshipped.txt
index 3df6e35..00524cf 100644
--- a/src/Microsoft.Build.Utilities.ProjectCreation/PublicAPI/net10.0/PublicAPI.Unshipped.txt
+++ b/src/Microsoft.Build.Utilities.ProjectCreation/PublicAPI/net10.0/PublicAPI.Unshipped.txt
@@ -1,2 +1,16 @@
#nullable enable
+Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator
+Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator.FullPath.get -> string!
+Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator.MSBuildSdk(string! name, string! version) -> Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator!
+Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator.Save() -> Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator!
+Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator.ToJson() -> string!
+Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward
+Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward.Disable = 4 -> Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward
+Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward.LatestFeature = 1 -> Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward
+Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward.LatestMajor = 3 -> Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward
+Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward.LatestMinor = 2 -> Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward
+Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward.LatestPatch = 0 -> Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward
Microsoft.Build.Utilities.ProjectCreation.ProjectCreator.TryBuild(System.Collections.Generic.IDictionary? globalProperties, out bool result) -> Microsoft.Build.Utilities.ProjectCreation.ProjectCreator!
+static Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator.Create(string? directory, string! sdkVersion, Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward? rollForward = null, bool? allowPrerelease = null) -> Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator!
+static Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator.Create(System.IO.DirectoryInfo! directory, string! sdkVersion, Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward? rollForward = null, bool? allowPrerelease = null) -> Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator!
+static Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator.implicit operator string!(Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator! creator) -> string!
diff --git a/src/Microsoft.Build.Utilities.ProjectCreation/PublicAPI/net472/PublicAPI.Unshipped.txt b/src/Microsoft.Build.Utilities.ProjectCreation/PublicAPI/net472/PublicAPI.Unshipped.txt
index 3df6e35..00524cf 100644
--- a/src/Microsoft.Build.Utilities.ProjectCreation/PublicAPI/net472/PublicAPI.Unshipped.txt
+++ b/src/Microsoft.Build.Utilities.ProjectCreation/PublicAPI/net472/PublicAPI.Unshipped.txt
@@ -1,2 +1,16 @@
#nullable enable
+Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator
+Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator.FullPath.get -> string!
+Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator.MSBuildSdk(string! name, string! version) -> Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator!
+Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator.Save() -> Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator!
+Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator.ToJson() -> string!
+Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward
+Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward.Disable = 4 -> Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward
+Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward.LatestFeature = 1 -> Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward
+Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward.LatestMajor = 3 -> Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward
+Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward.LatestMinor = 2 -> Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward
+Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward.LatestPatch = 0 -> Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward
Microsoft.Build.Utilities.ProjectCreation.ProjectCreator.TryBuild(System.Collections.Generic.IDictionary? globalProperties, out bool result) -> Microsoft.Build.Utilities.ProjectCreation.ProjectCreator!
+static Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator.Create(string? directory, string! sdkVersion, Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward? rollForward = null, bool? allowPrerelease = null) -> Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator!
+static Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator.Create(System.IO.DirectoryInfo! directory, string! sdkVersion, Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward? rollForward = null, bool? allowPrerelease = null) -> Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator!
+static Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator.implicit operator string!(Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator! creator) -> string!
diff --git a/src/Microsoft.Build.Utilities.ProjectCreation/PublicAPI/net8.0/PublicAPI.Unshipped.txt b/src/Microsoft.Build.Utilities.ProjectCreation/PublicAPI/net8.0/PublicAPI.Unshipped.txt
index 3df6e35..00524cf 100644
--- a/src/Microsoft.Build.Utilities.ProjectCreation/PublicAPI/net8.0/PublicAPI.Unshipped.txt
+++ b/src/Microsoft.Build.Utilities.ProjectCreation/PublicAPI/net8.0/PublicAPI.Unshipped.txt
@@ -1,2 +1,16 @@
#nullable enable
+Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator
+Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator.FullPath.get -> string!
+Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator.MSBuildSdk(string! name, string! version) -> Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator!
+Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator.Save() -> Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator!
+Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator.ToJson() -> string!
+Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward
+Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward.Disable = 4 -> Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward
+Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward.LatestFeature = 1 -> Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward
+Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward.LatestMajor = 3 -> Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward
+Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward.LatestMinor = 2 -> Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward
+Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward.LatestPatch = 0 -> Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward
Microsoft.Build.Utilities.ProjectCreation.ProjectCreator.TryBuild(System.Collections.Generic.IDictionary? globalProperties, out bool result) -> Microsoft.Build.Utilities.ProjectCreation.ProjectCreator!
+static Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator.Create(string? directory, string! sdkVersion, Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward? rollForward = null, bool? allowPrerelease = null) -> Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator!
+static Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator.Create(System.IO.DirectoryInfo! directory, string! sdkVersion, Microsoft.Build.Utilities.ProjectCreation.GlobalJsonSdkRollForward? rollForward = null, bool? allowPrerelease = null) -> Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator!
+static Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator.implicit operator string!(Microsoft.Build.Utilities.ProjectCreation.GlobalJsonCreator! creator) -> string!