Create .github/workflows/codeql.yml:
name: "CodeQL"
on:
push:
branches: [main, master]
pull_request:
branches: [main, master]
schedule:
- cron: '30 5 * * 1' # Weekly Monday 5:30 AM UTC
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: ['csharp']
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'
- name: Build
run: dotnet build --configuration Release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{ matrix.language }}"Explicit control over the build process:
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: csharp
build-mode: manual
- name: Build
run: |
dotnet restore
dotnet build --no-restore --configuration ReleaseLet CodeQL detect and run the build:
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: csharp
build-mode: autobuildAutobuild limitations:
- May not find all projects in complex solutions
- Custom build steps are not executed
- May miss conditional compilation
Not applicable for C#/.NET compiled code.
Create .github/codeql/codeql-config.yml:
name: "Custom CodeQL Config"
queries:
- uses: security-extended
- uses: security-and-quality
paths:
- src
paths-ignore:
- "**/Tests/**"
- "**/*.Designer.cs"
- "**/Migrations/**"
- "**/obj/**"
- "**/bin/**"Reference in workflow:
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: csharp
config-file: .github/codeql/codeql-config.ymlFor solutions with multiple projects:
- name: Build Solution
run: |
dotnet restore MySolution.sln
dotnet build MySolution.sln --no-restore -c Release
# Or build specific projects
- name: Build Projects
run: |
dotnet build src/Api/Api.csproj -c Release
dotnet build src/Core/Core.csproj -c ReleaseFor legacy .NET Framework:
jobs:
analyze:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: csharp
build-mode: manual
- name: Setup MSBuild
uses: microsoft/setup-msbuild@v2
- name: Setup NuGet
uses: NuGet/setup-nuget@v2
- name: Restore NuGet packages
run: nuget restore MySolution.sln
- name: Build
run: msbuild MySolution.sln /p:Configuration=Release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3on:
pull_request:
branches: [main]
paths:
- '**.cs'
- '**.csproj'
- '**.sln'on:
schedule:
# Daily at 2 AM UTC
- cron: '0 2 * * *'on:
workflow_dispatch:
inputs:
query-suite:
description: 'Query suite to use'
required: false
default: 'security-extended'Automatic with github/codeql-action/analyze:
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:csharp"
output: sarif-results
upload: always # or 'failure-only' or 'never'- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: results.sarif
category: "custom-analysis"- name: Upload SARIF as artifact
uses: actions/upload-artifact@v7
with:
name: sarif-results
path: sarif-results
retention-days: 5- name: Cache NuGet packages
uses: actions/cache@v4
with:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
restore-keys: |
${{ runner.os }}-nuget-strategy:
fail-fast: false
matrix:
include:
- project: src/Api/Api.csproj
name: api
- project: src/Web/Web.csproj
name: webjobs:
analyze:
timeout-minutes: 60permissions:
actions: read # Required for workflow runs
contents: read # Required to checkout code
security-events: write # Required to upload SARIFpermissions:
pull-requests: read
security-events: write- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: csharp
debug: trueCheck autobuild logs:
- name: Autobuild
uses: github/codeql-action/autobuild@v3
continue-on-error: true
- name: Manual build fallback
if: failure()
run: dotnet build- name: Check database
run: |
ls -la ${{ runner.temp }}/codeql_databases/For private repositories:
- GitHub Advanced Security license required for GitHub-hosted scanning
- Self-hosted runners with CodeQL CLI may have different licensing
- Verify licensing requirements with GitHub before enabling