Skip to main content

Configuration examples

For each project type, this page gives you a suitable .codeguard.yml, explains how CodeGuard builds and tests the project, and shows what a real run looked like. Every configuration on this page was checked with codeguard 0.3.5 config validate.

Configure little

Many projects only need version: 1. CodeGuard detects the project type and platforms on its own. Mainly configure paths if your folders are not named Sources/ and Tests/, and rules.metrics if you want metrics.

How CodeGuard selects platforms​

  1. Detect: Xcode projects via xcodebuild -showdestinations of the scheme, Swift packages via platforms: in the manifest (if not specified: macOS only).
  2. Availability: The simulator SDK must be installed locally (codeguard doctor shows platform.<name>).
  3. Restrict: If project.platforms is set, CodeGuard only builds the intersection.
  4. Test: macOS natively, all other platforms on disposable simulators. This requires an installed simulator runtime (simulator.<name> in doctor).
PlatformBuild destinationTest destination(s) in the reportText in the report
macosplatform=macOS,arch=<Host>macosmacOS
iosgeneric/platform=iOS Simulatorios-phone, plus ios-pad for iPad-capable Xcode targetsiOS/iPadOS or iOS/iPhone, iOS/iPad
watchosgeneric/platform=watchOS SimulatorwatchoswatchOS
tvosgeneric/platform=tvOS SimulatortvostvOS
visionosgeneric/platform=visionOS SimulatorvisionosvisionOS

macOS​

Swift package for macOS​

A package without platforms: in its manifest is built (swift build) and tested (swift test) as a macOS package. This configuration adds metrics and a custom rule:

version: 1
rules:
metrics:
line_length: { warning: 120, error: 160 }
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."
suggestion: "Logger verwenden."

Real run with a trust ticket, after a clean change:

CODEGUARD_PASSED

0 blocking violations found in 1 changed files.
Validation: file (complete)
Exit: 0 (completed)
Requested: compile, format, security, swiftlint, swiftlint_metrics, tests
Completed: compile, format, security, swiftlint, swiftlint_metrics, tests
Skipped:
Konfiguration: .codeguard.yml (auto, sha256 5967f32a…)
Tool: swift-format main [tool_swift_format] completed, 9ms, truncated: false
Tool: swiftlint 0.65.1 [tool_swiftlint] completed, 74ms, truncated: false
Tool: swiftlint 0.65.1 [tool_swiftlint_metrics] completed, 74ms, truncated: false
Tool: swift-package-manager 6.4.0-dev [tool_swiftpm_build] completed, 2611ms, truncated: false
Tool: swift-package-manager 6.4.0-dev [tool_swiftpm_test] completed, 3871ms, truncated: false
Run: cg_f5fb110f-22c5-4df5-9dd3-c302dffe4f4b

macOS app (Xcode)​

version: 1
project:
kind: xcode
xcode:
project: MyMacApp.xcodeproj
scheme: MyMacApp
configuration: Debug
platforms: [macos]
paths:
include: ["MyMacApp/**", "MyMacAppTests/**"]
exclude: [".build/**", "DerivedData/**", "Vendor/**", ".git/**"]
rules:
macos-app-sandbox-missing:
severity: error
entitlement-get-task-allow-release:
severity: error
  • kind: xcode and the xcode settings are required if the repository contains several projects or schemes. Otherwise CodeGuard finds the container and the shared scheme on its own.
  • paths.include covers the app's folders. Without this change, format, swiftlint and the content rules only check Sources/ and Tests/.
  • The two rules turn a missing App Sandbox and get-task-allow in Release into blocking findings. For apps distributed outside the App Store, a waiver is the intended approach.

Real platform findings from a macOS app without a sandbox and with disable-library-validation (default severity warning):

2. WARNING App.entitlements
Rule: entitlement-weakens-hardened-runtime
Entitlement com.apple.security.cs.disable-library-validation is true, weakening the hardened runtime.
Remove com.apple.security.cs.disable-library-validation unless the target has a specific, documented need for it.

3. WARNING App.entitlements
Rule: macos-app-sandbox-missing
Target "App" configuration "Debug" does not set com.apple.security.app-sandbox = true.
Set com.apple.security.app-sandbox to true, or waive this rule for non-App-Store distribution.

4. WARNING App.entitlements
Rule: macos-app-sandbox-missing
Target "App" configuration "Release" does not set com.apple.security.app-sandbox = true.
Set com.apple.security.app-sandbox to true, or waive this rule for non-App-Store distribution.

With a waiver for the Debug finding, the finding stays visible but counts as an accepted risk (summary.accepted_risk: 1, disposition: accepted_risk). You can find the example under Project configuration.

iOS and iPadOS​

version: 1
project:
kind: xcode
xcode:
workspace: MyApp.xcworkspace
scheme: MyApp
configuration: Debug
platforms: [ios]
test_destinations:
ios: { device_type: "iPhone 18 Pro", runtime: "27.0" }
ipad: { runtime: latest }
checks:
tests: { simulator: true, ipad: true }
paths:
include: ["MyApp/**", "MyAppTests/**"]
exclude: [".build/**", "DerivedData/**", "Pods/**", ".git/**"]
rules:
purpose-string-missing: { severity: critical }
ats-arbitrary-loads: { severity: error }
  • iPad run: If the TARGETED_DEVICE_FAMILY of an iOS target contains the value 2, CodeGuard also tests on an iPad. checks.tests.ipad: false turns this off.
  • test_destinations: If not specified, CodeGuard picks the newest runtime ≥ the deployment target and the first matching device type from its preference list. A forced destination that cannot be satisfied ends the run with exit 3. Device names depend on your Xcode version. codeguard doctor shows the automatically selected iPhone type.
  • Pods: Pods/** in the exclude list also removes the CocoaPods project from the platform checks.

Real run of an iOS app with iPad support and no configuration, one test fails:

CODEGUARD_FAILED

1 blocking violations found in 3 changed files.
Validation: project (complete)
Exit: 1 (validation_failed)
Requested: compile, format, platform, security, swiftlint, tests
Completed: compile, format, platform, security, swiftlint, tests
Skipped:
Plattformen: gebaut iOS/iPadOS
Simulatortests: getestet iOS/iPhone iPhone 18 Pro (Runtime 27.0), iOS/iPad iPad Pro 13-inch (M5) (16GB) (Runtime 27.0)
Tool: xcodebuild 1171.7.0 [tool_simctl_bootstatus] completed, 21870ms, truncated: false
…
Tool: xcodebuild 27.0.0 [tool_xcodebuild_test_ios_phone] completed, 13341ms, truncated: false
…
Run: cg_703370af-9cf1-4109-8175-b687b0c701ce

1. [iOS/iPhone, iOS/iPad] ERROR Tests/AppTests.swift:8:1
Rule: swift-test-failure
Expectation failed: 1 == 2

Next action: Fix the reported violations and run `codeguard check-diff` again.

Because two simulators had to boot, the run took much longer than a macOS run (bootstatus about 21 s per device on the reference machine).

tvOS​

version: 1
project:
kind: xcode
xcode:
project: MyTVApp.xcodeproj
scheme: MyTVApp
platforms: [tvos]
test_destinations:
tvos: { runtime: latest }
paths:
include: ["MyTVApp/**", "MyTVAppTests/**"]
exclude: [".build/**", "DerivedData/**", "Vendor/**", ".git/**"]
  • The build targets generic/platform=tvOS Simulator, tests run on a disposable simulator (destination tvos, device type from the preference list: Apple TV 4K).
  • An installed tvOS simulator runtime is required. If it is missing, the test destination is skipped. If tvOS is the only platform built, the run ends with exit 3, as shown in the watchOS example below.
note

This help has no real test run for tvOS and visionOS: no runtime for them was installed on the reference machine, and according to the CodeGuard verification documents, simulator tests for watchOS, tvOS and visionOS have not yet been run on a real simulator. Build and platform selection follow the same logic as for iOS.

watchOS​

version: 1
project:
kind: xcode
xcode:
project: MyApp.xcodeproj
scheme: MyWatchApp
platforms: [watchos]
test_destinations:
watchos: { runtime: latest }
paths:
include: ["MyWatchApp/**", "MyWatchAppTests/**"]
exclude: [".build/**", "DerivedData/**", "Vendor/**", ".git/**"]
  • The build targets generic/platform=watchOS Simulator, tests run on the destination watchos (device type: largest watch in the preference list).
  • A watch app does not raise the deployment target of the iOS part. CodeGuard evaluates the deployment target per platform.

Real run of a watchOS app on a machine without a watchOS runtime: the build succeeds, the tests cannot run.

CODEGUARD_ERROR

1 blocking violations found in 3 changed files.
Validation: project (partial)
Exit: 3 (dependency_unavailable)
Requested: compile, format, platform, security, swiftlint, tests
Completed: compile, format, platform, security, swiftlint
Skipped: tests
Plattformen: gebaut watchOS
Simulatortests: übersprungen watchOS (simulatorUnavailable)
…
1. ERROR
Rule: codeguard-simulator-selection-failed
checks.tests.required is set, but no test target can run on this host; no test ran.
Install a simulator runtime for a detected platform, or set checks.tests.required: false.

2. WARNING
Rule: codeguard-simulator-unavailable
No usable watchOS simulator runtime or device type with deployment target 10.0; its tests were skipped. There are no installed watchOS simulator runtimes.

How to fix this:

  • Install the runtime (recommended), then check again with codeguard doctor: simulator.watchos: available.
  • Or exclude tests from the project: checks: { tests: { scopes: [] } }.
  • Or, organization-wide, lock checks.tests.required: false in the organization policy. The missing destination is then only a warning.

Swift packages​

Package for several platforms​

version: 1
project:
kind: swift-package
package_path: Package.swift
platforms: [macos, ios]
rules:
metrics:
line_length: { warning: 120, error: 160, ignores_urls: true }
cyclomatic_complexity: { warning: 10, error: 20 }
function_body_length: { warning: 40, error: 80 }
nesting: { type_level: { warning: 2 }, function_level: { warning: 3 } }
  • macOS builds and tests with SwiftPM (swift build, swift test).
  • iOS, watchOS, tvOS, visionOS are built by xcodebuild on a copy of the package using the package scheme (<package name>-Package, otherwise the only scheme, otherwise project.xcode.scheme). If there are several schemes and none is specified, that is exit 2.
  • Packages do not get an iPad run.
  • project.platforms may name platforms that the manifest does not list under platforms:. With [macos, ios], CodeGuard also tests an iOS package natively on macOS.
Remote dependencies

swift build runs offline with an empty dependency cache. If the package depends on remote repositories, SwiftPM cannot load them. compile then reports codeguard-dependency-unavailable and the run ends with exit 3. The other checks still run. There is no way yet in 0.3.5 to provide dependencies offline. Until then, exclude compile and tests for such packages with scopes: [].

iOS-only package​

CodeGuard builds a package with platforms: [.iOS(.v17)] and no configuration for iOS only and tests it on an iPhone simulator. Real run:

CODEGUARD_FAILED

2 blocking violations found in 3 changed files.
Validation: project (complete)
Exit: 1 (validation_failed)
Requested: compile, format, security, swiftlint, tests
Completed: compile, format, security, swiftlint, tests
Skipped:
Plattformen: gebaut iOS/iPadOS
Simulatortests: getestet iOS/iPhone iPhone 18 Pro (Runtime 27.0)
…
Tool: swift-package-manager 6.4.0-dev [tool_swiftpm_dump_package] completed, 609ms, truncated: false
Tool: xcodebuild 27.0.0 [tool_xcodebuild_build_ios] completed, 1483ms, truncated: false
Tool: xcodebuild 27.0.0 [tool_xcodebuild_list] completed, 1022ms, truncated: false
…
1. ERROR Sources/IOSPackageTests/IOSPackageTests.swift:1:19
Rule: swiftlint.identifier_name
[identifier_name] Variable name 'a' should be between 3 and 40 characters long

2. ERROR Sources/IOSPackageTests/IOSPackageTests.swift:1:29
Rule: swiftlint.identifier_name
[identifier_name] Variable name 'b' should be between 3 and 40 characters long

3. WARNING Package.swift:10:85
Rule: swiftlint.trailing_comma
[trailing_comma] Collection literals should not have trailing commas

Build and tests were green. The SwiftLint findings with severity error caused the block.

All platforms, automatically​

version: 1
project:
kind: auto
platforms: [macos, ios, watchos, tvos, visionos]
test_destinations:
ios: { runtime: latest }
visionos: { runtime: latest }
  • Here platforms is an upper limit: CodeGuard builds what the project supports and what is on the list. For Xcode projects, however, a platform the scheme does not know is exit 2. In that case, leave out project.platforms to build everything detected.
  • Every listed platform needs its SDK, otherwise the run ends with exit 3.
  • An entry in test_destinations forces the destination: if the runtime is missing, that is exit 3 instead of a skipped destination.

Static checks only​

For projects where build and tests should not run (yet), for example because of remote dependencies:

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

Then security, platform, format, swiftlint and, if configured, swiftlint_metrics run. No trust ticket is needed.

See also​