Deploy dotnet CLI tools

I have mentioned in other posts that I have been working on building and refining tools that help me make the development of this blog more about the writing than the maintenance. The majority of the tools I have been working on are executed as CLI tools.
This is not the most glamorous type of interface; however, it is practical and pretty easy to extend. In a former role, I have deployed CLI tools to my machine, and it was kinda annoying. You had to choose a deployment directory somewhere on the machine, then add the directory to the path. Maybe I am overselling how annoying it is, maybe I just didn’t want to do it.
Assuming you are a dotnet developer, there is now a much easier way to build and deploy CLI tooling. The dotnet CLI team implemented a way to develop your own custom tools. This was deployed with dotnet Core 2.1 back in May of 2018. In this post, we are going to go through the steps to deploy your own CLI tooling.
First, you need to have a dotnet cli solution that is dotnet core 2.1 or newer. Given its 2026 and we are on dotnet 10, I do not think that will be too difficult to obtain. For this example, we will assume the project structure is:
~\Generator\src\
|- Generator.sln
|- Generator\
|- Generator.csproj
|- Program.cs
|- Generator.Test\
|- Generator.Test.csproj
|- UnitTest.cs
To deploy the project, there needs to be an update to the Generator.csproj file. Within the first node of the csproj file, add the following data:
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PackAsTool>true</PackAsTool>
<ToolCommandName>blog</ToolCommandName>
<PackageOutputPath>.\deployment-package</PackageOutputPath>
</PropertyGroup>
Note the value of the property PackageOutputPath, which is the location of the Nuget package data. We will use that in a future step.
The first build step we will want to do is run the tests by executing the command in the project directory: dotnet test .\src\Generator.sln
With all the tests passing successfully, the CLI tool then needs to be packaged into a Nuget package. That can be done with this command: dotnet pack .\src\Generator.sln -c Release. Note, that this particular command is building the package in Release mode.
Now that we have a Nuget package, the only next step is to deploy the CLI tool! To do that execute this command: dotnet tool install —global —add-source .\src\Generator\deployment-package Generator
That is all you need to get up and running with your first dotnet tool CLI deployment. If you are like me and want a script to simplify the deployment process, you will need to check for previous versions of the tool install, removing them if one is found. As the current version of the dotnet tool cli does not support forcing an install over an existing install. Since I am a regular PowerShell user, I created my deployment script using PowerShell. Adding colors to the output to make it quickly scannable for errors. For the majority of the calls to dotnet tools, I also added —verbosity quiet to reduce the output of the deployment script, for overall noise reduction once the script was working to my liking.