GitLab hat keine offizielle CodeCharter-Integration als Component, aber mit ein paar Zeilen YAML läuft die CLI sauber im Pipeline.
Liegt Ihr Repository auf GitHub und läuft nur der Build auf GitLab, können Sie aus dieser Pipeline zusätzlich einen gebrandeten CodeCharter-Check-Run und PR-Kommentar veröffentlichen, siehe Checks aus beliebigem CI veröffentlichen.
Minimal-Setup
.gitlab-ci.yml:
codecharter:
image: mcr.microsoft.com/dotnet/sdk:9.0
stage: test
before_script:
- curl -sSL -H "Authorization: Bearer $CODECHARTER_API_KEY" -o codecharter.tar.gz https://codecharter.tools/api/v1/cli/linux-x64/latest
- mkdir -p /opt/codecharter && tar -xzf codecharter.tar.gz -C /opt/codecharter
- chmod +x /opt/codecharter/codecharter
- export PATH="/opt/codecharter:$PATH"
script:
- codecharter analyze MySolution.sln --fail-on error --output sarif --output-file codecharter.sarif
artifacts:
when: always
paths:
- codecharter.sarif
Ersetzen Sie MySolution.sln durch den Pfad zu Ihrer Solution- oder
Projektdatei. analyze erwartet eine .sln-, .slnx- oder .csproj-Datei,
kein Verzeichnis.
API-Key beschaffen
- Im Portal unter API Keys einen Key erzeugen.
- In GitLab unter
Settings → CI/CD → VariablesalsCODECHARTER_API_KEYhinterlegen, "Protected" und "Masked" anhaken.
Die Variable erfüllt zwei Aufgaben: before_script lädt damit die CLI
herunter, und der analyze-Schritt erzeugt damit automatisch eine kurzlebige
Lizenz, wenn keine im Cache liegt. Sie muss deshalb dem gesamten Job zur
Verfügung stehen, was bei einer GitLab-CI/CD-Variable standardmäßig der Fall
ist.
SARIF und GitLab SAST
GitLabs artifacts.reports.sast verarbeitet kein SARIF, sondern erwartet
GitLabs eigenes Security-Report-JSON-Schema, das CodeCharter nicht erzeugt.
Würde reports.sast auf die SARIF-Datei zeigen, erschiene in der
GitLab-Oberfläche nichts.
Die SARIF-Datei (SARIF 2.1.0) ist trotzdem als normales Artifact nützlich: aus dem Pipeline herunterladen, in SARIF-fähige Tools einspeisen oder für Audits archivieren. Um Findings auf Merge Requests sichtbar zu machen, nutzen Sie den Code-Quality-Konverter unter Merge-Request-Reports.
Caching
CodeCharter hat keinen Cache für Analyseergebnisse, durch Caching von
Analyse-Output lässt sich also nichts beschleunigen. Cachen lohnt sich nur
für den Rule-Bundle-Cache: Wenn Ihr Projekt Portal-Regelprofile nutzt (eine
.codecharter/codecharter.lock.json im Verzeichnis .codecharter/), legt die CLI
heruntergeladene Bundles in .codecharter/cache ab. Dieses Verzeichnis zu
persistieren spart bei warmen Runs den erneuten Bundle-Download:
codecharter:
# ... wie oben ...
cache:
key: codecharter-$CI_COMMIT_REF_SLUG
paths:
- .codecharter/cache/
Liegt Ihre Solution-Datei nicht im Repo-Root, passen Sie den Pfad entsprechend an. Ohne Portal-Profile gibt es nichts zu cachen und Sie können diesen Abschnitt überspringen.
Versions-Pinning
Statt /latest/ eine konkrete CLI-Version pullen:
- curl -sSL -H "Authorization: Bearer $CODECHARTER_API_KEY"
-o codecharter.tar.gz
https://codecharter.tools/api/v1/cli/linux-x64/1.0.12
Empfehlung: für CI immer pinnen, siehe Versionierung.
Jede Download-Antwort enthält einen X-CodeCharter-Sha256-Header. Vergleichen
Sie ihn mit der Prüfsumme des heruntergeladenen Archivs, wenn Sie die
Integrität des Downloads im Job verifizieren wollen.
Self-Hosted GitLab Runner
Ein Self-Hosted Runner braucht bei jedem Pipeline-Run Zugriff auf
codecharter.tools, denn das before_script oben lädt die CLI
jedes Mal herunter. Weitere Anpassungen sind nicht nötig: das Minimal-Setup
nutzt mcr.microsoft.com/dotnet/sdk aus Microsofts öffentlichem Registry.
Spiegelt Ihre Organisation Docker-Images intern, beziehen Sie das
.NET-SDK-Image stattdessen aus Ihrem eigenen Mirror.
In abgeschotteten Netzen: das CLI-Binary auf den Runner spiegeln und mit lokalem Pfad statt Curl-Download arbeiten.
Merge-Request-Reports
GitLabs "Code Quality"-Sektion auf MRs erwartet eine JSON-Datei im GitLab-Code-Quality-Schema (nicht SARIF). CodeCharter erzeugt dieses Format nicht von Haus aus, den Konverter müssen Sie selbst schreiben.
Eine minimale jq-Abbildung von CodeCharter-JSON-Output auf das GitLab-Schema sieht
so aus:
codecharter analyze MySolution.sln --fail-on error --output json --output-file codecharter.json
jq '[.violations[] | {
description: .message,
check_name: .ruleId,
severity: (if .severity == "error" then "major" elif .severity == "warning" then "minor" else "info" end),
fingerprint: .fingerprint,
location: { path: .filePath, lines: { begin: .lineNumber } }
}]' codecharter.json > codequality.json
Danach das Ergebnis als GitLab-Artifact verdrahten:
artifacts:
reports:
codequality: codequality.json
Der JSON-Output enthält bereits einen stabilen fingerprint pro Violation,
der nicht von Zeilennummern abhängt. GitLab zeigt deshalb keine doppelten
Annotations, wenn sich unbeteiligte Zeilen verschieben.
Merge-Request-Pipelines: nur geänderte Zeilen
In MR-Pipelines können Sie mit --git-ref sowohl die gemeldeten Findings als
auch das --fail-on-Gate auf die im MR geänderten Zeilen beschränken:
codecharter-mr:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
variables:
GIT_DEPTH: 0
script:
- codecharter analyze MySolution.sln --fail-on error --git-ref $CI_MERGE_REQUEST_DIFF_BASE_SHA..HEAD
--git-ref führt intern git diff <range> --unified=0 aus, der Basis-Commit
muss also im Clone vorhanden sein (daher GIT_DEPTH: 0).
Für Legacy-Codebasen gibt es außerdem Baseline-Unterstützung:
--write-baseline hält die aktuellen Findings einmalig fest, --baseline
lässt Output und --fail-on danach nur noch auf neue Findings wirken.
Exit-Codes
Für das Pipeline-Debugging nutzt codecharter analyze diese Exit-Codes:
| Code | Bedeutung |
|---|---|
| 0 | Keine gate-relevanten Findings |
| 1 | Findings auf oder über dem --fail-on-Level; ohne --fail-on jedes Finding |
| 2 | Bedienfehler (ungültige Optionen, defekte Baseline, ...) |
| 3 | Solution oder Projekt konnte nicht geladen werden |
| 6 | Lizenzfehler |
Schlägt der Job plötzlich beim Download oder beim Analyze-Schritt mit HTTP
402 fehl, ist die Subscription abgelaufen. Sowohl der CLI-Download als auch
das Erzeugen der Lizenz liefern in diesem Fall 402.
Pipeline-Variablen
Praktische Variablen, die im Job zur Verfügung stehen:
| Variable | Verwendung |
|---|---|
$CI_PROJECT_DIR |
Repo-Root |
$CI_COMMIT_REF_SLUG |
Branch-Name für Caching |
$CI_MERGE_REQUEST_IID |
MR-Nummer wenn vorhanden |
$CI_MERGE_REQUEST_DIFF_BASE_SHA |
MR-Basis-Commit für --git-ref |
$CODECHARTER_API_KEY |
Ihr Secret |