Zum Inhalt springen

Lokal andere Findings als in CI

Wenn das CI rot ist und ihr lokal nichts seht oder umgekehrt.

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.