This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
This repository is undergoing a migration from Ruby Rake to a modern Swift command line tool called Xproject. The existing Ruby rakelib serves as a reference implementation that we are incrementally migrating to Swift, taking the opportunity to:
- Modernize configuration: Move from YAML to more flexible formats (TOML, Swift configs)
- Improve type safety: Leverage Swift's type system for compile-time validation
- Enhance extensibility: Design a plugin-based architecture for easy feature additions
- Better developer experience: Create more intuitive commands and helpful error messages
- Reduce dependencies: Eliminate Ruby/gem dependencies for easier CI/CD setup
Important: The current Ruby rakelib should be used only as reference for understanding existing functionality. All new development should focus on the Swift Xproject tool, migrating features one by one while improving upon the original design.
Remember to bump the CLI version! Before starting work on a new feature or bug fix that will be released, update the VERSION file at the project root with the new version number. This ensures:
- The release workflow can create a new release when changes are merged
- The
xp --versioncommand reports the correct version - Version validation passes in CI
# Check current version
cat VERSION
# Update to new version
echo "1.1.0" > VERSION- ✅ Swift Package Manager structure: Package.swift with Xproject library and XprojectCLI executable
- ✅ Type-safe configuration system: YAML loading with Codable structs, validation, and layered overrides
- ✅ Setup command: Homebrew formula installation (deprecated bundler/cocoapods/submodules removed)
- ✅ Build command: Complete implementation for building Xcode projects for testing
- ✅ Test command: Full test orchestration with multi-scheme and multi-destination support
- ✅ Release command: Complete implementation for iOS/tvOS app archiving, IPA generation, and App Store upload
- ✅ Working directory support: Run commands from any directory with
-C/--working-directory - ✅ Multi-scheme and multi-destination testing: Run tests across multiple iOS simulators
- ✅ Custom configuration files: Use
--configoption to specify project-specific configs - ✅ Dry-run mode: Preview operations without executing them (
--dry-run) - ✅ Verbose mode: Show detailed command output with
--verbose - ✅ Enhanced error handling: Clear error messages with config file context
- ✅ Legacy compatibility: Works with existing rake-config.yml files
- ✅ Type-safe configuration: Swift Codable structs with validation
- ✅ Homebrew integration: Automated tool installation and updates
- ✅ Clean architecture: Separated CLI and business logic with explicit working directory handling
- ✅ Improved CLI output formatting: Clear info blocks showing working directory and configuration at command start, with environment variables displayed in structured format
- ✅ Environment management: Complete environment system with xcconfig generation, variable mapping, and multi-environment support
- ✅ Version management: Automated version bumping (patch/minor/major), build numbers from git commits, and git tagging
- ✅ Git operations: Automated version commit, tag creation with environment support, and push to remote
- ✅ Secret management: Dual-layer security (EJSON encryption + XOR obfuscation) for API keys with binary protection
- ✅ Provision management: Encrypted provisioning profile storage and installation for CI/CD
- ✅ PR Report integration: Post build/test results to GitHub PRs via Checks API with xcresult parsing
Targets:
XprojectCLI: CLI layer using ArgumentParser, calls into Xproject libraryXproject: Core business logic library (configuration, services, utilities) - no CLI dependenciesXprojectTests: Test suite for core library
Key Services:
ConfigurationService: Thread-safe singleton for loading and caching YAML configs with custom config file supportSetupService: Handles project setup (currently Homebrew only)BuildService: Handles building for tests with Xcode discoveryTestService: Orchestrates test workflows including build and test phases across multiple schemes/destinationsReleaseService: Orchestrates release workflow (archive → IPA generation → App Store upload)CleanService: Removes build artifacts and test reports directoriesEnvironmentService: Manages environment configurations, xcconfig generation, and variable mappingVersionService: Handles version bumping and build number calculation from git commitsGitService: Git operations (commit, tag, push) with safety checksEJSONService: EJSON encryption/decryption wrapper around swift-ejson libraryKeychainService: macOS Keychain integration for secure private key storageProvisionService: Provisioning profile encryption/decryption and installationPRReportService: Parses xcresult bundles and posts results to GitHub PRs via Checks API
Key Utilities:
OutputFormatter: Consistent formatting for CLI output with info blocks and structured displayCommandExecutor: Utility for executing shell commands safely with dry-run support and executeReadOnly for discovery operationsNestedDictionary: Dot notation access for nested YAML structures (e.g., "apps.ios.bundle_identifier")StringObfuscator: XOR-based obfuscation for preventing binary string extraction
# Build and test the Xproject Swift package itself
swift build # Build the project
swift build -c release # Build for release
swift test # Run all tests
swift run xp # Run the CLI tool directly
# Install for development
swift build -c release
cp .build/release/xp /usr/local/bin/ # Optional: install to PATH# Global options available on all commands
-C, --working-directory <path> # Working directory for the command (default: current directory)
-c, --config <path> # Specify custom configuration file (auto-discovers Xproject.yml, rake-config.yml by default)
-v, --verbose # Show detailed output and commands being executed
--dry-run # Show what would be done without executing (available on most commands)
# Core commands
xp setup # Install/update Homebrew formulas from config
xp config show # Display current configuration
xp config validate # Validate configuration files with comprehensive checks
xp build # Build for testing (supports --scheme, --clean, --destination)
xp test # Run tests (supports --scheme, --clean, --skip-build, --destination)
xp release # Create release builds (archive, IPA, upload with --archive-only, --skip-upload, --upload-only)
xp clean # Remove build artifacts and test reports (supports --dry-run)
xp env list # List available environments
xp env show # Show environment variables (current or specific)
xp env current # Show currently activated environment
xp env load # Load an environment and generate xcconfig files
xp env validate # Validate environment configuration
xp secrets generate <env> # Generate obfuscated AppKeys.swift
xp secrets encrypt [env] # Encrypt EJSON files
xp secrets show <env> # Display encrypted file info
xp secrets decrypt <env> # Decrypt and display (dev only)
xp secrets validate [env] # Validate EJSON file structure
xp provision encrypt # Encrypt provisioning profiles
xp provision decrypt # Decrypt provisioning profile archive
xp provision list # List profiles in encrypted archive
xp provision install # Install profiles to system
xp provision cleanup # Remove decrypted profiles
xp version show # Show current version
xp version bump <level> # Bump version (patch/minor/major)
xp version commit # Commit version changes
xp version tag # Create version tag
xp version push # Push to remote with tags
xp pr-report # Post build/test results to GitHub PR (auto-discovers xcresult bundles)
xp pr-report --xcresult <path> # Report specific xcresult bundle
xp pr-report --build-only # Report only build warnings/errors
xp pr-report --test-only # Report only test failures
xp pr-report --dry-run # Preview without posting to GitHub
# Examples
xp -C /path/to/project config show
xp --working-directory MyProject build --scheme MyApp --clean
xp test --config my-config.yml --scheme MyApp --clean --dry-run
xp release production-ios
xp release dev-ios --archive-only --dry-run
xp setup --dry-run
xp clean --dry-run
xp config --config custom.yml validate
xp env list
xp env load dev --dry-run
xp env load production
xp env show dev
xp secrets generate dev
xp provision encrypt
xp provision decrypt
xp provision install
xp version bump patch
xp version tag --environment production
xp version push
xp pr-report --dry-run
xp pr-report --check-name "iOS Tests"Xproject includes a complete environment management system for handling multiple deployment environments (dev, staging, production, etc.) with automatic xcconfig file generation.
The environment system allows you to:
- Define multiple environments (dev, staging, production, etc.)
- Generate environment-specific
.xcconfigfiles automatically - Manage configuration variables using YAML
- Support multiple targets with bundle ID suffixes
- Per-configuration variable overrides (debug vs release)
YourProject/
├── env/
│ ├── config.yml # Environment system configuration
│ ├── .current # Currently active environment (gitignored)
│ ├── dev/
│ │ └── env.yml # Development environment variables
│ ├── staging/
│ │ └── env.yml # Staging environment variables
│ └── production/
│ └── env.yml # Production environment variables
├── YourApp/
│ └── Config/ # Generated xcconfig files (gitignored)
│ ├── YourApp.debug.xcconfig
│ └── YourApp.release.xcconfig
└── Xproject.yml # Project configuration
-
Create env/config.yml:
targets: - name: MyApp xcconfig_path: MyApp/Config shared_variables: PRODUCT_BUNDLE_IDENTIFIER: apps.bundle_identifier BUNDLE_DISPLAY_NAME: apps.display_name API_URL: api_url configurations: debug: {} release: variables: PROVISIONING_PROFILE_SPECIFIER: apps.ios.provision_profile
-
Create environment files (e.g., env/dev/env.yml):
environment_name: development api_url: https://dev-api.example.com apps: bundle_identifier: com.example.myapp.dev display_name: MyApp Dev ios: app_icon_name: AppIcon provision_profile: Development
-
Activate environment:
xp env load dev
- Dot notation access: Use paths like
apps.ios.bundle_identifierto access nested YAML values - Bundle ID suffixes: Automatically append suffixes for app extensions (
.widget,.notification-content) - Configuration-specific variables: Different variables for debug vs release builds
- Swift code generation: Type-safe Swift code from environment variables with prefix filtering and type inference
- Validation: Comprehensive validation of configuration and environment files
- Dry-run support: Preview xcconfig and Swift generation without writing files
The environment system can automatically generate type-safe Swift files:
swift_generation:
outputs:
# Base class - automatically includes ALL root-level variables
- path: MyApp/Generated/EnvironmentService.swift
prefixes: [] # Empty - base type auto-includes root-level
type: base
# Extension - explicitly specify namespaces
- path: MyApp/Generated/EnvironmentService+App.swift
prefixes: [apps, features]
type: extension
# Extension in different module - imports base class module
- path: MyAppKit/Generated/EnvironmentService+Kit.swift
prefixes: [services]
type: extension
imports: [MyApp]Features:
- Base type auto-includes root-level: Base class automatically includes all root-level variables
- Namespace filtering: Extensions filter by namespace (e.g.,
apps,features) - CamelCase conversion:
bundle_identifier→bundleIdentifier,api_url→apiURL - Type inference: Automatic URL, String, Int, Bool detection
- Base class or extension: Generate standalone class or extend existing
- URL handling: Auto-detect URL properties by name suffix (
*URL,*Url) - Cross-module imports: Extensions can import modules containing the base class via
importsoption
Example generated code:
public final class EnvironmentService {
public init() {}
public let apiURL = url("https://dev-api.example.com")
public let environmentName = "development"
}
extension EnvironmentService {
public var bundleIdentifier: String { "com.example.app.dev" }
public var iosAppIconName: String { "AppIcon" }
public var debugMenu: Bool { true }
}- Models:
EnvironmentConfig,SwiftGenerationConfig,SwiftOutputConfigin Sources/Xproject/Models/EnvironmentConfig.swift - Service:
EnvironmentServicein Sources/Xproject/Services/EnvironmentService.swift handles all environment operations - Templates:
SwiftTemplatesin Sources/Xproject/Templates/SwiftTemplates.swift with embedded code generation - Utility:
NestedDictionaryin Sources/Xproject/Utilities/NestedDictionary.swift provides dot notation access - Commands:
EnvironmentCommandin Sources/XprojectCLI/Commands/EnvironmentCommand.swift with 5 subcommands - Tests: 28 dedicated tests (17 environment, 12 Swift generation) in Tests/XprojectTests/Services/ - 226 total tests passing
See docs/environment-setup.md for detailed setup guide and examples.
Xproject includes a complete version management system for handling semantic versioning, build numbers from git commits, and automated git tagging.
The version management system allows you to:
- Bump semantic versions (major.minor.patch) using agvtool
- Calculate build numbers from git commit count with configurable offset
- Commit version changes automatically with
[skip ci]prefix - Create version tags in standardized format
- Push branches and tags to remote repositories
Important: The "target" parameter (e.g., "ios", "tvos") refers to a configuration key in project_path, not an Xcode build target. Each target maps to a specific .xcodeproj file, which may be in a subdirectory:
project_path:
ios: MyApp.xcodeproj # Root-level project
tvos: TV/TV.xcodeproj # Subdirectory projectWhen you run xp version bump patch ios, agvtool updates all Xcode targets within MyApp.xcodeproj. Similarly, xp version bump patch tvos updates all targets in TV/TV.xcodeproj. This matches the behavior of Apple's agvtool, which operates on entire projects, not individual targets.
Add version configuration to your Xproject.yml:
version:
build_number_offset: -6854 # Offset for git commit count
tag_format: "{env}-{target}/{version}-{build}" # Optional custom format# Show current version and build
xp version show [target]
# Bump version (patch/minor/major)
xp version bump patch [target] # 1.0.0 → 1.0.1
xp version bump minor [target] # 1.0.0 → 1.1.0
xp version bump major [target] # 1.0.0 → 2.0.0
# Commit version bump changes
xp version commit [target] # Commits with [skip ci] prefix
# Create git tag
xp version tag [target] # Creates tag: ios/1.0.0-100
xp version tag [target] --environment production # Creates tag: production-ios/1.0.0-100
# Push to remote
xp version push # Push current branch with tags
xp version push --remote upstream # Push to specific remote
# All commands support --dry-run
xp version bump patch --dry-run
xp version tag --dry-run# 1. Check current version
xp version show
# 2. Bump version
xp version bump patch
# 3. Commit changes
xp version commit
# 4. Create tag
xp version tag --environment production
# 5. Push to remote
xp version pushBuild numbers are automatically calculated from git commit count:
- Gets current commit count with
git rev-list HEAD --count - Applies configured offset from
version.build_number_offset - Example: 7000 commits + offset -6854 = build number 146
Tags follow the format: [environment-]target/version-build
- Without environment:
ios/1.0.0-146 - With environment:
production-ios/1.0.0-146
- Models:
Version,VersionConfigurationin Sources/Xproject/Models/ - Services:
VersionServicein Sources/Xproject/Services/VersionService.swift - Handles agvtool operations and build number calculationGitServicein Sources/Xproject/Services/GitService.swift - Handles git operations (commit, tag, push)
- Commands:
VersionCommandin Sources/XprojectCLI/Commands/VersionCommand.swift with 5 subcommands - Tests: 56 dedicated tests (19 Version + 17 VersionService + 20 GitService) - All passing
- Repository clean check: Warns if uncommitted changes exist
- Expected files validation: Ensures only version-related files changed
- Tag existence check: Prevents duplicate tags
- Dry-run mode: Preview all operations before execution
Xproject includes a complete secret management system for handling API keys and sensitive data with dual-layer security: EJSON encryption (at-rest) and XOR obfuscation (in-binary).
See docs/secrets-management.md for the complete user guide with setup instructions, CI/CD integration, and troubleshooting.
The secret management system provides:
- Dual-layer protection: EJSON asymmetric encryption for repository storage + XOR obfuscation to prevent binary extraction
- No plaintext in binaries: Secrets stored as obfuscated byte arrays, defeating
stringscommand - macOS Keychain integration: Secure storage for EJSON private keys
- CI/CD support: Environment variable priority (
EJSON_PRIVATE_KEY_{ENV}>EJSON_PRIVATE_KEY> Keychain) - Smart Swift generation: Automatic CamelCase conversion, URL/API suffix handling, type inference
- Automatic integration: Secrets generated automatically during
xp env load
Add to your Xproject.yml:
secrets:
swift_generation:
outputs:
- path: MyApp/Generated/AppKeys.swift
prefixes: [all, ios] # Filter secrets by prefix
- path: MyTVApp/Generated/AppKeys.swift
prefixes: [all, tvos]YourProject/
├── env/
│ ├── dev/
│ │ ├── env.yml
│ │ └── keys.ejson # Encrypted secrets
│ ├── production/
│ │ ├── env.yml
│ │ └── keys.ejson
└── MyApp/
└── Generated/
└── AppKeys.swift # Generated obfuscated code (gitignored)
Layer 1: EJSON Encryption (At-Rest)
- Asymmetric encryption using NaCl Box (Curve25519 + Salsa20 + Poly1305)
- Public key in repository, private key in keychain or ENV vars
- Compatible with Shopify EJSON specification
Layer 2: XOR Obfuscation (In-Binary)
- Prevents extraction with
stringscommand - Random XOR key stored alongside obfuscated data
- Inspired by cocoapods-keys
- Models:
SecretConfiguration,EJSONFile,SecretErrorin Sources/Xproject/Models/SecretConfig.swift - Services:
EJSONService- Swift wrapper around swift-ejson libraryKeychainService- macOS Keychain integration with ENV var priority
- Utilities:
StringObfuscator- XOR-based obfuscation - Templates:
AppKeysTemplate- Generates obfuscated Swift code - Commands:
SecretsCommandwith 4 subcommands (generate, encrypt, show, decrypt) - Tests: 48 dedicated tests (12 StringObfuscator + 13 KeychainService + 13 EJSONService + 10 AppKeysTemplate)
- Dependencies: swift-ejson library via SPM (includes libsodium for NaCl cryptography)
- Swift 6 compatibility: Uses
@preconcurrency import EJSONKitand@unchecked Sendable - Test serialization: KeychainService and EJSONService tests run serialized for thread safety
- Generated code structure: Private byte arrays with computed property accessors
- Prefix filtering: Separate secrets for iOS (
ios_*), tvOS (tvos_*), shared (all_*), services (services_*) - Type inference: Automatic detection of String, URL, Int, Bool types
- CamelCase naming:
shopify_api_key→shopifyAPIKey,api_url→apiURL
This system protects against:
- ✅ Casual
stringsextraction from binaries - ✅ Automated secret scanning tools
- ✅ Source code leaks (EJSON encryption)
- ✅ Accidental exposure in App Store analysis
This system does NOT protect against:
- ❌ Runtime debugging (LLDB, Frida)
- ❌ Memory dumps during execution
- ❌ Determined reverse engineering
Best Practice: Never store critical secrets in mobile apps. Use server-side authentication with OAuth or similar protocols. This system is for protecting third-party API keys (analytics, SDKs) that must be embedded in the app.
Xproject includes provisioning profile management for CI/CD with manual signing workflows. Profiles are encrypted using AES-256-CBC with PBKDF2 key derivation via the system's /usr/bin/openssl.
See docs/provision-management.md for the complete user guide with setup instructions, CI/CD integration, and troubleshooting.
The provision management system provides:
- AES-256-CBC encryption: Strong encryption for profiles at rest in repositories
- Password-based security: PBKDF2 key derivation with 100,000 iterations
- CI/CD support: Environment variable priority (
PROVISION_PASSWORD> Keychain) - macOS Keychain integration: Secure password storage for local development
- Atomic operations: Archive management with encrypt/decrypt/install commands
Add to your Xproject.yml:
provision:
source_path: provision/source/ # Source directory for encryption
archive_path: provision/profiles.zip.enc # Encrypted archive path
extract_path: provision/profiles/ # Extraction directoryYourProject/
├── provision/
│ ├── source/ # Source profiles (gitignored)
│ │ ├── iOS_Dev.mobileprovision
│ │ └── iOS_Dist.mobileprovision
│ ├── profiles/ # Extracted profiles (gitignored)
│ └── profiles.zip.enc # Encrypted archive (committed)
└── Xproject.yml
# Encrypt profiles for storage
xp provision encrypt
# Decrypt and install (CI/CD)
xp provision decrypt
xp provision install
# Clean up decrypted files
xp provision cleanup- Models:
ProvisionConfiguration,ProvisionProfile,ProvisionErrorin Sources/Xproject/Models/ProvisionConfiguration.swift - Services:
ProvisionService- Handles encrypt/decrypt/install/list/cleanup operations - Commands:
ProvisionCommandwith 5 subcommands (encrypt, decrypt, list, install, cleanup) - Tests: ~21 dedicated tests for ProvisionService
- Dependencies: Uses system
/usr/bin/openssl(no external dependencies)
This system protects against:
- ✅ Profile exposure in version control
- ✅ Unauthorized access to provisioning profiles
This system does NOT protect against:
- ❌ Access if password is compromised
- ❌ Installed profiles on disk (standard permissions)
Xproject can post build warnings, errors, and test failures directly to GitHub PRs via the Checks API. This provides inline annotations on the PR diff and summary comments.
The PR report system provides:
- xcresult parsing: Extracts build issues and test failures from Xcode result bundles
- GitHub Checks API: Posts inline annotations directly on PR diffs
- Auto-discovery: Automatically finds
.xcresultbundles in the reports directory - Filtering: Ignore files by glob pattern, filter warnings, collapse parallel test failures
- Dry-run mode: Preview what would be reported without posting
Add to your Xproject.yml:
pr_report:
check_name: "Xcode Build & Test" # Optional: custom check name
post_summary: true # Post summary (when false, still posts if issues)
inline_annotations: true # Post inline annotations
fail_on_errors: true # Mark check as failed on build errors
fail_on_test_failures: true # Mark check as failed on test failures
ignored_files: # Glob patterns to ignore
- "Pods/**"
- "**/Generated/**"
ignore_warnings: false # Filter out warnings
collapse_parallel_tests: true # Deduplicate parallel test failuresxp pr-report # Auto-discover and report all xcresult bundles
xp pr-report --xcresult path/to/test.xcresult # Report specific bundle
xp pr-report --check-name "iOS Tests" # Custom check name
xp pr-report --build-only # Report only build warnings/errors
xp pr-report --test-only # Report only test failures
xp pr-report --dry-run # Preview without posting- name: Run tests
run: xp test --scheme MyApp
- name: Report results
if: always()
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: xp pr-reportRequired environment variables (automatically set in GitHub Actions):
GITHUB_TOKEN- Authentication token withchecks:writepermissionGITHUB_REPOSITORY- Repository inowner/repoformatGITHUB_SHA- Commit SHA to annotate
- Models:
PRReportConfiguration,PRReportResult,PRReportErrorin Sources/Xproject/Models/PRReportConfiguration.swift - Services:
PRReportService- Parses xcresult bundles, converts to annotations, reports to GitHub - Commands:
PRReportCommandwith options for xcresult paths, check name, build/test modes - Tests: 46 dedicated tests for PRReportService
- Dependencies:
swift-pr-reporter(PRReporterKit) andswift-xcresult-parser(XCResultParser)
- Glob pattern filtering: Use patterns like
Pods/**or**/Generated/**to ignore files - Parallel test collapsing: Deduplicate failures from parallel test runs
- Graceful non-PR handling: Automatically switches to dry-run mode when not in a PR context
- Summary generation: Markdown summary with error/warning/test counts
When running outside a PR context (e.g., push to main after merge, local development), the command automatically switches to dry-run mode instead of failing:
- Not in GitHub Actions: Displays results without posting
- Push event (no PR number): Shows results with informative skip message
- Fork PR: Handles read-only token gracefully
This allows the same CI workflow to run on both PR and non-PR events without conditional logic:
This is a existing iOS/tvOS application build system using Ruby Rake. The project consists of a comprehensive Xcode build automation toolkit with multiple targets (iOS app, tvOS app, notification extensions, widgets) and environment-specific configuration management.
- Central config:
rake-config.ymlcontains app settings, Xcode build configurations, and release configurations - Environment management:
env/directory contains environment-specific YAML files with bundle identifiers, API keys, and platform-specific settings - Generated configs: System automatically generates
.xcconfigfiles and Swift environment files from YAML configs
- Multi-target support: iOS app, tvOS app, notification extensions, widgets, TopShelf extension
- Environment-driven builds: Each environment (dev, staging, production, snapshot) has specific bundle IDs, signing certificates, and provisioning profiles
- Automated versioning: Build numbers derived from git commit count with offset, semantic versioning for marketing versions
- EJSON encryption: API keys and secrets stored in encrypted
keys.ejsonfiles per environment - Provision profiles: Encrypted with GPG, stored in keychain for CI/CD access
- Keychain integration: Automatic storage/retrieval of sensitive build credentials
rake setup # Full project setup (bundler, brew, dependencies)
rake setup:bundler # Install Ruby dependencies
rake setup:brew # Install/update brew formulas
rake setup:cocoapods # Install CocoaPods dependencies
rake setup:googlecast # Download Google Cast SDKrake env:load[env_name] # Load and configure environment (generates .xcconfig and Swift files)
rake env:current # Show currently selected environmentrake xcode:tests[clean,run_danger] # Run unit tests (clean=true for clean build, run_danger=true for CI checks)
rake xcode:release[env] # Full release build (archive + generate IPA)
rake xcode:archive[env] # Archive only
rake xcode:generate_ipa[env] # Generate IPA from existing archive
rake xcode:upload[env] # Upload to App Store Connectrake bump:patch[target] # Bump patch version (1.0.0 -> 1.0.1)
rake bump:minor[target] # Bump minor version (1.0.0 -> 1.1.0)
rake bump:major[target] # Bump major version (1.0.0 -> 2.0.0)rake git:commit_version_bump[target] # Commit version changes with [skip ci]
rake git:add_tag[target] # Tag release with version
rake git:push # Push branch and tags
rake git:check_dirty_repository # Verify clean working directoryrake ejson:encrypt # Encrypt all environment key files
rake provision:encrypt # Encrypt provisioning profiles
rake provision:decrypt # Decrypt provisioning profilesrake swiftgen # Generate Swift code from resources
rake swiftgen:strings # Generate localized strings- Environment setup: Run
rake env:load[environment]to configure for target environment - Development: Code changes, then
rake xcode:tests[true]for clean test run - Version bump: Use
rake bump:patch[ios]or appropriate version increment - Release:
rake git:commit_version_bump[ios] && rake git:add_tag[ios] && rake xcode:release[production-ios] - Deploy:
rake xcode:upload[production-ios] && rake git:push
- ios: Main iOS target
- tvos: tvOS target
- production-ios/tvos: App Store releases
- dev-ios/tvos: Development builds
- staging-ios/tvos: Staging/QA builds
- snapshot-ios/tvos: Snapshot testing builds
.xcconfigfiles: Generated in*/SupportingFiles/directories per target and configuration- Swift environment files: Generated in
*/Generated/directories using Mustache templates - Secret files: Generated Swift files with encrypted keys in
*/Generated/AppKeys.swift
- Ruby gems: bundler, xcodeproj, git, plist, json, mustache, tty-prompt, keychain
- System tools: brew, agvtool, xcodebuild, xcpretty, ejson, gpg
- Build tools: SwiftGen, CocoaPods, Google Cast SDK
- Danger integration: Automated code review checks with multiple Dangerfiles
- Build artifacts: Stored in configurable
build/andreports/directories - Environment variables: Support for
BUNDLER_PATH,ARTIFACTS_PATH,TEST_REPORTS_PATH,APP_STORE_PASS,EJSON_PRIVATE_KEY,PROVISION_PASSWORD
- No CLI dependencies in core library: Xproject library must remain free of ArgumentParser or other CLI frameworks
- Deprecated dependency managers: Do not implement bundler, cocoapods, submodules, or carthage - these are deprecated
- Service-based architecture: Business logic should be in services that CLI commands call into
- Swift 6.2 compliance: Project uses Swift 6.2 with strict concurrency checking
- Explicit working directory: All services and classes require explicit
workingDirectoryparameter with NO default values. Only GlobalOptions provides the default via computed propertyresolvedWorkingDirectory. This eliminates implicitFileManager.default.currentDirectoryPathusage throughout the codebase. - Single source of truth for working directory: CommandExecutor uses only its instance property for working directory, not method parameters. If different directory needed, create new executor instance.
- Temporary files directory: All temporary files and directories MUST be created in the project's
tmp/directory, NEVER in the system/tmp. Thetmp/directory is in .gitignore and its contents can be deleted at any time, so no important files should be stored there.
- Any use of @unchecked Sendable or nonisolated(unsafe) needs user approval
- Swift files should have less up to 300 lines
- Test directory structure must mirror source directory structure
- For example: if source file is at
Sources/Xproject/Utilities/CommandExecutor.swift, test file should be atTests/XprojectTests/Utilities/CommandExecutorTests.swift - This ensures consistent organization and makes tests easy to locate
Priority order for implementing remaining features:
-
✅
Build command- COMPLETED: Full implementation with scheme selection, clean builds, and custom destinations -
✅
Test command- COMPLETED: Complete test orchestration with multi-scheme and multi-destination support -
✅
Global --config option- COMPLETED: Custom configuration file support across all commands -
✅
Enhanced error handling- COMPLETED: Informative error messages with config file context -
✅
Dry-run functionality- COMPLETED: Safe preview mode with executeReadOnly for discovery operations -
✅
Release command- COMPLETED: Archive, IPA generation, and App Store upload with automatic/manual signing (139 tests passing) -
✅
Environment management- COMPLETED: Full environment system with xcconfig generation, Swift code generation, variable mapping, validation (226 tests passing) -
✅
Version management- COMPLETED: Auto-increment build numbers, semantic versioning, git tagging (56 tests passing) -
✅
Git operations- COMPLETED: Commit, tag, and push automation with safety checks -
✅
Secret management- COMPLETED: Dual-layer security with EJSON encryption and XOR obfuscation -
✅
Provision management- COMPLETED: Encrypted profile storage and CI/CD installation -
✅
PR Report integration- COMPLETED: Post build/test results to GitHub PRs via Checks API (392 total tests passing)
Remaining Work:
- None for core functionality - all planned features complete!
- Support for additional configuration formats (TOML, Swift configs)
- Plugin-based architecture for extensibility
- SwiftGen integration for code generation
The docs/ directory contains user guides and reference documentation:
environment-setup.md- Detailed setup guide for the environment management systemsecrets-management.md- Complete user guide for secret management with EJSON encryptionswift-testing_api.md- Swift Testing framework API referenceswift-testing-playbook.md- Best practices and patterns for Swift Testing