From 6cde367746368738b541abb0a3c5dd1bde3f3b5b Mon Sep 17 00:00:00 2001
From: John Campion Jr <1094820+JohnCampionJr@users.noreply.github.com>
Date: Mon, 8 Jun 2026 15:12:40 -0400
Subject: [PATCH 1/3] Update Spectre.Console
Updates Spectre.Console to 0.56.0 and Spectre.Console.Cli to 0.55.0 (not released
in lockstep), plus the matching testing packages.
Adapts to two breaking changes: commands' ExecuteAsync now takes a CancellationToken
and is protected, and CommandAppTester/CommandAppResult moved to the new
Spectre.Console.Cli.Testing package and is now single-use (tests that ran it more
than once use a fresh tester per run). Removes the CommandAppTesterExtensions
reflection hack now that input can go through the tester's own console.
---
.changeset/upgrade-spectre-console.md | 5 +++
Directory.Packages.props | 7 +--
.../Commands/Init/InitChangesetCommand.cs | 3 +-
.../Shared/ConfigurationCommandBase.cs | 2 +-
.../Add/AddCommandTests.cs | 30 +++++++------
.../Add/CommandAppTesterExtensions.cs | 45 -------------------
.../Init/InitCommandTests.cs | 24 +++++-----
.../Publish/PublishChangesetCommandTests.cs | 9 ++--
.../SolarWinds.Changesets.Tests.csproj | 1 +
.../Status/StatusChangesetCommandTests.cs | 9 ++--
.../Version/VersionChangesetCommandTests.cs | 2 +-
11 files changed, 56 insertions(+), 81 deletions(-)
create mode 100644 .changeset/upgrade-spectre-console.md
delete mode 100644 tests/SolarWinds.Changesets.Tests/Add/CommandAppTesterExtensions.cs
diff --git a/.changeset/upgrade-spectre-console.md b/.changeset/upgrade-spectre-console.md
new file mode 100644
index 0000000..13ff94f
--- /dev/null
+++ b/.changeset/upgrade-spectre-console.md
@@ -0,0 +1,5 @@
+---
+"SolarWinds.Changesets": Patch
+---
+
+Upgrade Spectre.Console to 0.56.0 and Spectre.Console.Cli to 0.55.0 (with matching testing packages). Adapts to the new command `ExecuteAsync(CommandContext, CancellationToken)` signature and the move of `CommandAppTester` into the new `Spectre.Console.Cli.Testing` package.
diff --git a/Directory.Packages.props b/Directory.Packages.props
index 4cdc0e9..5a788e6 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -22,9 +22,10 @@
-
+
-
-
+
+
+
diff --git a/src/SolarWinds.Changesets/Commands/Init/InitChangesetCommand.cs b/src/SolarWinds.Changesets/Commands/Init/InitChangesetCommand.cs
index 75e48d9..84dd207 100644
--- a/src/SolarWinds.Changesets/Commands/Init/InitChangesetCommand.cs
+++ b/src/SolarWinds.Changesets/Commands/Init/InitChangesetCommand.cs
@@ -46,13 +46,14 @@ IConfigurationService configurationService
/// Executes Init command.
///
/// Command context.
+ /// A token to observe for cancellation requests.
///
/// An integer indicating the result of the initialization:
/// - 0: Initialization succeeded.
/// - 1: Directory existed but config file was missing; default config created.
/// - 2: Changesets already initialized; no further action needed.
///
- public override async Task ExecuteAsync(CommandContext context)
+ protected override async Task ExecuteAsync(CommandContext context, CancellationToken cancellationToken)
{
if (Directory.Exists(Constants.ChangesetDirectoryFullPath))
{
diff --git a/src/SolarWinds.Changesets/Shared/ConfigurationCommandBase.cs b/src/SolarWinds.Changesets/Shared/ConfigurationCommandBase.cs
index 0c609d6..6823346 100644
--- a/src/SolarWinds.Changesets/Shared/ConfigurationCommandBase.cs
+++ b/src/SolarWinds.Changesets/Shared/ConfigurationCommandBase.cs
@@ -16,7 +16,7 @@ protected ConfigurationCommandBase(IConfigurationService configurationService)
_configurationService = configurationService;
}
- public sealed override async Task ExecuteAsync(CommandContext context)
+ protected sealed override async Task ExecuteAsync(CommandContext context, CancellationToken cancellationToken)
{
if (!Directory.Exists(Constants.ChangesetDirectoryFullPath))
{
diff --git a/tests/SolarWinds.Changesets.Tests/Add/AddCommandTests.cs b/tests/SolarWinds.Changesets.Tests/Add/AddCommandTests.cs
index 47cb88f..968eadf 100644
--- a/tests/SolarWinds.Changesets.Tests/Add/AddCommandTests.cs
+++ b/tests/SolarWinds.Changesets.Tests/Add/AddCommandTests.cs
@@ -6,6 +6,7 @@
using SolarWinds.Changesets.Infrastructure;
using SolarWinds.Changesets.Shared;
using Spectre.Console.Cli;
+using Spectre.Console.Cli.Testing;
using Spectre.Console.Testing;
namespace SolarWinds.Changesets.Tests.Add;
@@ -14,8 +15,8 @@ namespace SolarWinds.Changesets.Tests.Add;
internal sealed class AddCommandTests
{
private readonly Mock _projectFileNameLocator = new();
+ private TypeRegistrar _typeRegistrar = null!;
private CommandAppTester _app = null!;
- private TestConsole _console = null!;
private ChangesetsRepository _changesetsRepository = null!;
[SetUp]
@@ -29,8 +30,8 @@ public void SetUp()
_changesetsRepository = new ChangesetsRepository();
serviceCollection.AddSingleton(_changesetsRepository);
- TypeRegistrar typeRegistrar = new(serviceCollection);
- _app = new(typeRegistrar);
+ _typeRegistrar = new(serviceCollection);
+ _app = new(_typeRegistrar);
_app.Configure(config =>
{
config
@@ -51,27 +52,28 @@ public async Task AddCommand_HappyPath_ChangesetIsCreated()
// Arrange
_projectFileNameLocator.Setup(x => x.GetProjectFileNames(It.IsAny())).Returns(["A", "B"]);
- _console = new();
- _console.Interactive();
+ CommandAppTester initApp = new(_typeRegistrar);
+ initApp.SetDefaultCommand();
+ await initApp.RunAsync();
+
+ _app.Console.Interactive();
// MultiSelectionPrompt - Select 2nd project 'B'
- _console.Input.PushKey(ConsoleKey.DownArrow);
- _console.Input.PushKey(ConsoleKey.Spacebar);
- _console.Input.PushKey(ConsoleKey.Enter);
+ _app.Console.Input.PushKey(ConsoleKey.DownArrow);
+ _app.Console.Input.PushKey(ConsoleKey.Spacebar);
+ _app.Console.Input.PushKey(ConsoleKey.Enter);
// SelectionPrompt - Select BumpType 'Minor'
- _console.Input.PushKey(ConsoleKey.DownArrow);
- _console.Input.PushKey(ConsoleKey.Enter);
+ _app.Console.Input.PushKey(ConsoleKey.DownArrow);
+ _app.Console.Input.PushKey(ConsoleKey.Enter);
// TextPrompt - Describe changes
string expectedDescription = "Test example description";
- _console.Input.PushTextWithEnter(expectedDescription);
+ _app.Console.Input.PushTextWithEnter(expectedDescription);
// Act
- _app.SetDefaultCommand();
- await _app.RunAsync();
_app.SetDefaultCommand();
- CommandAppResult result = _app.RunWithCustomConsole([], _console);
+ CommandAppResult result = await _app.RunAsync();
// Assert
result.ExitCode.Should().Be(ResultCodes.Success, result.Output);
diff --git a/tests/SolarWinds.Changesets.Tests/Add/CommandAppTesterExtensions.cs b/tests/SolarWinds.Changesets.Tests/Add/CommandAppTesterExtensions.cs
deleted file mode 100644
index 6feaff3..0000000
--- a/tests/SolarWinds.Changesets.Tests/Add/CommandAppTesterExtensions.cs
+++ /dev/null
@@ -1,45 +0,0 @@
-using System.Reflection;
-using Spectre.Console.Testing;
-
-namespace SolarWinds.Changesets.Tests.Add;
-
-internal static class CommandAppTesterExtensions
-{
- ///
- /// This method is used to run the command app tester with a custom console.
- ///
- ///
- /// This can be deleted once we upgrade Spectre.Console.Testing to version 0.51.X or higher.
- ///
- /// CommandAppTester instance.
- /// CLI arguments.
- /// Custom test console.
- /// Command result.
- /// Thrown when the command failed to run with the custom console.
- public static CommandAppResult RunWithCustomConsole(
- this CommandAppTester tester,
- string[] args,
- TestConsole console
- )
- {
- Type testerType = tester.GetType();
-
- MethodInfo? runMethod = testerType.GetMethod("Run", BindingFlags.NonPublic | BindingFlags.Instance);
-
- if (runMethod == null)
- {
- throw new InvalidOperationException("The method 'Run' was not found.");
- }
-
- object[] parameters = [args, console, null!];
-
- object? result = runMethod.Invoke(tester, parameters);
-
- if (result is CommandAppResult commandAppResult)
- {
- return commandAppResult;
- }
-
- throw new InvalidOperationException("The method 'Run' returned unexpected type.");
- }
-}
diff --git a/tests/SolarWinds.Changesets.Tests/Init/InitCommandTests.cs b/tests/SolarWinds.Changesets.Tests/Init/InitCommandTests.cs
index 2ea4712..0a3149c 100644
--- a/tests/SolarWinds.Changesets.Tests/Init/InitCommandTests.cs
+++ b/tests/SolarWinds.Changesets.Tests/Init/InitCommandTests.cs
@@ -3,14 +3,14 @@
using SolarWinds.Changesets.Commands.Init;
using SolarWinds.Changesets.Infrastructure;
using SolarWinds.Changesets.Shared;
-using Spectre.Console.Testing;
+using Spectre.Console.Cli.Testing;
namespace SolarWinds.Changesets.Tests.Init;
[TestFixture]
internal sealed class InitCommandTests
{
- private CommandAppTester _app = null!;
+ private TypeRegistrar _typeRegistrar = null!;
[SetUp]
public void SetUp()
@@ -19,10 +19,14 @@ public void SetUp()
ServiceCollection serviceCollection = new();
serviceCollection.AddSingleton();
- TypeRegistrar typeRegistrar = new(serviceCollection);
- CommandAppTester app = new(typeRegistrar);
+ _typeRegistrar = new(serviceCollection);
+ }
+
+ private CommandAppTester CreateApp()
+ {
+ CommandAppTester app = new(_typeRegistrar);
app.SetDefaultCommand();
- _app = app;
+ return app;
}
[TearDown]
@@ -35,7 +39,7 @@ public void TearDown()
public void InitCommand_HappyPath_FolderAndFilesAreCreated()
{
// Arrange, Act
- CommandAppResult result = _app.Run();
+ CommandAppResult result = CreateApp().Run();
// Assert
AssertInitCommand(result, ResultCodes.Success);
@@ -45,12 +49,12 @@ public void InitCommand_HappyPath_FolderAndFilesAreCreated()
public void InitCommand_HappyPathRunTwice_ConfigIsMissingAndWillBeGenerated()
{
// Arrange, Act, Assert
- CommandAppResult result = _app.Run();
+ CommandAppResult result = CreateApp().Run();
AssertInitCommand(result, ResultCodes.Success);
File.Delete(Constants.ChangesetConfigFileFullPath);
- CommandAppResult result2 = _app.Run();
+ CommandAppResult result2 = CreateApp().Run();
AssertInitCommand(result2, ResultCodes.ConfigFileWasGenerated);
}
@@ -58,10 +62,10 @@ public void InitCommand_HappyPathRunTwice_ConfigIsMissingAndWillBeGenerated()
public void InitCommand_HappyPathRunTwice_ConsoleContainMessageThatAlreadyExists()
{
// Arrange, Act, Assert
- CommandAppResult result = _app.Run();
+ CommandAppResult result = CreateApp().Run();
AssertInitCommand(result, ResultCodes.Success);
- CommandAppResult result2 = _app.Run();
+ CommandAppResult result2 = CreateApp().Run();
AssertInitCommand(result2, ResultCodes.AlreadyInitialized);
}
diff --git a/tests/SolarWinds.Changesets.Tests/Publish/PublishChangesetCommandTests.cs b/tests/SolarWinds.Changesets.Tests/Publish/PublishChangesetCommandTests.cs
index 94722b8..997d4ca 100644
--- a/tests/SolarWinds.Changesets.Tests/Publish/PublishChangesetCommandTests.cs
+++ b/tests/SolarWinds.Changesets.Tests/Publish/PublishChangesetCommandTests.cs
@@ -5,7 +5,7 @@
using SolarWinds.Changesets.Commands.Publish.Services;
using SolarWinds.Changesets.Infrastructure;
using SolarWinds.Changesets.Shared;
-using Spectre.Console.Testing;
+using Spectre.Console.Cli.Testing;
namespace SolarWinds.Changesets.Tests.Publish;
@@ -31,9 +31,12 @@ public void SetUp()
_configurationServiceMock.Setup(x => x.GetConfigAsync(It.IsAny())).Returns(Task.FromResult(new ChangesetConfig()));
TypeRegistrar typeRegistrar = new(serviceCollection);
+
+ CommandAppTester initApp = new(typeRegistrar);
+ initApp.SetDefaultCommand();
+ initApp.Run();
+
_app = new(typeRegistrar);
- _app.SetDefaultCommand();
- _app.Run();
_app.SetDefaultCommand();
}
diff --git a/tests/SolarWinds.Changesets.Tests/SolarWinds.Changesets.Tests.csproj b/tests/SolarWinds.Changesets.Tests/SolarWinds.Changesets.Tests.csproj
index 87d24dc..b5092d8 100644
--- a/tests/SolarWinds.Changesets.Tests/SolarWinds.Changesets.Tests.csproj
+++ b/tests/SolarWinds.Changesets.Tests/SolarWinds.Changesets.Tests.csproj
@@ -23,6 +23,7 @@
all
runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/tests/SolarWinds.Changesets.Tests/Status/StatusChangesetCommandTests.cs b/tests/SolarWinds.Changesets.Tests/Status/StatusChangesetCommandTests.cs
index a5da30c..4aca3a9 100644
--- a/tests/SolarWinds.Changesets.Tests/Status/StatusChangesetCommandTests.cs
+++ b/tests/SolarWinds.Changesets.Tests/Status/StatusChangesetCommandTests.cs
@@ -4,7 +4,7 @@
using SolarWinds.Changesets.Commands.Status;
using SolarWinds.Changesets.Infrastructure;
using SolarWinds.Changesets.Shared;
-using Spectre.Console.Testing;
+using Spectre.Console.Cli.Testing;
namespace SolarWinds.Changesets.Tests.Status;
@@ -23,9 +23,12 @@ public void SetUp()
serviceCollection.AddSingleton(_changesetsRepositoryMock.Object);
TypeRegistrar typeRegistrar = new(serviceCollection);
+
+ CommandAppTester initApp = new(typeRegistrar);
+ initApp.SetDefaultCommand();
+ initApp.Run();
+
_app = new(typeRegistrar);
- _app.SetDefaultCommand();
- _app.Run();
_app.SetDefaultCommand();
}
diff --git a/tests/SolarWinds.Changesets.Tests/Version/VersionChangesetCommandTests.cs b/tests/SolarWinds.Changesets.Tests/Version/VersionChangesetCommandTests.cs
index fa5c89f..57060de 100644
--- a/tests/SolarWinds.Changesets.Tests/Version/VersionChangesetCommandTests.cs
+++ b/tests/SolarWinds.Changesets.Tests/Version/VersionChangesetCommandTests.cs
@@ -6,7 +6,7 @@
using SolarWinds.Changesets.Commands.Version.Helpers;
using SolarWinds.Changesets.Infrastructure;
using SolarWinds.Changesets.Shared;
-using Spectre.Console.Testing;
+using Spectre.Console.Cli.Testing;
namespace SolarWinds.Changesets.Tests.Version;
From 64518427dc736bfb7693ec04317c9d4967e62d0b Mon Sep 17 00:00:00 2001
From: Marek Magath
Date: Fri, 10 Jul 2026 10:03:55 +0200
Subject: [PATCH 2/3] #28 Add doc about changesets action integration (#29)
---
.changeset/nyrdfxvizwsykar.md | 5 +++++
README.md | 29 +++++++++++++++++++++++++++++
2 files changed, 34 insertions(+)
create mode 100644 .changeset/nyrdfxvizwsykar.md
diff --git a/.changeset/nyrdfxvizwsykar.md b/.changeset/nyrdfxvizwsykar.md
new file mode 100644
index 0000000..1a33ed6
--- /dev/null
+++ b/.changeset/nyrdfxvizwsykar.md
@@ -0,0 +1,5 @@
+---
+"SolarWinds.Changesets": Patch
+---
+
+[[#28](https://github.com/solarwinds/net-changesets/issues/28)] Added documentation for integrating net-changesets with the official Changesets GitHub Action, including custom `version` and `publish` commands, required checkout depth, status-check behavior, NuGet source configuration, and links to a working demo workflow. ([PR #29](https://github.com/solarwinds/net-changesets/pull/29))
diff --git a/README.md b/README.md
index 49573e9..7291da7 100644
--- a/README.md
+++ b/README.md
@@ -34,6 +34,35 @@ This .NET implementation is port from original `npm` implementation [@changesets
- `publish` This publishes changes to specified nuget repository
- `status` Provides information about the changesets that currently exist. If there are no changesets present, it exits with an error status code
+## Changesets GitHub Action Integration with the .NET Changesets Implementation
+
+net-changesets can be used together with the original [changesets GitHub action](https://github.com/changesets/action). The action supports custom commands for the versioning and publishing steps, so a net-changesets tool can be used instead of the default [JavaScript-based changesets CLI tool](https://github.com/changesets/changesets).
+
+After each merge to the main branch, the action creates a release PR. During that step, `changeset version` converts changeset files into changelog entries and bumps C# project versions. When the release PR is merged, `changeset publish` builds and publishes NuGet packages to the configured nuget source.
+
+Minimal action configuration:
+
+```yaml
+- name: Create release pull request or publish packages
+ uses: changesets/action@v1
+ with:
+ version: changeset version
+ publish: changeset publish
+```
+Just a note: we don't need to override changesets status, because both the .NET and Node.js implementations use the same behavior for this command.
+
+Important workflow details:
+
+- Checkout should use `fetch-depth: 2`, because `changeset publish` compares the last two commits to find changed packages.
+- If the workflow runs `changeset status`, use `continue-on-error: true` when an empty changeset state should not fail the job.
+- The publish target is controlled by the net-changesets configuration and NuGet configuration. The demo publishes to a local folder package source configured in [.changeset/config.json](https://github.com/magiino/Marekth.NetChangesets.Demo/blob/main/.changeset/config.json#L3) and [nuget.config](https://github.com/magiino/Marekth.NetChangesets.Demo/blob/main/nuget.config).
+
+For a complete working example, see the [net-changesets demo repository](https://github.com/magiino/Marekth.NetChangesets.Demo/tree/main), especially the configured [release workflow](https://github.com/magiino/Marekth.NetChangesets.Demo/blob/main/.github/workflows/release.yml). The workflow wires the changesets action to net-changesets through its custom command inputs, as shown around [line 44](https://github.com/magiino/Marekth.NetChangesets.Demo/blob/main/.github/workflows/release.yml#L44). It also shows the required checkout depth at [line 16](https://github.com/magiino/Marekth.NetChangesets.Demo/blob/main/.github/workflows/release.yml#L16) and a non-failing status check at [line 48](https://github.com/magiino/Marekth.NetChangesets.Demo/blob/main/.github/workflows/release.yml#L48). An example generated release PR is available at [magiino/Marekth.NetChangesets.Demo#7](https://github.com/magiino/Marekth.NetChangesets.Demo/pull/7), and the repository [commit history](https://github.com/magiino/Marekth.NetChangesets.Demo/commits/main/) shows the release flow in detail.
+
+**You can fork the demo repository and try the workflow yourself !!! :)**
+
+The changesets action can also customize the release PR title, description, commit message, and other behavior. See the action [inputs documentation](https://github.com/changesets/action?tab=readme-ov-file#inputs) for the full list of supported options.
+
## Documentation
- [Implementation Details of net-changesets commands](https://github.com/solarwinds/net-changesets/blob/main/docs/commands-implementation-details.md)
From 706872c80f20868b673c796fe0f6b8e713ef637e Mon Sep 17 00:00:00 2001
From: Jan Vilimek
Date: Fri, 10 Jul 2026 10:43:33 +0200
Subject: [PATCH 3/3] Adopt .NET 10 with multitargeting (#30)
* Adopt .NET 10 with multitargeting
Multi-target net8.0;net10.0 for the tool and tests, bump the SDK and CI to .NET 10, and run the tests on both runtimes. AnalysisLevel tracks the TFM now; fixed the findings it surfaced (CA1515 -> internal types with InternalsVisibleTo for Moq, CA1872 -> Convert.ToHexString).
* Support macOS in ProcessExecutorTests
* Relax global.json SDK to a band-agnostic floor
Use 10.0.100 with rollForward latestFeature so any installed .NET 10 feature band
satisfies it, instead of requiring 10.0.300 or higher.
* Simplified lang and analysis version for both .net versions
only one lang and analysis should be supported (we will develop in .net 10, yet compile for .net 8-10)
* Update target frameworks to include net9.0
* Remove LangVersion condition for net8.0
* Add target frameworks net8.0, net9.0, and net10.0 to directory.build.props
* Deleted target frameworks in project file as it was moved to directory.build.props
Removed net10.0 from the target frameworks.
* Deleted target frameworks in project file as it was moved to directory.build.props
* Update .NET version to 10.0.x in CI workflow
for building all .net 8-10 we just need the .net 10 sdk
* Update adopt-dotnet-10.md
---------
Co-authored-by: John Campion Jr <1094820+JohnCampionJr@users.noreply.github.com>
---
.changeset/adopt-dotnet-10.md | 5 +++++
.github/workflows/ci.yml | 2 +-
.github/workflows/codeql.yml | 2 +-
Directory.Build.props | 8 +++-----
global.json | 2 +-
.../Commands/Add/IProjectFileNamesLocator.cs | 2 +-
.../Commands/Publish/Services/DotnetService.cs | 2 +-
.../Commands/Publish/Services/GitService.cs | 2 +-
.../Commands/Publish/Services/IDotnetService.cs | 2 +-
.../Commands/Publish/Services/IGitService.cs | 2 +-
src/SolarWinds.Changesets/Shared/BumpType.cs | 2 +-
src/SolarWinds.Changesets/Shared/ChangesetConfig.cs | 2 +-
src/SolarWinds.Changesets/Shared/ChangesetFile.cs | 2 +-
src/SolarWinds.Changesets/Shared/Constants.cs | 2 +-
src/SolarWinds.Changesets/Shared/IChangesetsRepository.cs | 2 +-
src/SolarWinds.Changesets/Shared/IConfigurationService.cs | 2 +-
src/SolarWinds.Changesets/Shared/IProcessExecutor.cs | 2 +-
.../Shared/InitializationException.cs | 2 +-
src/SolarWinds.Changesets/Shared/ProcessExecutor.cs | 2 +-
src/SolarWinds.Changesets/Shared/ProcessOutput.cs | 2 +-
src/SolarWinds.Changesets/Shared/ResultCodes.cs | 2 +-
src/SolarWinds.Changesets/SolarWinds.Changesets.csproj | 1 +
tests/SolarWinds.Changesets.Tests/ProcessExecutorTests.cs | 2 +-
.../Version/CsProjectsRepositoryTests.cs | 2 +-
24 files changed, 30 insertions(+), 26 deletions(-)
create mode 100644 .changeset/adopt-dotnet-10.md
diff --git a/.changeset/adopt-dotnet-10.md b/.changeset/adopt-dotnet-10.md
new file mode 100644
index 0000000..d72e657
--- /dev/null
+++ b/.changeset/adopt-dotnet-10.md
@@ -0,0 +1,5 @@
+---
+"SolarWinds.Changesets": Minor
+---
+
+Adopt .NET 10 with multi-targeting. The tool and tests now target `net8.0`, `net9.0` and `net10.0`, the SDK and CI use .NET 10.
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index f724d3f..860222e 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -19,7 +19,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
- dotnet-version: 8.0.406
+ dotnet-version: 10.0.x
- name: Restore dependencies
run: dotnet restore --packages ./packages
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index 9b059ba..f38fd12 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -33,7 +33,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
- dotnet-version: 8.0.406
+ dotnet-version: 10.0.x
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
diff --git a/Directory.Build.props b/Directory.Build.props
index 3cea168..66bc774 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -3,9 +3,8 @@
- net8.0
-
- 12.0
+ net8.0;net9.0;net10.0
+ 14.0
@@ -25,8 +24,7 @@
true
false
true
-
- 8
+ 10
all
true
diff --git a/global.json b/global.json
index 952b4c4..512142d 100644
--- a/global.json
+++ b/global.json
@@ -1,6 +1,6 @@
{
"sdk": {
- "version": "8.0.406",
+ "version": "10.0.100",
"rollForward": "latestFeature"
}
}
diff --git a/src/SolarWinds.Changesets/Commands/Add/IProjectFileNamesLocator.cs b/src/SolarWinds.Changesets/Commands/Add/IProjectFileNamesLocator.cs
index 05140d3..3462df8 100644
--- a/src/SolarWinds.Changesets/Commands/Add/IProjectFileNamesLocator.cs
+++ b/src/SolarWinds.Changesets/Commands/Add/IProjectFileNamesLocator.cs
@@ -3,7 +3,7 @@ namespace SolarWinds.Changesets.Commands.Add;
///
/// Defines a contract for locating project file names within a specified directory.
///
-public interface IProjectFileNamesLocator
+internal interface IProjectFileNamesLocator
{
///
/// Retrieves project file names located in the specified directory.
diff --git a/src/SolarWinds.Changesets/Commands/Publish/Services/DotnetService.cs b/src/SolarWinds.Changesets/Commands/Publish/Services/DotnetService.cs
index 3a318e2..b81fab8 100644
--- a/src/SolarWinds.Changesets/Commands/Publish/Services/DotnetService.cs
+++ b/src/SolarWinds.Changesets/Commands/Publish/Services/DotnetService.cs
@@ -3,7 +3,7 @@
namespace SolarWinds.Changesets.Commands.Publish.Services;
///
-public sealed class DotnetService : IDotnetService
+internal sealed class DotnetService : IDotnetService
{
private readonly IProcessExecutor _processExecutor;
diff --git a/src/SolarWinds.Changesets/Commands/Publish/Services/GitService.cs b/src/SolarWinds.Changesets/Commands/Publish/Services/GitService.cs
index afb837e..7030e70 100644
--- a/src/SolarWinds.Changesets/Commands/Publish/Services/GitService.cs
+++ b/src/SolarWinds.Changesets/Commands/Publish/Services/GitService.cs
@@ -3,7 +3,7 @@
namespace SolarWinds.Changesets.Commands.Publish.Services;
///
-public sealed class GitService : IGitService
+internal sealed class GitService : IGitService
{
private readonly IProcessExecutor _processExecutor;
diff --git a/src/SolarWinds.Changesets/Commands/Publish/Services/IDotnetService.cs b/src/SolarWinds.Changesets/Commands/Publish/Services/IDotnetService.cs
index 4d5e495..c7bda24 100644
--- a/src/SolarWinds.Changesets/Commands/Publish/Services/IDotnetService.cs
+++ b/src/SolarWinds.Changesets/Commands/Publish/Services/IDotnetService.cs
@@ -5,7 +5,7 @@ namespace SolarWinds.Changesets.Commands.Publish.Services;
///
/// Provides functionality to interact with the .NET CLI for operations such as packing and publishing NuGet packages.
///
-public interface IDotnetService
+internal interface IDotnetService
{
///
/// Packs a .NET project into a NuGet package.
diff --git a/src/SolarWinds.Changesets/Commands/Publish/Services/IGitService.cs b/src/SolarWinds.Changesets/Commands/Publish/Services/IGitService.cs
index 1b3e79a..9527b00 100644
--- a/src/SolarWinds.Changesets/Commands/Publish/Services/IGitService.cs
+++ b/src/SolarWinds.Changesets/Commands/Publish/Services/IGitService.cs
@@ -5,7 +5,7 @@ namespace SolarWinds.Changesets.Commands.Publish.Services;
///
/// Provides Git-related services, such as retrieving file differences.
///
-public interface IGitService
+internal interface IGitService
{
///
/// Retrieves a list of file names that have changed in the specified source path.
diff --git a/src/SolarWinds.Changesets/Shared/BumpType.cs b/src/SolarWinds.Changesets/Shared/BumpType.cs
index 92d795e..73fa3fd 100644
--- a/src/SolarWinds.Changesets/Shared/BumpType.cs
+++ b/src/SolarWinds.Changesets/Shared/BumpType.cs
@@ -3,7 +3,7 @@ namespace SolarWinds.Changesets.Shared;
///
/// Specifies the type of version bump to apply.
///
-public enum BumpType
+internal enum BumpType
{
///
/// No version bump.
diff --git a/src/SolarWinds.Changesets/Shared/ChangesetConfig.cs b/src/SolarWinds.Changesets/Shared/ChangesetConfig.cs
index 944bb8f..f23e72d 100644
--- a/src/SolarWinds.Changesets/Shared/ChangesetConfig.cs
+++ b/src/SolarWinds.Changesets/Shared/ChangesetConfig.cs
@@ -3,7 +3,7 @@ namespace SolarWinds.Changesets.Shared;
///
/// Changeset config.
///
-public sealed class ChangesetConfig
+internal sealed class ChangesetConfig
{
///
/// Specify the relative path from the changeset command's execution folder to the location of the projects.
diff --git a/src/SolarWinds.Changesets/Shared/ChangesetFile.cs b/src/SolarWinds.Changesets/Shared/ChangesetFile.cs
index ad45086..1236d07 100644
--- a/src/SolarWinds.Changesets/Shared/ChangesetFile.cs
+++ b/src/SolarWinds.Changesets/Shared/ChangesetFile.cs
@@ -6,4 +6,4 @@ namespace SolarWinds.Changesets.Shared;
/// Changed module names.
/// Bump type.
/// Description.
-public sealed record ChangesetFile(ICollection ChangedModuleNames, BumpType BumpType, string Description);
+internal sealed record ChangesetFile(ICollection ChangedModuleNames, BumpType BumpType, string Description);
diff --git a/src/SolarWinds.Changesets/Shared/Constants.cs b/src/SolarWinds.Changesets/Shared/Constants.cs
index ff78376..0b6c48d 100644
--- a/src/SolarWinds.Changesets/Shared/Constants.cs
+++ b/src/SolarWinds.Changesets/Shared/Constants.cs
@@ -3,7 +3,7 @@ namespace SolarWinds.Changesets.Shared;
///
/// Provides application-wide constant values of file names and file path.
///
-public static class Constants
+internal static class Constants
{
///
/// The file name of the changelog file.
diff --git a/src/SolarWinds.Changesets/Shared/IChangesetsRepository.cs b/src/SolarWinds.Changesets/Shared/IChangesetsRepository.cs
index f2f4d69..a50e49b 100644
--- a/src/SolarWinds.Changesets/Shared/IChangesetsRepository.cs
+++ b/src/SolarWinds.Changesets/Shared/IChangesetsRepository.cs
@@ -3,7 +3,7 @@ namespace SolarWinds.Changesets.Shared;
///
/// Defines methods for accessing and managing changesets.
///
-public interface IChangesetsRepository
+internal interface IChangesetsRepository
{
///
/// Creates changeset file in the changeset working directory.
diff --git a/src/SolarWinds.Changesets/Shared/IConfigurationService.cs b/src/SolarWinds.Changesets/Shared/IConfigurationService.cs
index 9d627d4..9708e11 100644
--- a/src/SolarWinds.Changesets/Shared/IConfigurationService.cs
+++ b/src/SolarWinds.Changesets/Shared/IConfigurationService.cs
@@ -7,7 +7,7 @@ namespace SolarWinds.Changesets.Shared;
/// This service allows creating a default configuration file and retrieving an existing configuration file.
/// It uses JSON serialization and deserialization to handle the configuration data.
///
-public interface IConfigurationService
+internal interface IConfigurationService
{
///
diff --git a/src/SolarWinds.Changesets/Shared/IProcessExecutor.cs b/src/SolarWinds.Changesets/Shared/IProcessExecutor.cs
index caf8188..e23aab4 100644
--- a/src/SolarWinds.Changesets/Shared/IProcessExecutor.cs
+++ b/src/SolarWinds.Changesets/Shared/IProcessExecutor.cs
@@ -3,7 +3,7 @@ namespace SolarWinds.Changesets.Shared;
///
/// Executes external processes and captures their output and exit code.
///
-public interface IProcessExecutor
+internal interface IProcessExecutor
{
///
/// Executes a process with the specified executable, arguments, and working directory.
diff --git a/src/SolarWinds.Changesets/Shared/InitializationException.cs b/src/SolarWinds.Changesets/Shared/InitializationException.cs
index c6270fd..3048300 100644
--- a/src/SolarWinds.Changesets/Shared/InitializationException.cs
+++ b/src/SolarWinds.Changesets/Shared/InitializationException.cs
@@ -3,7 +3,7 @@ namespace SolarWinds.Changesets.Shared;
///
/// Represents errors that occur during the initialization phase.
///
-public sealed class InitializationException : Exception
+internal sealed class InitializationException : Exception
{
///
/// Initializes a new instance of the class
diff --git a/src/SolarWinds.Changesets/Shared/ProcessExecutor.cs b/src/SolarWinds.Changesets/Shared/ProcessExecutor.cs
index bd1ed31..86b68cb 100644
--- a/src/SolarWinds.Changesets/Shared/ProcessExecutor.cs
+++ b/src/SolarWinds.Changesets/Shared/ProcessExecutor.cs
@@ -3,7 +3,7 @@
namespace SolarWinds.Changesets.Shared;
///
-public class ProcessExecutor : IProcessExecutor
+internal class ProcessExecutor : IProcessExecutor
{
///
public async Task Execute(string executable, string arguments, string workingDirectoryPath)
diff --git a/src/SolarWinds.Changesets/Shared/ProcessOutput.cs b/src/SolarWinds.Changesets/Shared/ProcessOutput.cs
index 70b3242..bf3bb03 100644
--- a/src/SolarWinds.Changesets/Shared/ProcessOutput.cs
+++ b/src/SolarWinds.Changesets/Shared/ProcessOutput.cs
@@ -5,4 +5,4 @@ namespace SolarWinds.Changesets.Shared;
///
/// The list of output lines from the process.
/// The exit code of the process.
-public record ProcessOutput(ICollection Output, int ExitCode);
+internal record ProcessOutput(ICollection Output, int ExitCode);
diff --git a/src/SolarWinds.Changesets/Shared/ResultCodes.cs b/src/SolarWinds.Changesets/Shared/ResultCodes.cs
index 7608d5d..92b50a7 100644
--- a/src/SolarWinds.Changesets/Shared/ResultCodes.cs
+++ b/src/SolarWinds.Changesets/Shared/ResultCodes.cs
@@ -3,7 +3,7 @@ namespace SolarWinds.Changesets.Shared;
///
/// Defines command result codes with documentation.
///
-public static class ResultCodes
+internal static class ResultCodes
{
#region Success Codes
diff --git a/src/SolarWinds.Changesets/SolarWinds.Changesets.csproj b/src/SolarWinds.Changesets/SolarWinds.Changesets.csproj
index 1a47387..64cb23d 100644
--- a/src/SolarWinds.Changesets/SolarWinds.Changesets.csproj
+++ b/src/SolarWinds.Changesets/SolarWinds.Changesets.csproj
@@ -41,6 +41,7 @@
+
diff --git a/tests/SolarWinds.Changesets.Tests/ProcessExecutorTests.cs b/tests/SolarWinds.Changesets.Tests/ProcessExecutorTests.cs
index 8dc65fe..280e6ab 100644
--- a/tests/SolarWinds.Changesets.Tests/ProcessExecutorTests.cs
+++ b/tests/SolarWinds.Changesets.Tests/ProcessExecutorTests.cs
@@ -21,7 +21,7 @@ public void SetUp()
_executable = "cmd";
_argumentsTemplate = '/';
}
- else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
+ else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
_executable = "/bin/bash";
_argumentsTemplate = '-';
diff --git a/tests/SolarWinds.Changesets.Tests/Version/CsProjectsRepositoryTests.cs b/tests/SolarWinds.Changesets.Tests/Version/CsProjectsRepositoryTests.cs
index 54eb16a..36486c7 100644
--- a/tests/SolarWinds.Changesets.Tests/Version/CsProjectsRepositoryTests.cs
+++ b/tests/SolarWinds.Changesets.Tests/Version/CsProjectsRepositoryTests.cs
@@ -125,6 +125,6 @@ private static string ComputeFileHash(string path)
using FileStream stream = File.OpenRead(path);
byte[] hashBytes = sha256.ComputeHash(stream);
- return BitConverter.ToString(hashBytes).Replace("-", "", StringComparison.Ordinal).ToUpperInvariant();
+ return Convert.ToHexString(hashBytes);
}
}