CodeCharter ist deterministisch. Wenn lokal und CI unterschiedliche Findings zeigen, gibt es eine konkrete Ursache. Hier die häufigsten.
1. Unterschiedliche CodeCharter-Versionen
Häufigster Fall. Im CI läuft eine andere Version als lokal.
Check:
codecharter --version
Lokal und im CI vergleichen.
Fix: beide auf dieselbe Version bringen. Empfehlung: in CI pinnen (siehe Versionierung) und lokal dieselbe Version installieren.
2. Unterschiedliche Regel-Konfiguration
Das CI sieht eine andere rules/-Version als lokal, weil ihr in einem
Branch arbeitet, der die Änderung noch nicht hat.
Check: git status lokal ausführen und prüfen, welcher Commit im CI
ausgecheckt wurde.
Fix: sicherstellen, dass rules/ und .codecharter/config.yml committet
sind und beide Seiten denselben Commit sehen.
Beachtet außerdem, dass ein Lauf seit 1.6.4 nur die deklarierten
Regelquellen liest: die profiles: und rules: in
.codecharter/config.yml sowie jedes --rules <dir> auf der
Kommandozeile, das hinzukommt. Kein Ordner wird aufgenommen, nur weil er
existiert, und es gibt keine eingebauten Standardregeln als Rückfall. Da
die Config committet ist, lesen lokale Läufe und das CI dieselben Quellen,
solange keine Seite ein zusätzliches --rules übergibt (der rules-Input
von GitHub Actions ist so ein Flag).
Vergleicht die Rules:-Zeile auf beiden Seiten: Sie listet jede Quelle mit
ihrer Regelanzahl. Eine ältere CLI im CI ignoriert rules: ohne Meldung,
pinnt das CI also auf 1.6.4 oder neuer, sobald ihr den Schlüssel nutzt.
3. Solution-State
CodeCharter nutzt MSBuild, um die Solution zu laden. Analysiert werden die Dateien auf der Festplatte: wenn das CI auf einem sauberen Checkout mit allen NuGet-Packages restored arbeitet, lokal aber nicht committete Änderungen vorliegen oder Packages nicht restored sind, weicht das Modell ab.
Check:
dotnet restore
dotnet build
Fix: lokal ein sauberes dotnet restore && dotnet build vor dem
codecharter analyze laufen lassen.
4. Unterschiedliche --fail-on-Schwellen
Ohne --fail-on beendet sich codecharter analyze mit Exit-Code 1, sobald
es irgendein Finding gibt, unabhängig von der Severity. Mit
--fail-on error lassen nur Findings der Stufe error den Lauf
fehlschlagen. Der Default ohne Flag ist also die strengere Schwelle: läuft
das CI mit --fail-on error und ihr lokal ohne Flags, macht schon eine
Warnung euren lokalen Lauf rot, während das CI grün bleibt.
Check: in eurer CI-Konfiguration nachsehen, welche Flags gesetzt sind.
Fix: lokal mit denselben Flags laufen lassen:
codecharter analyze MySolution.sln --fail-on error
5. Unterschiedliche --severity-Schwellen
--severity steuert die minimale Severity, die im Report erscheint
(Default: info). Läuft eine Seite mit einer höheren Schwelle, etwa
--severity warn, verschwinden info-Findings aus ihrer Ausgabe und die
beiden Findings-Listen sehen unterschiedlich aus.
Fix: auf beiden Seiten denselben --severity-Wert verwenden.
6. Diff-Scoping
Mit --diff oder --git-ref meldet CodeCharter nur Findings auf geänderten
Zeilen, und auch das --fail-on-Gate gilt nur für diese Findings. Der
Action-Input diff: true der GitHub Action aktiviert dasselbe Verhalten
auf Pull Requests. Das CI kann dann völlig korrekt weniger Findings zeigen
als ein voller lokaler Lauf.
Check: ob das CI --diff, --git-ref oder den Action-Input
diff: true verwendet.
Fix: den CI-Scope lokal nachstellen, zum Beispiel:
codecharter analyze MySolution.sln --git-ref main..HEAD
7. Baselines
Übergibt das CI eine --baseline-Datei, werden alle darin erfassten
Findings unterdrückt; Ausgabe und --fail-on gelten nur noch für neue
Findings. Ein lokaler Lauf ohne die Baseline zeigt alles.
Fix: lokal mit derselben Baseline-Datei laufen lassen oder
--baseline auf beiden Seiten weglassen, um die vollen Ergebnisse zu
vergleichen.
8. Plattform-Unterschiede
CodeCharter ist plattform-deterministisch. Gleiche Findings auf Windows und Linux. Wenn ihr trotzdem Unterschiede seht, ist das ein Bug. Schreibt uns mit einer minimalen Repro.
Debug-Workflow
Prüft zuerst den Exit-Code, nicht nur die Findings-Liste. Exit-Code
1 bedeutet, dass Findings die Schwelle gerissen haben. Andere Codes
ungleich null bedeuten, dass der Lauf selbst nicht normal durchgelaufen
ist: 2 (fehlende codecharter.lock.json bei konfigurierten
Portal-Profilen), 3 (Solution konnte nicht geladen werden oder das
Portal war beim Restore nicht erreichbar), 4 (Lockfile-Drift), 6
(Lizenzfehler). Ein rotes CI ohne Findings deutet meist auf einen dieser
Codes hin.
Wenn nichts hilft, lasst beide Seiten mit --verbose laufen und
difft die Logs:
codecharter analyze MySolution.sln --verbose 2> debug-local.log
# CI: dasselbe, Log als Artifact ablegen
diff debug-local.log debug-ci.log | less
Im --verbose-Modus gibt CodeCharter auf stderr aus:
- Welcher Pfad analysiert wird
- Welches Regel-Verzeichnis verwendet wird und wie viele Regeln daraus geladen wurden
- Wie viele Typen und Methoden die Analyse gefunden hat
Das Verbose-Log umfasst nur wenige Zeilen. Der Diff zeigt daher sofort, ob beide Seiten dasselbe Regel-Verzeichnis nutzen, gleich viele Regeln laden und dieselbe Modellgröße sehen.
Wenn ihr es nicht findet
Schreibt uns an support@codecharter.tools
mit eurer CLI-Version, den --verbose-Logs beider Seiten und dem Diff der
Findings-Listen.