November 10 2025
mkdir dotnet-ci-hardening-demo
cd dotnet-ci-hardening-demo
git init
dotnet new sln -n Acme
dotnet new classlib -n Acme.Calculator
dotnet sln Acme.sln add Acme.Calculator/Acme.Calculator.csproj
<!-- Directory.Build.props -->
<Project>
<PropertyGroup>
<!-- Enable analyzers and modern analysis level -->
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<AnalysisLevel>latest</AnalysisLevel>
<!-- Make style warnings fail the build -->
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<!-- For deterministic builds -->
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
<Deterministic>true</Deterministic>
<DebugType>portable</DebugType>
</PropertyGroup>
<!-- Ignore a few less important warnings -->
<PropertyGroup>
<WarningsNotAsErrors>$(WarningsNotAsErrors);CS1591</WarningsNotAsErrors>
</PropertyGroup>
<!-- Add more analyzers -->
<ItemGroup>
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.556" PrivateAssets="All" />
<PackageReference Include="Roslynator.Analyzers" Version="4.12.4" PrivateAssets="All" />
</ItemGroup>
</Project>
root = true
[*.cs]
charset = utf-8
indent_style = space
indent_size = 4
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
# Usings and ordering
dotnet_sort_system_directives_first = true:warning
dotnet_separate_import_directive_groups = true:warning
# Qualification rules
dotnet_style_qualification_for_field = false:warning
dotnet_style_qualification_for_property = false:warning
dotnet_style_qualification_for_method = false:warning
# Analyzer examples
dotnet_diagnostic.IDE0005.severity = warning # Remove unused usings
dotnet_diagnostic.SA1200.severity = warning # Using placement
dotnet_diagnostic.RCS1213.severity = warning # Remove unused members
# Optional: relax doc comment warnings
dotnet_diagnostic.CS1591.severity = none
# Disable StyleCop file header & XML comment rules
dotnet_diagnostic.SA1633.severity = none # File must have a header
dotnet_diagnostic.SA1636.severity = none # Header text must match
dotnet_diagnostic.SA1638.severity = none # File header must include filename
dotnet_diagnostic.SA0001.severity = none # Disable XML comment analysis warning
dotnet_diagnostic.CS1591.severity = none # Ignore "missing XML comment" warnings
dotnet_diagnostic.IDE0005.severity = none

// Client picks columns: "CustomerID,Name,Country"
using System; // unused
using System.Threading.Tasks; // unused
namespace Acme.Calculator
{
public class Calculator
{
public int Add(int a,int b){ return a + b; } // bad spacing + analyzer warnings
}
}
dotnet build -c Release /warnaserror
dotnet format --verify-no-changes
name: CI
on:
push:
branches: [ main ]
pull_request:
jobs:
build-test-format:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 9.0.x
- name: Cache NuGet
uses: actions/cache@v4
with:
path: ~/.nuget/packages
key: nuget-${ { runner.os } }-${ { hashFiles('**/*.csproj') } }
restore-keys: nuget-${ { runner.os } }-
- name: Restore
run: dotnet restore
- name: Build (warnings as errors)
run: dotnet build --no-restore -c Release /warnaserror
- name: Format (verify)
run: dotnet format --no-restore --verify-no-changes
git checkout -b feature/failing-pr
git add .
git commit -m "add intentionally bad formatting"
git push -u origin feature/failing-pr
IDE0005: Using directive is unnecessary.
SA1200: Using directives must be placed outside the namespace.

namespace Acme.Calculator
{
public static class Calculator
{
public static int Add(int a, int b)
{
return a + b;
}
}
}
git add .
git commit -m "fix: clean code formatting and remove unused usings"
git push

dotnet new xunit -n Acme.Calculator.Tests
dotnet sln add Acme.Calculator.Tests/Acme.Calculator.Tests.csproj
dotnet add Acme.Calculator.Tests reference Acme.Calculator
namespace Acme.Calculator.Tests
{
/// <summary>
/// Calculator Tests.
/// </summary>
public class CalculatorTests
{
/// <summary>
/// Add tests.
/// </summary>
[Fact]
public void Add_ReturnsSum()
{
int result = Calculator.Add(2, 3);
Assert.Equal(5, result);
}
}
}
- name: Test
run: dotnet test --no-build -c Release

1. Design Patterns that Deliver
This isn’t just another design patterns book. Dive into real-world examples and practical solutions to real problems in real applications.Check out it here.
Go-to resource for understanding the core concepts of design patterns without the overwhelming complexity. In this concise and affordable ebook, I've distilled the essence of design patterns into an easy-to-digest format. It is a Beginner level. Check out it here.
Every Monday morning, I share 1 actionable tip on C#, .NET & Arcitecture topic, that you can use right away.
Join 17,150+ subscribers to improve your .NET Knowledge.
Subscribe to the TheCodeMan.net and be among the 17,150+ subscribers gaining practical tips and resources to enhance your .NET expertise.