.NET Project Guardrails
Enforce .NET-specific project standards including project file presence, target framework configuration, dependency locking, test project requirements, and minimum SDK version requirements for both development and CI/CD environments.
dotnet to your lunar-config.yml:uses: github://earthly/lunar-lib/policies/dotnet@v1.0.0
Included Guardrails
This policy includes 6 guardrails that enforce standards for your devex build and ci.
project-file-exists
Ensures the project has at least one .NET project file (.csproj, .fsproj, .vbproj). Required for all .NET projects to be buildable.
target-framework-set
Ensures all project files have a target framework specified. Required for proper compilation and runtime behavior.
dependencies-locked
Ensures the project has packages.lock.json files for dependency locking. Required for reproducible builds and supply chain security.
test-project-exists
Ensures the project has at least one test project. Encourages proper testing practices and quality assurance.
min-sdk-version
Ensures the .NET SDK version meets minimum requirements. Prevents using outdated SDK versions that may have security vulnerabilities or missing features.
min-sdk-version-cicd
Ensures the .NET SDK version used in CI/CD meets minimum requirements. Prevents CI/CD pipelines from using outdated SDK versions.
How Guardrails Fit into Lunar
Lunar guardrails define your engineering standards as code. They evaluate data collected by integrations and produce pass/fail checks with actionable feedback.
Policies support gradual enforcement—from silent scoring to blocking PRs or deployments—letting you roll out standards at your own pace without disrupting existing workflows.
Learn How Lunar Works →Required Integrations
This policy evaluates data gathered by one or more of the following integration(s).
Make sure to enable them in your lunar-config.yml.
Configuration
Configure this policy in your lunar-config.yml.
Inputs
| Input | Required | Default | Description |
|---|---|---|---|
min_sdk_version
|
Optional |
8.0
|
Minimum .NET SDK version required for the project |
min_sdk_version_cicd
|
Optional |
8.0
|
Minimum .NET SDK version required for CI/CD pipelines |
Documentation
View on GitHub.NET Project Guardrails
Enforce .NET project standards including project file presence, target framework configuration, dependency locking, test projects, and SDK version requirements.
Overview
This policy validates .NET projects against best practices for project structure and build configuration. It ensures projects have proper project files, specify target frameworks, use dependency locking for reproducible builds, include test projects for quality assurance, and meet minimum SDK version requirements for both development and CI/CD environments.
Policies
This plugin provides the following policies (use include to select a subset):
| Policy | Description | Severity | Failure Meaning |
|---|---|---|---|
project-file-exists |
Validates .NET project file exists | Error | Project lacks buildable project file |
target-framework-set |
Ensures target framework is specified | Warning | Projects missing framework specification |
dependencies-locked |
Validates packages.lock.json exists | Warning | Dependencies not locked for reproducible builds |
test-project-exists |
Ensures at least one test project exists | Info | No automated tests detected |
min-sdk-version |
Ensures SDK version meets minimum requirements | Warning | Using outdated SDK version |
min-sdk-version-cicd |
Ensures CI/CD SDK version meets minimum requirements | Warning | CI/CD using outdated SDK version |
Required Data
This policy reads from the following Component JSON paths:
| Path | Type | Provided By |
|---|---|---|
.lang.dotnet |
object | dotnet collector |
.lang.dotnet.project_files |
array | dotnet collector |
.lang.dotnet.packages_lock_exists |
boolean | dotnet collector |
.lang.dotnet.test_projects |
array | dotnet collector |
.lang.dotnet.sdk_version |
string | dotnet collector |
.lang.dotnet.cicd.cmds |
array | dotnet collector |
Installation
Add to your lunar-config.yml:
policies:
- uses: github://earthly/lunar-lib/policies/dotnet@v1.0.0
on: ["domain:your-domain"] # replace with your own domain or tags
enforcement: report-pr
# include: [project-file-exists, target-framework-set] # Only run specific checks
# inputs:
# min_sdk_version: "8.0" # Minimum SDK version for development
# min_sdk_version_cicd: "8.0" # Minimum SDK version for CI/CD
Examples
Passing Example
{
"lang": {
"dotnet": {
"sdk_version": "8.0.100",
"target_frameworks": ["net8.0"],
"project_files": [
{
"path": "MyApp/MyApp.csproj",
"type": "csharp",
"target_framework": "net8.0"
}
],
"packages_lock_exists": true,
"test_projects": [
{
"path": "MyApp.Tests/MyApp.Tests.csproj",
"type": "csharp",
"test_framework": "xunit"
}
]
}
}
}
Failing Example
{
"lang": {
"dotnet": {
"project_files": [],
"packages_lock_exists": false,
"test_projects": []
}
}
}
Failure messages:
"No .NET project files found. Create a .csproj, .fsproj, or .vbproj file.""2 of 3 project(s) missing target framework: Add <TargetFramework>net8.0</TargetFramework> to project files.""No packages.lock.json found. Dependencies are not locked.""No test projects detected. Consider adding test projects."
Remediation
project-file-exists
- Create a new .NET project:
dotnet new console(orclasslib,web) - For F# projects:
dotnet new console -lang F# - For existing code: Create a .csproj file manually or migrate from packages.config
target-framework-set
- Add
<TargetFramework>net8.0</TargetFramework>to your .csproj files - Or for multi-targeting:
<TargetFrameworks>net6.0;net8.0</TargetFrameworks> - Choose appropriate framework version for your deployment target
dependencies-locked
- Add
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>to all project files - Run
dotnet restoreto generate packages.lock.json files - Commit all packages.lock.json files to version control
- This ensures consistent dependency versions across environments
test-project-exists
- Create test projects:
dotnet new xunit -n MyProject.Tests(recommended)dotnet new nunit -n MyProject.Testsdotnet new mstest -n MyProject.Tests
- Add project reference:
dotnet add MyProject.Tests reference MyProject.csproj - Write unit tests and run with
dotnet test
min-sdk-version
- Update global.json to specify minimum SDK version:
{ "sdk": { "version": "8.0.100" } } - Install the required SDK version:
dotnet --install-sdk 8.0.100 - Verify installation:
dotnet --version - Consider using
rollForward: "latestMinor"policy for flexibility
min-sdk-version-cicd
- Update CI/CD pipeline files to use required SDK version:
- GitHub Actions: Update
dotnet-versionin setup-dotnet action - Azure DevOps: Update
versionin DotNetCoreCLI task - Jenkins: Update SDK version in docker image or installation step
- GitHub Actions: Update
- Example GitHub Actions update:
- uses: actions/setup-dotnet@v3 with: dotnet-version: '8.0.x' - Test pipeline with updated SDK version before merging
Open Source
This policy is open source and available on GitHub. Contribute improvements, report issues, or fork it for your own use.
Common Use Cases
Explore how individual guardrails work with specific integrations.
Ready to Automate Your Standards?
See how Lunar can turn your engineering wiki, compliance docs, or postmortem action items into automated guardrails with our 100+ built-in guardrails.