In the world of software development, creating custom tools can significantly enhance your workflow and streamline repetitive tasks. .NET tools offer a powerful and versatile approach to building cross-platform command-line utilities specifically designed for the .NET ecosystem. This article guides you through the process of creating a simple .NET tool and publishing it to GitHub, making it readily available for other developers.
Let's embark on creating a .NET tool named HelloTool that demonstrates a basic greeting functionality.
dotnet new console -o HelloTool
Replace HelloTool with your preferred tool name.
dotnet new sln --name HelloTool
dotnet sln add HelloTool
Console.WriteLine($"Hello, {(args.Length>0?args[0]:"World")}!");
This code checks for any command-line arguments passed to the tool. If an argument exists, it's used as the name in the greeting. Otherwise, it defaults to "World."
-Prepare your tool for deployment to the NuGet package repository (nuget.org).
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PackAsTool>true</PackAsTool>
<ToolCommandName>hello</ToolCommandName>
<PackageOutputPath>./nupkg</PackageOutputPath>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageId>HelloTool</PackageId>
<Authors>your name</Authors>
<Company>tour email</Company>
<Product>HelloTool</Product>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageProjectUrl>https://github.com/dejandjenic/hello-tool</PackageProjectUrl>
</PropertyGroup>
<ItemGroup>
<None Include="README.md" Pack="true" PackagePath="\" />
</ItemGroup>
</Project>
This configuration specifies:
create a file called GetBuildVersion.psm1 and paste the code bellow
Function GetBuildVersion {
Param (
[string]$VersionString
)
# Process through regex
$VersionString -match "(?<major>\d+)(\.(?<minor>\d+))?(\.(?<patch>\d+))?(\-(?<pre>[0-9A-Za-z\-\.]+))?(\+(?<build>\d+))?" | Out-Null
if ($matches -eq $null) {
return "1.0.0-build"
}
# Extract the build metadata
$BuildRevision = [uint64]$matches['build']
# Extract the pre-release tag
$PreReleaseTag = [string]$matches['pre']
# Extract the patch
$Patch = [uint64]$matches['patch']
# Extract the minor
$Minor = [uint64]$matches['minor']
# Extract the major
$Major = [uint64]$matches['major']
$Version = [string]$Major + '.' + [string]$Minor + '.' + [string]$Patch;
if ($PreReleaseTag -ne [string]::Empty) {
$Version = $Version + '-' + $PreReleaseTag
}
if ($BuildRevision -ne 0) {
$Version = $Version + '.' + [string]$BuildRevision
}
return $Version
}
This section outlines how to leverage GitHub Actions for automated versioning and publishing of your .NET tool.
Navigate to the 'Actions' tab in your GitHub repository. Create a new workflow file (e.g., .github/workflows/dotnet.yml) and paste the following code into it.
name: .NET
on:
create:
branches:
- release/**
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Get Build Version
run: |
Import-Module .\build\GetBuildVersion.psm1
Write-Host $Env:GITHUB_REF
$version = GetBuildVersion -VersionString $Env:GITHUB_REF
echo "BUILD_VERSION=$version" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf-8 -Append
shell: pwsh
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x
- name: Restore dependencies
run: dotnet restore
- name: Build
run: dotnet build --no-restore -p:Version=$BUILD_VERSION
- name: Push
if: startsWith(github.ref, 'refs/heads/release')
run: dotnet nuget push **\*.nupkg --api-key "${{ secrets.NUGET_KEY }}" --source https://api.nuget.org/v3/index.json --skip-duplicate
Create a release branch and verify the build and deployment process.
Once your tool is published on nuget execute in terminal
dotnet tool install -g HelloTool
after installlation process is finished you can use your tool
hello dejan
should output "Hello dejan!"
github repo with this sample can be found https://github.com/dejandjenic/hello-tool
Happy coding!