Update Jenkins file.
This commit is contained in:
parent
1fe968196e
commit
16482f82b3
97
Jenkinsfile
vendored
97
Jenkinsfile
vendored
@ -1,14 +1,12 @@
|
|||||||
pipeline {
|
pipeline {
|
||||||
agent none
|
agent none
|
||||||
|
options { ansiColor('xterm'); timestamps() }
|
||||||
|
|
||||||
environment {
|
environment {
|
||||||
// Optional: tweak for speed
|
|
||||||
DOTNET_CLI_TELEMETRY_OPTOUT = '1'
|
DOTNET_CLI_TELEMETRY_OPTOUT = '1'
|
||||||
DOTNET_SKIP_FIRST_TIME_EXPERIENCE = '1'
|
DOTNET_SKIP_FIRST_TIME_EXPERIENCE = '1'
|
||||||
|
SONAR_PROJECT_KEY = 'as400api-dotnet' // <-- change if you like
|
||||||
// Sonar: set host via withSonarQubeEnv; token via credentials below
|
SONAR_PROJECT_NAME = 'AS400_API_DOTNET (.NET 9)'
|
||||||
SONAR_PROJECT_KEY = 'AS400-API'
|
|
||||||
SONAR_PROJECT_NAME = 'AS/400 API (.NET9)'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stages {
|
stages {
|
||||||
@ -17,56 +15,57 @@ pipeline {
|
|||||||
steps { checkout scm }
|
steps { checkout scm }
|
||||||
}
|
}
|
||||||
|
|
||||||
stage('SCA (Dependency Audit)') {
|
stage('SCA (NuGet vulnerabilities + OWASP)') {
|
||||||
// Run inside official .NET 9 SDK image
|
agent { docker { image 'mcr.microsoft.com/dotnet/sdk:9.0'; reuseNode true } }
|
||||||
agent {
|
|
||||||
docker { image 'mcr.microsoft.com/dotnet/sdk:9.0'; reuseNode true }
|
|
||||||
}
|
|
||||||
steps {
|
steps {
|
||||||
sh '''
|
sh '''
|
||||||
|
set -e
|
||||||
dotnet --info
|
dotnet --info
|
||||||
# 1) Built-in vulnerability audit (NuGet advisory DB)
|
|
||||||
dotnet restore
|
dotnet restore
|
||||||
# dotnet list package --vulnerable exits 0 even when vulnerabilities found; use Jenkins Warnings NG to surface, or grep to fail on high
|
|
||||||
|
echo "=== NuGet vulnerability audit ==="
|
||||||
|
# Prints known vulnerable packages (won't fail the build by default)
|
||||||
dotnet list package --vulnerable || true
|
dotnet list package --vulnerable || true
|
||||||
|
|
||||||
# 2) (Optional) OWASP Dependency-Check via Docker
|
echo "=== OWASP Dependency-Check (try Docker first) ==="
|
||||||
# Scans csproj/packages.lock.json for known CVEs
|
|
||||||
mkdir -p depcheck
|
mkdir -p depcheck
|
||||||
docker run --rm \
|
if command -v docker >/dev/null 2>&1; then
|
||||||
-v "$PWD":/src \
|
docker run --rm \
|
||||||
-v "$PWD/depcheck":/report \
|
-v "$PWD":/src \
|
||||||
owasp/dependency-check:latest \
|
-v "$PWD/depcheck":/report \
|
||||||
--scan /src \
|
owasp/dependency-check:latest \
|
||||||
--format "HTML" \
|
--scan /src --format "HTML" --out /report || true
|
||||||
--out /report || true
|
else
|
||||||
echo "Dependency-Check report at depcheck/dependency-check-report.html"
|
echo "Docker not found; falling back to CLI zip…"
|
||||||
|
curl -sSL -o depcheck.zip https://github.com/jeremylong/DependencyCheck/releases/latest/download/dependency-check.zip || true
|
||||||
|
if [ -f depcheck.zip ]; then
|
||||||
|
unzip -q depcheck.zip -d depcheckcli || true
|
||||||
|
java -jar depcheckcli/dependency-check/bin/dependency-check.jar \
|
||||||
|
--scan . --format HTML --out depcheck || true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "SCA reports generated in depcheck/"
|
||||||
'''
|
'''
|
||||||
// You can archive the HTML report for viewing in Jenkins
|
}
|
||||||
archiveArtifacts artifacts: 'depcheck/**', allowEmptyArchive: true
|
post {
|
||||||
|
always {
|
||||||
|
archiveArtifacts artifacts: 'depcheck/**', allowEmptyArchive: true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stage('SAST + Coverage (SonarQube + Tests)') {
|
stage('SAST + Coverage (SonarQube + Tests)') {
|
||||||
agent {
|
agent { docker { image 'mcr.microsoft.com/dotnet/sdk:9.0'; reuseNode true } }
|
||||||
docker {
|
environment { SONAR_TOKEN = credentials('sonar-token') }
|
||||||
// Use SDK image; we’ll install scanner + reportgenerator inside
|
|
||||||
image 'mcr.microsoft.com/dotnet/sdk:9.0'
|
|
||||||
reuseNode true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
environment {
|
|
||||||
SONAR_TOKEN = credentials('sonar-token')
|
|
||||||
}
|
|
||||||
steps {
|
steps {
|
||||||
withSonarQubeEnv('SonarQubeServer') {
|
withSonarQubeEnv('SonarQubeServer') {
|
||||||
sh '''
|
sh '''
|
||||||
# Install dotnet tools we need
|
set -e
|
||||||
dotnet tool install --global dotnet-sonarscanner --version 7.*
|
dotnet tool install --global dotnet-sonarscanner --version 7.*
|
||||||
dotnet tool install --global dotnet-reportgenerator-globaltool
|
dotnet tool install --global dotnet-reportgenerator-globaltool
|
||||||
export PATH="$PATH:/root/.dotnet/tools"
|
export PATH="$PATH:/root/.dotnet/tools"
|
||||||
|
|
||||||
# Begin Sonar analysis (SAST + quality gates)
|
|
||||||
dotnet sonarscanner begin \
|
dotnet sonarscanner begin \
|
||||||
/k:"$SONAR_PROJECT_KEY" \
|
/k:"$SONAR_PROJECT_KEY" \
|
||||||
/n:"$SONAR_PROJECT_NAME" \
|
/n:"$SONAR_PROJECT_NAME" \
|
||||||
@ -75,22 +74,17 @@ pipeline {
|
|||||||
/d:sonar.cs.opencover.reportsPaths="**/TestResults/**/coverage.opencover.xml" \
|
/d:sonar.cs.opencover.reportsPaths="**/TestResults/**/coverage.opencover.xml" \
|
||||||
/d:sonar.coverage.exclusions="**/*.cshtml,**/Migrations/**"
|
/d:sonar.coverage.exclusions="**/*.cshtml,**/Migrations/**"
|
||||||
|
|
||||||
# Build (needed for Sonar to analyze)
|
dotnet build -c Release
|
||||||
dotnet restore
|
# run tests; produce OpenCover coverage for Sonar
|
||||||
dotnet build -c Release --no-restore
|
# If your test project path differs, specify it explicitly or run at solution level:
|
||||||
|
dotnet test -c Release \
|
||||||
# Test + Coverage (OpenCover format for Sonar)
|
|
||||||
# This uses coverlet.msbuild (works without editing csproj)
|
|
||||||
# Generates: ./<testproject>/TestResults/<GUID>/coverage.opencover.xml
|
|
||||||
dotnet test -c Release --no-build \
|
|
||||||
/p:CollectCoverage=true \
|
/p:CollectCoverage=true \
|
||||||
/p:CoverletOutputFormat=opencover \
|
/p:CoverletOutputFormat=opencover \
|
||||||
/p:CoverletOutput=./TestResults/coverage
|
/p:CoverletOutput=./TestResults/coverage
|
||||||
|
|
||||||
# End Sonar (uploads results to server)
|
|
||||||
dotnet sonarscanner end /d:sonar.login="$SONAR_TOKEN"
|
dotnet sonarscanner end /d:sonar.login="$SONAR_TOKEN"
|
||||||
|
|
||||||
# Optional: create a single Cobertura report for Jenkins UI
|
# Generate a Cobertura report for Jenkins Coverage UI
|
||||||
reportgenerator \
|
reportgenerator \
|
||||||
-reports:**/TestResults/**/coverage.opencover.xml \
|
-reports:**/TestResults/**/coverage.opencover.xml \
|
||||||
-targetdir:coverage-report \
|
-targetdir:coverage-report \
|
||||||
@ -100,7 +94,6 @@ pipeline {
|
|||||||
}
|
}
|
||||||
post {
|
post {
|
||||||
always {
|
always {
|
||||||
// Publish coverage into Jenkins (Cobertura)
|
|
||||||
publishCoverage adapters: [coberturaAdapter('coverage-report/Cobertura.xml')],
|
publishCoverage adapters: [coberturaAdapter('coverage-report/Cobertura.xml')],
|
||||||
sourceFileResolver: sourceFiles('STORE_LAST_BUILD')
|
sourceFileResolver: sourceFiles('STORE_LAST_BUILD')
|
||||||
junit '**/TestResults/**/*.trx'
|
junit '**/TestResults/**/*.trx'
|
||||||
@ -110,11 +103,10 @@ pipeline {
|
|||||||
}
|
}
|
||||||
|
|
||||||
stage('Build Artifact') {
|
stage('Build Artifact') {
|
||||||
agent {
|
agent { docker { image 'mcr.microsoft.com/dotnet/sdk:9.0'; reuseNode true } }
|
||||||
docker { image 'mcr.microsoft.com/dotnet/sdk:9.0'; reuseNode true }
|
|
||||||
}
|
|
||||||
steps {
|
steps {
|
||||||
sh '''
|
sh '''
|
||||||
|
set -e
|
||||||
dotnet publish -c Release -o out
|
dotnet publish -c Release -o out
|
||||||
ls -la out
|
ls -la out
|
||||||
'''
|
'''
|
||||||
@ -122,9 +114,4 @@ pipeline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
options {
|
|
||||||
ansiColor('xterm')
|
|
||||||
timestamps()
|
|
||||||
}
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user