A repository task runner built on modern .NET
Your build script is just C#
Every repository accumulates a pile of YAML, shell, and copy-pasted pipeline steps that nobody can run locally and nobody wants to change. DotNetDo moves it into the language you already ship, where the compiler checks it, your IDE understands it, and it runs the same on your laptop and in CI.
A whole build task in one file
DotNetDo is built on .NET 10 file-based apps. A shebang, a package reference, and the file is a runnable task. No project, no scaffolding, no build step in front of your build.
- Parameters are declared in code and exposed on the command line
- Tool commands are records, so options are discoverable and type-checked
./do buildruns it anywhere; add--version-suffix beta.1when you need it
#!/usr/bin/env dotnet
#:package DotNetDo.Core@0.7.0
using DotNetDo;
using static DotNetDo.Tools;
[assembly: TaskDescription("Build, test, and package the solution.")]
var versionSuffix = Do.Param("version-suffix");
await DotNet.Test;
await (DotNet.Pack with
{
VersionSuffix = versionSuffix,
Output = Do.RootDirectory / "artifacts",
});
Why write automation in C#
Build logic is real logic. It deserves the same tools as the rest of your code.
Code, not configuration
Autocomplete finds the options, the compiler catches the typos, and rename refactoring reaches your build. Nothing important hides inside an unchecked string.
Modern .NET, no ceremony
File-based apps mean a task is a single .cs file. Nothing to scaffold, nothing to keep in sync, nothing standing between an idea and running it.
Batteries included
Typed commands wrap the tools you already run, like dotnet, git, and npm. Paths, secrets, and logging come in the box. Fill in properties instead of stitching together a command line.
The same script everywhere
What you debug on your laptop is what CI runs. Paths are cross-platform by construction, and the CI provider is detected for you, so the pipeline stays a one-liner.
From nothing to a working build
Install the global tool. DotNetDo needs the .NET 10 SDK.
dotnet tool install --global DotNetDo
Set up the workspace and its local launchers.
dotnetdo :init
Run a task by name, with completion in your shell.
./do build
Let's do it
Start with a single task and move the rest of the pipeline over as you go. Nothing has to migrate at once.