✅ Introduction
Modern development demands security from the very first line of code.
Static Application Security Testing (SAST) tools help developers detect vulnerabilities early in the development lifecycle.
In this article, I’ll walk you through how to apply Codacy, a powerful but lightweight SAST platform, to an ASP.NET Core MVC project from scratch, including:
- ✅ Project creation
- 🧪 Test setup
- 📊 Code coverage analysis
- ⚙️ GitHub Actions CI/CD
- ☁️ Automatic upload to Codacy
🛠️ Step-by-step project setup
🔹 Step 1: Create the base solution and projects
mkdir CodacyDemoApp
cd CodacyDemoApp
dotnet new sln -n CodacyDemo
dotnet new mvc -n CodacyDemoApp
dotnet new xunit -n CodacyDemoApp.Tests
dotnet sln CodacyDemo.sln add CodacyDemoApp/CodacyDemoApp.csproj
dotnet sln CodacyDemo.sln add CodacyDemoApp.Tests/CodacyDemoApp.Tests.csproj
dotnet add CodacyDemoApp.Tests/CodacyDemoApp.Tests.csproj reference CodacyDemoApp/CodacyDemoApp.csproj
🔹 Step 2: Add a vulnerable class for Codacy to analyze
CodacyDemoApp/Models/User.cs
namespace CodacyDemoApp.Models
{
public class User
{
public string Username { get; set; }
public string Password { get; set; } // insecure on purpose
}
}
🔹 Step 3: Create a unit test
CodacyDemoApp.Tests/UnitTest1.cs
using CodacyDemoApp.Models;
using Xunit;
namespace CodacyDemoApp.Tests
{
public class UserTests
{
[Fact]
public void Should_Create_User_With_Username_And_Password()
{
var user = new User { Username = "admin", Password = "123" };
Assert.Equal("admin", user.Username);
Assert.Equal("123", user.Password);
}
}
}
🔹 Step 4: Run tests and generate coverage
dotnet test CodacyDemoApp.Tests/CodacyDemoApp.Tests.csproj --collect:"XPlat Code Coverage"
🔹 Step 5: Convert coverage to Codacy-compatible format
dotnet tool install --global dotnet-reportgenerator-globaltool
reportgenerator -reports:**/coverage.cobertura.xml -targetdir:coverage-report -reporttypes:Cobertura
🤖 Step 7: Create GitHub Actions workflow
.github/workflows/codacy.yml
name: Codacy Coverage
on:
push:
branches: [ main ]
workflow_dispatch:
jobs:
analyze:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.x'
- name: Restore dependencies
run: dotnet restore
- name: Run tests with coverage
run: dotnet test CodacyDemoApp.Tests/CodacyDemoApp.Tests.csproj --collect:"XPlat Code Coverage"
- name: Install ReportGenerator
run: dotnet tool install --global dotnet-reportgenerator-globaltool
- name: Generate coverage.xml
run: |
reportgenerator -reports:**/coverage.cobertura.xml -targetdir:coverage-report -reporttypes:Cobertura
- name: Upload to Codacy
shell: bash
env:
CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }}
run: |
curl -Ls https://coverage.codacy.com/get.sh | bash
./codacy-coverage-reporter report -r coverage-report/Cobertura.xml
🔐 Step 8: Configure Codacy
- Go to https://app.codacy.com
- Import your GitHub repo
- Go to Settings > Integrations
- Create a new Project API Token
- Go back to GitHub > Settings > Secrets > Actions
- Add new secret: Name: CODACY_PROJECT_TOKEN Value: (Paste your token)
💻 GitHub Repository
👉 Demo Code + GitHub Actions ready to deploy:
🔗 View on GitHub
This repository includes:
- ✅ ASP.NET Core MVC project (
CodacyDemoApp
) - 🧪 Unit test project with xUnit (
CodacyDemoApp.Tests
) - 🔍 Static analysis with Codacy
- 📊 Code coverage reports
- ⚙️ GitHub Actions workflow:
.github/workflows/codacy.yml
- 📄 Detailed setup instructions in
README.md
✅ What Codacy detects
Hardcoded passwords
Unused code
Unvalidated input (if added)
Code style issues
Code coverage metric
📊 Example Result
Once set up, Codacy will give you:
Code grade (A–F)
% test coverage
Security, duplication, and style warnings
GitHub PR comments with inline suggestions
🎓 Conclusion
This guide showed how to:
Build a secure, testable .NET app from scratch
Use xUnit for basic unit testing
Generate real code coverage reports
Integrate everything into Codacy and CI/CD
✅ You now have a clean, secure, and automated pipeline for your ASP.NET Core project.