An opinionated task and build automation framework#
License
—
Deps
3
Install Size
—
Vulns
✓ 0
Published
Jan 23, 2026
$ dotnet add package DecSm.Atom.Module.DotnetAtom is an opinionated task and build automation framework, written in C#.
Inspired by the likes of NUKE, Atom aims to provide a flexible, extensible framework for defining and executing build tasks. It leverages .NET and provides a comprehensive set of features for automating your development workflow with automatic CI/CD pipeline generation e.g. for GitHub Actions and Azure DevOps.
Create a new console application and add the Atom package:
dotnet new console -n MyBuild
cd MyBuild
dotnet add package DecSm.Atom
Create a Build.cs file:
using DecSm.Atom.Build.Definition;
using DecSm.Atom.Hosting;
namespace MyBuild;
[BuildDefinition]
[GenerateEntryPoint]
internal partial class Build : BuildDefinition
{
private Target HelloWorld =>
t => t
.DescribedAs("Prints a hello world message")
.Executes(() => Logger.LogInformation("Hello, World!"));
}
Targets can also be async:
private Target HelloWorldAsync =>
t => t
.DescribedAs("Prints a hello world message asynchronously")
.Executes(async () =>
{
await Task.Delay(1000); // Simulate async work
Logger.LogInformation("Hello, World!");
});
private Target HelloWorldAsyncWithCancel =>
t => t
.DescribedAs("Prints a hello world message asynchronously")
.Executes(async cancellationToken =>
{
await Task.Delay(1000, cancellationToken); // Simulate async work with cancellation
Logger.LogInformation("Hello, World!");
});dotnet run -- HelloWorldBuild definitions are classes that inherit from BuildDefinition and define targets (build steps) as properties:
[BuildDefinition]
internal partial class Build : BuildDefinition
{
private Target Compile => t => t
.DescribedAs("Compiles the project")
.Executes(() =>
{
// Your build logic here
});
}Define and use parameters in your builds:
[ParamDefinition("my-name", "Name to greet")]
private string? MyName => GetParam(() => MyName);
private Target Hello => t => t
.RequiresParam(nameof(MyName))
.Executes(() =>
{
Logger.LogInformation("Hello, {Name}!", MyName);
});Define dependencies between targets:
private Target Test => t => t
.DependsOn(Compile)
.Executes(() =>
{
// Run tests after compilation
});You can also define targets using interfaces for better organization:
using DecSm.Atom.Build.Definition;
[BuildDefinition]
internal partial class Build : BuildDefinition, ICompile, ITest;
public interface ICompile
{
Target Compile => t => t
.DescribedAs("Compiles the project")
.Executes(() =>
{
// Your build logic here
});
}
public interface ITest
{
Target Test => t => t
.DependsOn(Compile)
.Executes(() =>
{
// Run tests after compilation
});
}You can access various build services like logging, parameters, and secrets:
public interface ICompile : IBuildAccessor
{
Target Compile => t => t
.DescribedAs("Compiles the project")
.Executes(() =>
{
Logger.LogInformation("Compiling project...");
FileSystem.File.Create("output.txt");
Services.Get<IService>().DoSomething();
});
}Atom can automatically generate CI/CD pipelines for your builds:
Install the required modules for your CI/CD platform (GitHub Actions, Azure DevOps, etc.):
dotnet add package DecSm.Atom.Module.GithubWorkflows[BuildDefinition]
public partial class Build : BuildDefinition, IGithubWorkflows
{
public override IReadOnlyList<WorkflowDefinition> Workflows =>
[
new("ci")
{
Triggers = [new GitPullRequestTrigger { IncludedBranches = ["main"] }],
StepDefinitions = [Targets.Test],
WorkflowTypes = [new GithubWorkflowType()]
}
];
}Install the required modules for your CI/CD platform (GitHub Actions, Azure DevOps, etc.):
dotnet add package DecSm.Atom.Module.DevopsWorkflows[BuildDefinition]
public partial class Build : BuildDefinition, IDevopsWorkflows
{
public override IReadOnlyList<WorkflowDefinition> Workflows =>
[
new("ci")
{
Triggers = [new GitPullRequestTrigger { IncludedBranches = ["main"] }],
StepDefinitions = [Targets.Test],
WorkflowTypes = [new DevopsWorkflowType()]
}
];
}Atom provides several modules for different functionalities:
Add modules to your build definition:
[BuildDefinition]
public partial class Build : BuildDefinition,
IGithubWorkflows,
IDotnetPackHelper,
IAzureKeyVault
{
// Your build targets here
}Atom supports artifact management with automatic upload/download in CI/CD pipelines:
private Target Package => t => t
.ProducesArtifact("MyPackage") // Workflows automatically upload this artifact
.Executes(() => {
// Create your package
return Task.CompletedTask;
});
private Target Deploy => t => t
.ConsumesArtifact(nameof(Package), "MyPackage") // Workflows automatically download this artifact
.Executes(() =>
{
// Deploy the package
});Atom supports variable management for build parameters and secrets:
[ParamDefinition("my-name", "Name to greet")]
private string? MyName => GetParam(() => MyName);
private Target Info => t => t
.ProducesVariable("MyPackage")
.Executes(() =>
{
// Variable writing is done manually
Services.GetRequiredService<IVariablesHelper>().WriteVariable(nameof(MyName), "Declan");
});
private Target Print => t => t
.ConsumesVariable(nameof(Info), "MyPackage") // Workflows automatically inject this variable
.Executes(() =>
{
// Using the variable
Logger.LogInformation("Hello, {Name}!", MyName);
// output: Hello, Declan!
});Run builds across multiple configurations:
public override IReadOnlyList<WorkflowDefinition> Workflows =>
[
new("build")
{
StepDefinitions =
[
Targets.Test.WithMatrixDimensions(
new MatrixDimension("os", ["ubuntu-latest", "windows-latest", "macos-latest"])),
],
}
];
Use custom artifact storage backends:
public override IReadOnlyList<WorkflowDefinition> Workflows =>
[
new("build")
{
Options = [UseCustomArtifactProvider.Enabled],
// ... other configuration
}
];Integrate with Azure Key Vault:
Install the required module for Azure Key Vault:
dotnet add package DecSm.Atom.Module.AzureKeyVault[BuildDefinition]
public partial class Build : BuildDefinition, IAzureKeyVault
{
[SecretDefinition("my-secret", "Description of the secret")]
private string MySecret => GetSecret(() => MySecret);
}Check out the sample projects:
Atom can build itself!
git clone https://github.com/DecSmith42/atom.git
cd atom
dotnet run --project _atom -- PackAtomEven faster if you've installed the Atom tool globally:
atom PackAtomOr the old-fashioned way:
dotnet build _atom/Atom.csprojdotnet run --project _atom -- TestAtomContributions are welcome! Please feel free to submit a Pull Request.
Atom is released under the MIT License. See the LICENSE file for details.