This document covers development workflows for contributors to the Contour project.
- Rust 1.85+ (stable) via
rust-toolchain.toml uvfor Python (mSCP generation pipeline)
contour/
├── Cargo.toml # Workspace manifest with shared dependencies + lints
├── Cargo.lock # Committed lockfile for reproducible builds
├── rust-toolchain.toml # Rust stable + rustfmt, clippy
├── crates/
│ ├── contour/ # Unified CLI dispatcher (binary)
│ ├── contour-core/ # Shared library (output, logging, fragments, FleetLayout, help-ai)
│ ├── mscp-schema/ # mSCP compliance data (embedded parquet, 10 datasets)
│ ├── profile/ # Apple configuration profile toolkit
│ ├── pppc/ # Privacy/TCC profile generator
│ ├── btm/ # Background Task Management profiles
│ ├── notifications/ # Notification settings profiles
│ ├── support/ # Root3 Support App profiles
│ ├── santa/ # Santa allowlist/blocklist toolkit (CEL, FAA, rings)
│ └── mscp/ # mSCP baseline transformer (Fleet, Jamf, Munki)
├── scripts/
│ ├── build-release.sh # Build, sign (codesign + pkgbuild), notarize (--op for 1Password)
└── .github/workflows/
├── ci.yml # PR checks: fmt, clippy, test, audit
├── release.yml # Tag-triggered linux build (v* tags)
└── build_contour_{pre,}release_manual.yml # Manual macOS draft releases (workflow_dispatch)
# Build the unified contour binary (default member)
cargo build
# Build all crates
cargo build --workspace
# Build release
cargo build --release
# Build for Apple Silicon (release, cross-target)
cargo build --release --target aarch64-apple-darwin -p contour
# Run a specific tool directly
cargo run -p profile -- --help
cargo run -p santa -- cel fields --json# Run all tests
cargo test --workspace
# Run tests for specific crate
cargo test -p contour-core
cargo test -p profile
cargo test -p mscp
cargo test -p santa
cargo test -p mscp-schema
# Run a specific test
cargo test -p santa -- cel::validate::tests::test_validate_unknown_field
# Run tests with output
cargo test -- --nocaptureLints are configured at workspace level in Cargo.toml:
[workspace.lints.rust]— 7 compiler lints[workspace.lints.clippy]— all major categories + 19 restriction lints
# Check formatting
cargo fmt --check
# Apply formatting
cargo fmt
# Run clippy (workspace lints apply automatically)
cargo clippy --workspace
# Run clippy with warnings as errors (CI mode)
cargo clippy --workspace -- -D warnings- Use
#[expect(lint, reason = "...")]for non-dead-code suppressions - Use
#[allow(dead_code, reason = "...")]for forward-declared items - Every
#[allow]must include areasonparameter
All Fleet output uses FleetLayout from contour-core. Default is v4.83 (definitive structure from fleetctl new):
platforms/
├── all/{icons,policies,reports}/
├── macos/{configuration-profiles,declaration-profiles,commands,enrollment-profiles,policies,reports,scripts,software}/
├── ios/{configuration-profiles,declaration-profiles}/
├── ipados/{configuration-profiles,declaration-profiles}/
├── windows/{configuration-profiles,policies,reports,scripts,software}/
├── linux/{policies,reports,scripts,software}/
└── android/{configuration-profiles,managed-app-configurations}/
fleets/ # fleet YAML files (glob paths: *.mobileconfig)
labels/ # one .yml per label
Key v4.83 changes: declaration-profiles/ separated from configuration-profiles/, glob paths: patterns, apple_settings key.
Versions: FleetLayout::v4_83() (default), FleetLayout::v4_82(), FleetLayout::legacy().
Import profiles from Jamf backup YAML (jamf-cli export format):
# Step 1: Export profiles from Jamf Pro using jamf-cli
jamf-cli pro backup --output ./jamf-backup --resources profiles
# Step 2: Import, normalize, and validate with contour
contour profile import --jamf ./jamf-backup/profiles/macos/ --all -o output/ --org com.yourco
# Dry run (preview without writing)
contour profile import --jamf ./jamf-backup/profiles/macos/ --all --dry-runThe Jamf YAML payloads: |- field contains minified mobileconfig XML. The import pipeline:
- Parses YAML, extracts
general.payloadsplist - Writes as properly formatted
.mobileconfig - Normalizes identifiers under
--orgnamespace - Regenerates deterministic UUIDs
- Validates against embedded Apple schema
Synthesize mobileconfigs from deployed managed preference plists:
contour profile synthesize /Library/Managed\ Preferences/ -o profiles/ --org com.yourco --validateDependencies are managed at workspace level:
# In root Cargo.toml
[workspace.dependencies]
new-crate = "1.0"
# In crate's Cargo.toml
[dependencies]
new-crate.workspace = trueAll crates share one version (set in the workspace [workspace.package]).
Current: v0.2.0. Release via v* tags:
# Bump in crates/contour/Cargo.toml (and any other crate that doesn't
# inherit the workspace version yet) — verify with:
grep -E "^version = " Cargo.toml crates/*/Cargo.toml | sort -u
# Tag and push
git tag v0.2.0
git push origin v0.2.0
# GitHub Actions builds Linux + macOS artifacts# Full pipeline: build → sign → notarize binary → pkg → notarize pkg → staple
./scripts/build-release.sh --op
# Skip build (reuse existing binary)
./scripts/build-release.sh --op --skip-build --install
# Skip pkg creation
./scripts/build-release.sh --op --skip-pkg
# Upload to GitHub Release
./scripts/release-macos.sh contourAll CLIs support reproducible builds via SOURCE_DATE_EPOCH:
SOURCE_DATE_EPOCH=1706500000 cargo build --releaseBuild timestamps round to 10-minute intervals for cache efficiency.
All commands support --json for machine-readable output:
use contour_core::{CommandResult, OutputMode};
pub fn handle_info(mode: OutputMode) -> Result<()> {
match mode {
OutputMode::Human => print_info("..."),
OutputMode::Json => print_json(&serde_json::json!({...}))?,
}
Ok(())
}Agent-facing workflows are documented in help-ai:
contour help-ai # command index + SOP pointers
contour help-ai --sop profile # profile generation workflow
contour help-ai --sop mscp # mSCP compliance workflow
contour help-ai --sop santa # Santa allowlist workflow
contour help-ai --command santa.cel.compile # specific command detail
contour help-json profile.validate # JSON schema for a commandci.yml— on push/PR to main: fmt → clippy → test → build → auditrelease.yml— onv*tags: build Linux + macOS, create GitHub Release
cargo fmt --check && \
cargo clippy --workspace -- -D warnings && \
cargo test --workspace