Zum Hauptinhalt springen

Projektkonfiguration

Mit einer .codeguard.yml passt du CodeGuard an dein Projekt an: Pfade, Plattformen, Regeln, Metriken, eigene Regeln und Ausnahmen. Diese Seite beschreibt jeden Schlüssel.

Wo die Datei liegt und wie sie gefunden wird​

AufrufGeladen wirdim Bericht (project_source.mode)
ohne Parameter, Datei vorhanden<Projektwurzel>/.codeguard.yml bzw. .codeguard.yamlauto
ohne Parameter, keine DateiStandardwerteFeld fehlt
--config Xnur Xexplicit
--no-project-configStandardwerte, Warnung codeguard-project-config-ignored, falls eine Datei existiertdisabled
--config und --no-project-confignichtsExit 2
  • Die Projektwurzel ist --project-root oder das aktuelle Verzeichnis. CodeGuard sucht nicht in übergeordneten Verzeichnissen und nicht im Git-Wurzelverzeichnis.
  • Nur genau diese Dateinamen zählen, auch auf Volumes ohne Unterscheidung der Groß-/Kleinschreibung. .CodeGuard.yml wird nicht geladen.
  • Liegen .codeguard.yml und .codeguard.yaml im Wurzelverzeichnis, ist das Exit 2 (mehrdeutig).
  • Eine kaputte Datei ist Exit 2. CodeGuard fällt nie still auf Standardwerte zurück.
  • .codeguard.yml und .codeguard.yaml sind standardmäßig geschützte Dateien. Ein Diff, der sie ändert, endet mit Exit 6.

Die kleinste gültige Datei:

version: 1

Das vollständige Schema liefert codeguard schema --kind configuration. Prüfen kannst du die Datei jederzeit mit:

codeguard config validate

Ebenen und Vorrang​

Wirksam ist immer das Ergebnis aus drei Quellen, in dieser Reihenfolge:

  1. Eingebaute Standardwerte
  2. Organisationsrichtlinie (/Library/Application Support/CodeGuard/policy.yml): Metrik-Baseline, Pflichtregeln, Mindestschweren, gesperrte Werte, vertrauenswürdige Werkzeugverzeichnisse. Siehe Organisationsrichtlinie.
  3. Projektkonfiguration (.codeguard.yml)

Danach setzt die Richtlinie ihre gesperrten Werte (locked_values) durch. Ein Projektwert, der einem gesperrten Wert widerspricht, ist Exit 2.

Benutzer- oder CI-Konfigurationsdateien lädt codeguard 0.3.5 nicht. Auch --ci lädt keine zusätzliche Datei.

Listen werden ersetzt, nicht ergänzt

Setzt die Projektkonfiguration eine Liste (z. B. paths.exclude oder protected_files), ersetzt sie die Standardliste. Willst du die Standardeinträge behalten, schreibe sie mit hinein.

Was die Projektebene darf​

Die Projektebene darf verschärfen, aber keine Sicherheitszusage lockern. Diese Grenzen wurden mit codeguard 0.3.5 geprüft:

Projekt setzt …Ergebnis
project.*, paths.*, protected_files, rules.*, custom_rules, waivers, diff.*erlaubt
checks.*.scopes, checks.platform.*, checks.tests.simulator, checks.tests.ipaderlaubt
checks.<format/swiftlint/compile/tests/security>.enabled: false oder .required: falseExit 2: required checks cannot be disabled by a lower-precedence source
checks.compile.enabled: falseExit 2: tests require compile
execution.analysis_limits.*erlaubt
execution.timeouts.*Exit 2, außer der Wert wiederholt den Standard
execution.max_workers und übrige execution.*Exit 2, außer der Wert wiederholt den Standard
security.* (auch security.network.allowed_destinations)Exit 2, außer der Wert wiederholt den Standard
tools.*Exit 2 (configuration source is not allowed to set this field), außer die Richtlinie erlaubt es mit allow_project_tool_paths: true
logging.level ungleich infoExit 2: project configuration may only repeat the safe logging default
logging.audit.enabled: false, logging.audit.include_tool_raw_output: trueExit 2
Wert, den die Organisation gesperrt hat, anders als gesperrtExit 2

Was die Projektebene nicht darf, kann die Organisationsrichtlinie über enforcement.locked_values festlegen.

version​

SchlüsselTypStandardPflicht
versionGanzzahl, nur 11ja

Schlüssel, die mit x- beginnen, sind auf jeder Ebene als Erweiterung erlaubt und werden ignoriert. Jeder andere unbekannte Schlüssel ist Exit 2.

project​

Beschreibt, wie CodeGuard das Projekt baut und testet.

SchlüsselWerteStandardWirkung
project.kindauto, swift-package, xcodeautoWahl des Build-Werkzeugs (siehe unten)
project.package_pathPfad oder nullnullBenennt das Manifest. Nur das Package.swift im Wurzelverzeichnis wird akzeptiert; ein Paket in einem Unterordner ist Exit 2.
project.xcode.workspacePfad zu .xcworkspace oder nullnullContainer für Xcode-Builds
project.xcode.projectPfad zu .xcodeproj oder nullnullContainer für Xcode-Builds
project.xcode.schemeName oder nullnullScheme. Ohne Angabe nutzt CodeGuard das geteilte Scheme des Projekts; ohne geteiltes Scheme Exit 2.
project.xcode.configurationNameDebugBuild-Konfiguration für xcodebuild
project.xcode.destinationplatform=macOS oder platform=macOS,arch=<Host-Architektur>nullVeraltet. Nur noch eine Absicherung für macOS, jeder andere Wert ist Exit 2. Nutze project.platforms.
project.platformsListe aus macos, ios, watchos, tvos, visionosnicht gesetzt (automatisch)Plattformen für compile/tests
project.test_destinationsObjekt (siehe unten)nicht gesetztSimulator-Gerät und -Runtime je Ziel überschreiben

project.kind:

  • auto: Gibt es ein Package.swift im Wurzelverzeichnis, baut SwiftPM, auch wenn zusätzlich ein Xcode-Projekt existiert. Sonst wird ein .xcodeproj/.xcworkspace mit xcodebuild gebaut (Workspace vor Projekt). Gibt es beides nicht, laufen compile und tests nicht.
  • swift-package: immer SwiftPM, nie Xcode.
  • xcode: immer Xcode.

project.platforms:

  • Nicht gesetzt: CodeGuard baut jede Plattform, die es erkennt und deren SDK lokal installiert ist.
  • Gesetzt: Schnittmenge aus Liste und erkannten Plattformen.
    • Bei Xcode-Projekten ist eine Plattform, die das Scheme nicht unterstützt, Exit 2.
    • Ein Swift Package darf jede Plattform nennen, auch eine, die sein Manifest nicht unter platforms: aufführt. So baut [macos, ios] ein iOS-Paket zusätzlich auf macOS.
    • Fehlt das SDK einer genannten Plattform lokal, endet der Lauf vor dem ersten Build mit Exit 3.
  • Die Liste darf nicht leer sein und keine Duplikate enthalten.

project.test_destinations: erlaubte Schlüssel ios, ipad, watchos, tvos, visionos. Jeder Eintrag hat:

FeldWerteBedeutung
device_typeName oder Identifier des Gerätetyps, nicht leerersetzt den automatisch gewählten Gerätetyp
runtimeX.Y oder latestX.Y wählt genau diese Version (18.0 passt nicht auf 18.2)

ios gilt nur für das iPhone-Ziel, ipad nur für das iPad-Ziel. Ist ein hier genanntes Ziel nicht erfüllbar (Runtime fehlt, Runtime unter dem Deployment-Target), endet der Lauf mit Exit 3, bevor ein Gerät entsteht. Ein leeres Objekt, ein unbekannter Schlüssel oder ein ungültiges Versionsformat ist Exit 2.

project:
platforms: [ios]
test_destinations:
ios: { device_type: "iPhone 18 Pro", runtime: "27.0" }
ipad: { runtime: latest }

paths​

SchlüsselStandardWirkung
paths.include["Sources/**", "Tests/**", "Package.swift"]Nur diese Dateien dürfen geprüft werden. Andere ergeben in check-file/check-diff path-outside-allowed-scope (Exit 6).
paths.exclude[".build/**", "DerivedData/**", "Vendor/**", ".git/**"]Diese Dateien sind ausgeschlossen, auch für die Inhaltsregeln und das Lesen der Plattform-Checks
paths.generated[".codeguard-artifacts/**"]Wird validiert, hat in 0.3.5 aber keine Wirkung auf den Lauf

Globs sind projektrelativ: ** (beliebig viele Ebenen), *, ?, [...]. Nicht erlaubt sind ein führendes /, .. und die Zeichen ! ~ ; | & < > ( ) { } $ sowie Backtick und Backslash.

Xcode-Projekte mit anderen Ordnernamen

Der Standard deckt nur Sources/, Tests/ und Package.swift ab. Liegen deine Quellen etwa in MyApp/ und MyAppTests/, musst du paths.include anpassen, sonst prüfen format, swiftlint und die Inhaltsregeln diese Dateien nicht. Die Plattform-Checks lesen Projektdatei, Info.plist und Entitlements auch außerhalb von paths.include.

Ein CocoaPods-Projekt nimmst du mit Pods/** in paths.exclude aus. Deckt ein Exclude die project.pbxproj eines Projekts ab, überspringen die Plattform-Checks dieses Projekt still.

protected_files​

Liste von Globs. Ändert ein Diff eine passende Datei, endet der Lauf mit protected-file-change und Exit 6. Die Standardliste steht unter Prüfungen und Regeln. Die Organisationsrichtlinie kann mit mandatory_protected_files Einträge erzwingen, die das Projekt nicht entfernen kann.

protected_files:
- .codeguard.yml
- .codeguard.yaml
- Package.swift
- Package.resolved
- "**/*.entitlements"
- "**/*.xcodeproj/project.pbxproj"
- .github/workflows/**
- .gitlab-ci.yml
- "**/*.xcconfig"
- Config/Secrets.plist # eigener Eintrag

checks​

Jede Prüfung hat drei Felder:

FeldBedeutung
enabledPrüfung eingeschaltet
requiredverpflichtend: Werkzeug fehlt oder Prüfung unvollständig ergibt Exit 3 statt einer Warnung
scopesIn welchen Kommandos die Prüfung läuft: file (check-file), diff (check-diff), project (check-project), operation
Prüfungenabledrequiredscopes (Standard)
checks.securitytruetrue[file, diff, project, operation]
checks.platformtruefalse[file, diff, project]
checks.formattruetrue[file, diff, project]
checks.swiftlinttruetrue[file, diff, project]
checks.compiletruetrue[diff, project]
checks.teststruetrue[diff, project]

Zusätzlich für checks.tests:

FeldStandardWirkung
simulatortruefalse überspringt alle Simulator-Testziele (simulatorDisabled)
ipadtruefalse verhindert den zusätzlichen iPad-Lauf

Was das Projekt mit checks tun kann:

  • scopes einschränken ist erlaubt, auch auf []. So nimmst du eine Prüfung aus jedem Lauf heraus, ohne sie abzuschalten. compile und tests laufen in file ohnehin nie.
  • checks.platform darf das Projekt ganz abschalten (enabled: false) oder verpflichtend machen (required: true).
  • enabled: false oder required: false für format, swiftlint, compile, tests und security ist Exit 2. Das darf nur die Organisationsrichtlinie über locked_values.

Beispiel: nur statische Prüfungen, kein Build und keine Tests:

version: 1
checks:
compile: { scopes: [] }
tests: { scopes: [] }

rules​

Jede eingebaute Regel unter rules.<id> kennt diese Felder:

FeldWerteBedeutung
enabledtrue/falseRegel an oder aus
severityinfo, warning, error, criticalSchwere. error und critical blockieren.
scopesfile, diff, project, operationin welchen Kommandos die Regel läuft
path_overridesListe von { paths, enabled?, severity? }abweichende Einstellung für bestimmte Pfade

Regel-IDs, für die das gilt:

  • Inhaltsregeln: forbidden-fatal-error, forbidden-force-try, forbidden-force-cast, sensitive-data-in-log, hardcoded-secret, unauthorized-network-destination
  • Plattformregeln: privacy-manifest-invalid, privacy-manifest-missing, privacy-required-reason-undeclared, privacy-reason-code-invalid, privacy-tracking-domains-missing, purpose-string-missing, purpose-string-empty, ats-arbitrary-loads, ats-insecure-exception-domain, entitlements-file-missing, entitlement-weakens-hardened-runtime, entitlement-get-task-allow-release, macos-app-sandbox-missing

Die Standardwerte stehen unter Prüfungen und Regeln. Die Schlüssel rules.public-api-change und rules.dependency-policy sind im Schema vorhanden, haben in 0.3.5 aber keine Wirkung.

Zusätzliche Felder:

SchlüsselStandardBedeutung
rules.sensitive-data-in-log.logger_symbols.functions[print, debugPrint, dump, NSLog, os_log]freie Logger-Funktionen
rules.sensitive-data-in-log.logger_symbols.methods[debug, info, notice, log, trace, warning, error, fault, critical]Logger-Methoden (Empfänger muss log enthalten)
rules.sensitive-data-in-log.sensitive_identifiers[token, accessToken, refreshToken, password, passwd, secret, apiKey, authorization, cookie, sessionID, privateKey]sensible Bezeichner (auch für die Zuweisungsheuristik von hardcoded-secret)
rules.hardcoded-secret.allowlist_sha256[]Freigabe bestimmter Werte als sha256:<64 Hex> (nur Formatstufe und URL-Userinfo; bei URLs der Hash des Passworts)

Mindestens severity, die die Organisation per severity_floors vorgibt, darf das Projekt nicht unterschreiten (Exit 2). Pflichtregeln (mandatory_rules) darf es nicht abschalten.

Beispiel:

rules:
forbidden-fatal-error:
severity: critical
path_overrides:
- paths: ["Tests/**", "Sources/Previews/**"]
enabled: false
sensitive-data-in-log:
sensitive_identifiers: [token, password, iban]
hardcoded-secret:
path_overrides:
- paths: ["Tests/Fixtures/**"]
enabled: false
ats-arbitrary-loads:
severity: error
hinweis

Ein path_overrides-Eintrag ersetzt bei forbidden-* die Standard-Overrides für Testpfade, weil Listen ersetzt werden. Nimm Tests/**, **/*Tests/** und **/*UITests/** wieder auf, wenn die Regel dort aus bleiben soll.

rules.metrics​

Konfiguriert die verwalteten SwiftLint-Metrikregeln. Ohne rules.metrics gibt es keinen Metrik-Lauf. Schlüssel sind hier snake_case.

SchlüsselParameter
severityerror (Standard) oder critical: Schwere eines Funds über der error-Schwelle
line_lengthwarning, error, ignores_urls, ignores_function_declarations, ignores_comments, ignores_interpolated_strings
file_lengthwarning, error, ignore_comment_only_lines
type_body_lengthwarning, error
function_body_lengthwarning, error
closure_body_lengthwarning, error
cyclomatic_complexitywarning, error, ignores_case_statements
nestingtype_level.warning, type_level.error, function_level.warning, function_level.error
function_parameter_countwarning, error, ignores_default_parameters
large_tuplewarning, error
enum_case_associated_values_countwarning, error

Regeln für die Werte:

  • Schwellen sind Ganzzahlen ≥ 1, und warning ≤ error.

  • Jede Regel im Projekt braucht mindestens einen Schwellenwert. Nur ein Schalter ist Exit 2:

    configuration validation failed: project:/rules/metrics/line_length: metric rule requires at least one warning or error threshold
  • Nur konfigurierte Schwellen gelten. Ist nur error gesetzt, gilt warning = error. Eine nicht gesetzte nesting-Ebene ist abgeschaltet.

  • Gibt die Organisation eine Baseline vor (enforcement.metrics), darf das Projekt Schwellen nur senken, ignores_* nur von true auf false setzen und severity nur anheben.

rules:
metrics:
severity: error
line_length: { warning: 120, error: 160, ignores_urls: true }
function_body_length: { warning: 40, error: 80 }
cyclomatic_complexity: { warning: 10, error: 20 }
nesting: { type_level: { warning: 2 }, function_level: { warning: 3 } }

config validate zeigt danach jede wirksame Schwelle mit Herkunft:

metrics: rules.metrics.severity = error (built-in, locked: false)
metrics: rules.metrics.line_length.warning = 120 (project, locked: false)
metrics: rules.metrics.line_length.error = 160 (project, locked: false)
metrics: rules.metrics.line_length.ignores_urls = true (project, locked: false)

custom_rules​

Eigene Regeln. In 0.3.5 müssen alle Felder außer pattern und suggestion angegeben werden, sonst meldet config validate configuration value has the wrong type.

FeldWertePflicht
id^[a-z][a-z0-9-]{2,63}$, nicht codeguard-…, keine eingebaute IDja
engineregex oder file (dependency, architecture sind nicht umgesetzt)ja
severityinfo, warning, error, criticalja
scopesListe aus file, diff, project, operationja
autofixnur falseja
paths{ include: [...], exclude: [...] }, beide Listen angebenja
patternregulärer Ausdruck, höchstens 4096 Zeichen; bei engine: file verbotenbei regex
messagehöchstens 500 Zeichenja
suggestionhöchstens 1000 Zeichennein
custom_rules:
- id: no-debug-print
engine: regex
severity: warning
scopes: [file, diff, project]
autofix: false
paths: { include: ["Sources/**"], exclude: [] }
pattern: "debugPrint\\("
message: "debugPrint gehört nicht in Produktionscode."
suggestion: "Logger verwenden."
- id: no-env-files
engine: file
severity: error
scopes: [diff, project]
autofix: false
paths: { include: ["**/*.env"], exclude: [] }
message: ".env-Dateien nicht einchecken."

Eigene Regeln sind nie waivebar. Der Treffertext erscheint nicht im Bericht.

waivers​

Ein Waiver nimmt einen bestimmten Fund als akzeptiertes Risiko an. Der Fund bleibt im Bericht, blockiert aber nicht mehr (disposition: accepted_risk, gezählt unter summary.accepted_risk).

FeldBedeutung
ideindeutige ID
ruleRegel-ID des Funds (nur eingebaute Regeln und codeguard-metric-*)
fingerprintsha256:<64 Hex> aus dem Feld fingerprint des Funds im JSON-Bericht
pathsGlobs, auf die der Waiver beschränkt ist (nicht leer)
reasonBegründung (nicht leer)
ownerverantwortliche Person oder Gruppe (nicht leer)
created_at, expires_atZeitstempel, z. B. 2026-10-01T00:00:00Z; expires_at muss nach created_at liegen und der Waiver muss gerade gültig sein

Höchstdauer: 90 Tage, bei critical 7 Tage. Die Organisation kann das mit limits.max_waiver_days weiter senken. Nicht waivebar sind protected-file-change, path-outside-allowed-scope, alle Laufdiagnosen (codeguard-… außer codeguard-metric-…), eigene Regeln, swift-format, swiftlint.* und Regeln, die die Organisation in non_waivable_rules führt.

So kommst du zum Fingerprint:

codeguard --format json check-project | jq '.violations[] | {rule, file, fingerprint}'
waivers:
- id: W-001
rule: macos-app-sandbox-missing
fingerprint: "sha256:3f766684cfc82777b3ca10fb481c1154bed31576d0f9a3e45301457d7a741496"
paths: ["App.entitlements"]
reason: "Debug-Build außerhalb des App Store, Ticket APP-123"
owner: "team-mac"
created_at: "2026-10-01T00:00:00Z"
expires_at: "2026-12-01T00:00:00Z"

Ein critical-Waiver über mehr als 7 Tage scheitert:

configuration validation failed: project:/waivers/0/expires_at: waiver duration exceeds the severity maximum
Wann ein Waiver weiter passt

Der Fingerprint enthält keine Zeilennummer. Ein Waiver passt deshalb weiter, wenn Code darüber verschoben wird. Er passt nicht mehr, wenn sich die betroffene Zeile selbst ändert. Bei Plattformregeln hängt er an Target, Datei, Schlüssel und Konfiguration.

execution​

Die Projektebene darf hier nur analysis_limits setzen. Alle übrigen Werte kann nur die Organisation per locked_values ändern.

execution.analysis_limits (Projekt darf setzen):

SchlüsselStandardMaximumGilt für
max_plist_bytes1 MiB64 MiBPlist, .entitlements, .xcprivacy
max_pbxproj_bytes16 MiB256 MiBproject.pbxproj
max_source_bytes2 MiB64 MiBSwift/ObjC/C-Quellen, .xcconfig, contents.xcworkspacedata
max_text_bytes2 MiB64 MiBübrige Textdateien
max_files20 0001 000 000Dateimenge eines Laufs (wird sie überschritten, wertet die Inhaltsprüfung keine Datei aus)
max_include_depth1664Tiefe von #include in .xcconfig-Ketten

Minimum ist jeweils 1. Werte in Bytes angeben, z. B. max_text_bytes: 4194304.

execution.timeouts (nur Organisation): Dauer als Zahl plus s, m, h oder d.

SchlüsselStandardGilt für
preflight10sAbfragen vor dem Build (dump-package, -showsdks, simctl list, -showBuildSettings) als gemeinsames Budget
format_file30sswift-format je Datei
format_batch2mswift-format je Lauf
swiftlint5mSwiftLint-Läufe
static_analysis2mInhaltsregeln und Plattform-Checks
compile20mjeder Build der Matrix, auch -showdestinations und -list
tests30mjeder Testlauf
simulator_boot3mAnlegen und Booten eines Simulators
simulator_cleanup1mHerunterfahren und Löschen eines Simulators
termination_grace5sWartezeit nach dem Beenden eines Werkzeugs
project_total60mkein Gesamtlimit des Laufs; geht nur in die Erkennung verwaister Simulatoren ein
guard_operation, report, check_file_total5s, 30s, 5min 0.3.5 ohne Wirkung

Weitere Werte (nur Organisation):

SchlüsselStandardWirkung
max_workers4 (1–4)parallele Auswertung der Inhaltsregeln
output_limit_mib_per_stream10 (1–10)Obergrenze je Ausgabestrom eines Werkzeugs
concurrency, reserve_logical_cpus, cache.enabled, cache.locationauto, 2, true, user-cachein 0.3.5 ohne Wirkung

security​

Nur die Organisation kann hier etwas ändern.

SchlüsselStandardWirkung
security.network.allowed_destinations[]Allowlist für unauthorized-network-destination. Format scheme://host[:port] oder scheme://*.host[:port]. Das alte Format host[:port] ist Exit 2. Leer: Regel inaktiv.
security.fail_closed, security.offline, security.redact.enabledtrueimmer true, nicht änderbar
security.build_scripts, security.shell.*, security.network.default_decision, security.approvals.*, security.redact.replacementsiehe Schemain 0.3.5 ohne Wirkung

tools​

Pfade und Versionsbedingungen der Werkzeuge. Standardmäßig nur über die Organisation setzbar.

SchlüsselStandardWirkung
tools.swift_format.executable / .version_constraintnullexpliziter Pfad bzw. Versionsbedingung (z. B. >=6.3.0,<6.4.0)
tools.swiftlint.executable / .version_constraintnulldto.
tools.swift.executable / .version_constraintnulldto.
tools.xcodebuild.executable / .version_constraint/usr/bin/xcodebuild / Standardbereich >=26.0.0,<28.0.0dto.
tools.resolutiontrusted-pathseinziger Wert

Ein expliziter Pfad muss unter einem vertrauenswürdigen Verzeichnis der Richtlinie liegen. Eine gesetzte version_constraint für swift-format schließt die unversionierte Xcode-27-Fassung (main) aus.

diff​

SchlüsselStandardWirkung
diff.detect_renamestrueUmbenennungen und Kopien erkennen (git diff -M -C --find-copies-harder)
diff.include_untrackedtruein 0.3.5 ohne Wirkung. Unversionierte Dateien steuert nur check-diff --include-untracked.
diff.static_findings.fail_on, diff.baseline[introduced, touched], nullin 0.3.5 ohne Wirkung

Schlüssel ohne Wirkung in 0.3.5​

Diese Bereiche sind im Schema vorhanden und werden validiert, beeinflussen den Lauf aber nicht (sie gehen nur in den configuration_hash ein):

  • autofix.* (es gibt keinen Autofix; autofix.max_iterations erscheint nur als run.max_iterations im Bericht)
  • reports.* (Format und Ziel kommen aus --format und --output)
  • logging.level, logging.audit.retention_days, logging.audit.include_tool_raw_output; das Audit-Log ist immer an
  • ci.*
Jede Änderung invalidiert Trust-Tickets

Der configuration_hash ist Teil jedes Trust-Tickets. Jede Änderung an der wirksamen Konfiguration, auch an einem Schlüssel ohne Wirkung, macht bestehende Tickets ungültig. Danach ist codeguard trust grant erneut nötig.

Vollständiges Beispiel​

version: 1

project:
kind: auto
platforms: [macos, ios]

paths:
include: ["Sources/**", "Tests/**", "Package.swift"]
exclude: [".build/**", "DerivedData/**", "Vendor/**", ".git/**", "Tests/Fixtures/**"]

checks:
platform: { enabled: true, required: true, scopes: [file, diff, project] }
tests: { simulator: true, ipad: true }

rules:
forbidden-fatal-error:
severity: error
sensitive-data-in-log:
sensitive_identifiers: [token, accessToken, refreshToken, password, secret, apiKey, iban]
metrics:
line_length: { warning: 120, error: 160, ignores_urls: true }
function_body_length: { warning: 40, error: 80 }

custom_rules:
- id: no-debug-print
engine: regex
severity: warning
scopes: [file, diff, project]
autofix: false
paths: { include: ["Sources/**"], exclude: [] }
pattern: "debugPrint\\("
message: "debugPrint gehört nicht in Produktionscode."

execution:
analysis_limits:
max_text_bytes: 4194304

Siehe auch​