Files
secdevops-csharp-app/Jenkinsfile
Achim H. dacd8fd7c4
Some checks failed
csharp-secdevops-pipeline-pod/pipeline/head There was a failure building this commit
fixed missing comma
2026-05-07 12:03:20 +02:00

169 lines
6.6 KiB
Groovy

pipeline {
agent {
kubernetes {
// Definiert den Pod mit dem .NET 8 SDK Image
yaml '''
apiVersion: v1
kind: Pod
spec:
containers:
- name: dotnet8
image: mcr.microsoft.com/dotnet/sdk:8.0
command:
- cat
tty: true
- name: trivy
image: aquasec/trivy:latest
command:
- cat
tty: true
- name: kaniko
image: gcr.io/kaniko-project/executor:v1.23.1-debug
command: ["sleep"]
args: ["99d"]
'''
}
}
options {
// Log-Rotation: Bewahre nur die letzten 10 Builds auf
// und lösche Berichte/Artefakte von Builds, die älter als 7 Tage sind.
buildDiscarder(logRotator(numToKeepStr: '10', artifactNumToKeepStr: '10', daysToKeepStr: '7'))
}
stages {
stage('Checkout Source') {
steps {
// Ersetze 'dein-user' und 'dein-repo' durch die Namen aus Gitea
git url: 'http://130.61.26.230:30080/dev-master/secdevops-csharp-app.git',
branch: 'master'
}
}
stage('Build with .NET 8') {
steps {
// Führt den Build-Befehl im spezialisierten Container aus
container('dotnet8') {
sh 'dotnet --version' // Zur Bestätigung der Version
sh 'dotnet build'
}
}
}
stage('Security: Trivy Scan') {
steps {
container('trivy') {
// Wir erstellen ein Verzeichnis für den Report
sh 'mkdir -p reports'
// Der Befehl erzeugt die HTML-Datei
// --format template: Nutzt ein Layout
// --template "@/contrib/html.tpl": Das Standard-Trivy-Layout
// Scannt das Dateisystem auf Schwachstellen (NuGet) und Secrets
// --exit-code 1 lässt die Pipeline bei kritischen Fehlern abbrechen
sh 'trivy fs --scanners vuln,misconfig,secret,license --exit-code 1 --severity HIGH,CRITICAL --format template --template "@/contrib/html.tpl" -o reports/trivy-fs-report.html .'
}
}
}
stage('Unit Tests') {
steps {
container('dotnet8') {
// Erstellt eine XML-Datei im Format 'junit', die Jenkins lesen kann
// sh 'dotnet test --configuration Release'
sh 'dotnet test --configuration Release --logger "junit;LogFileName=results.xml"'
}
}
}
stage('Set Build Name') {
steps {
script {
// Setzt den Namen des aktuellen Laufs auf die Version + Build-Nummer
currentBuild.displayName = "v1.0.0-build-${env.BUILD_NUMBER}"
}
}
}
stage('Docker Build & Push') {
when {
branch 'master'
}
steps {
container('kaniko') {
// Nutze die ID, die du in Jenkins für den Token vergeben hast
withCredentials([usernamePassword(credentialsId: 'gitea-registry-token',
usernameVariable: 'GITEA_USER',
passwordVariable: 'GITEA_TOKEN')]) {
sh '''
# WORKAROUND: Dem Container beibringen, wer git.example.com ist
echo "130.61.26.230 git.example.com" >> /etc/hosts
# Erstellt die Docker-Konfiguration für Kaniko
# Das $(echo ...) Kommando kombiniert User und Token für den Login
echo "{\\"auths\\":{\\"130.61.26.230:30080\\":{\\"auth\\":\\"\$(echo -n \${GITEA_USER}:\${GITEA_TOKEN} | base64)\\"}}}" > /kaniko/.docker/config.json
# Der Bau- und Push-Befehl
# Wir taggen das Image mit 'latest' UND der Build-Nummer zur Sicherheit
/kaniko/executor --context `pwd` \
--dockerfile `pwd`/Dockerfile \
--insecure \
--skip-tls-verify \
--destination 130.61.26.230:30080/dev-master/secdevops-csharp-app:latest \
--destination 130.61.26.230:30080/dev-master/secdevops-csharp-app:${BUILD_NUMBER}
'''
}
}
}
}
stage('Security: Trivy Image Scan') {
when {
branch 'master'
}
steps {
container('trivy') {
// 1. Scan ausführen und als HTML-Report speichern (Achte auf den neuen Dateinamen)
sh '''
trivy image --insecure \
--severity HIGH,CRITICAL \
--format template \
--template "@/contrib/html.tpl" \
-o reports/trivy-image-report.html \
130.61.26.230:30080/dev-master/secdevops-csharp-app:latest
'''
// 2. Den Scan ein zweites Mal kurz ohne Report ausführen, damit die Pipeline bei Lücken blockiert
sh 'trivy image --insecure --exit-code 1 --severity HIGH,CRITICAL 130.61.26.230:30080/dev-master/secdevops-csharp-app:latest'
}
}
}
}
post {
failure {
script {
currentBuild.description = "Build Fehler. Ev. Sicherheits-Check fehlgeschlagen! Details im Trivy Security Report."
}
}
always {
// Sammelt die Testergebnisse ein (die wir im Test-Schritt erzeugen)
// Das **/ bedeutet: Suche in allen Unterordnern nach .xml Dateien
junit testResults: '**/TestResults/*.xml', allowEmptyResults: true
// Dieser Schritt macht den Report im Jenkins-Menü links sichtbar
publishHTML([
allowMissing: false,
alwaysLinkToLastBuild: true,
keepAll: true,
reportDir: 'reports',
reportFiles: 'trivy-fs-report.html','trivy-image-report.html',
reportName: 'Trivy Security Report'
])
// Meldet den Status zurück, wenn das Gitea-Plugin korrekt konfiguriert ist
echo "Pipeline beendet: ${currentBuild.result}"
}
}
}