$npx -y skills add rshankras/claude-code-apple-skills --skill ci-cd-setupGenerate CI/CD configuration for automated builds, tests, and distribution of iOS/macOS apps. Use when setting up GitHub Actions, Xcode Cloud, or fastlane for continuous integration, TestFlight, or App Store deployment.
| 1 | # CI/CD Setup Generator |
| 2 | |
| 3 | Generate CI/CD configuration for automated builds, tests, and distribution of iOS/macOS apps. |
| 4 | |
| 5 | ## When This Skill Activates |
| 6 | |
| 7 | - User wants to automate their build and test process |
| 8 | - User mentions GitHub Actions, Xcode Cloud, or fastlane |
| 9 | - User wants to set up TestFlight or App Store deployment |
| 10 | - User asks about continuous integration for their app |
| 11 | |
| 12 | ## Pre-Generation Checks |
| 13 | |
| 14 | Before generating, verify: |
| 15 | |
| 16 | 1. **Existing CI Configuration** |
| 17 | ```bash |
| 18 | # Check for existing CI files |
| 19 | ls -la .github/workflows/ 2>/dev/null |
| 20 | ls -la ci_scripts/ 2>/dev/null |
| 21 | ls -la fastlane/ 2>/dev/null |
| 22 | ``` |
| 23 | |
| 24 | 2. **Project Structure** |
| 25 | ```bash |
| 26 | # Find Xcode project/workspace |
| 27 | find . -name "*.xcodeproj" -o -name "*.xcworkspace" | head -5 |
| 28 | ``` |
| 29 | |
| 30 | 3. **Package Manager** |
| 31 | ```bash |
| 32 | # Check for SPM vs CocoaPods |
| 33 | ls Package.swift 2>/dev/null |
| 34 | ls Podfile 2>/dev/null |
| 35 | ``` |
| 36 | |
| 37 | ## Configuration Questions |
| 38 | |
| 39 | ### 1. CI/CD Platform |
| 40 | - **GitHub Actions** (Recommended) - Full control, extensive marketplace |
| 41 | - **Xcode Cloud** - Native Apple integration, simpler setup |
| 42 | - **Both** - GitHub for PRs/tests, Xcode Cloud for releases |
| 43 | |
| 44 | ### 2. Distribution Method |
| 45 | - **TestFlight** - Beta testing via App Store Connect |
| 46 | - **App Store** - Production releases |
| 47 | - **Direct** (macOS only) - Notarized DMG/PKG distribution |
| 48 | - **All** - Full pipeline from dev to production |
| 49 | |
| 50 | ### 3. Include fastlane? |
| 51 | - **Yes** - Advanced automation, match for code signing |
| 52 | - **No** - Simpler setup using xcodebuild directly |
| 53 | |
| 54 | ### 4. Code Signing Approach |
| 55 | - **Manual** - Certificates in GitHub Secrets |
| 56 | - **match** (fastlane) - Git-based certificate management |
| 57 | - **Xcode Cloud Managed** - Apple handles signing |
| 58 | |
| 59 | ## Generated Files |
| 60 | |
| 61 | ### GitHub Actions |
| 62 | ``` |
| 63 | .github/workflows/ |
| 64 | ├── build-test.yml # PR checks, unit tests |
| 65 | ├── deploy-testflight.yml # TestFlight deployment |
| 66 | └── deploy-appstore.yml # App Store submission |
| 67 | ``` |
| 68 | |
| 69 | ### Xcode Cloud |
| 70 | ``` |
| 71 | ci_scripts/ |
| 72 | ├── ci_post_clone.sh # Post-clone setup |
| 73 | └── ci_pre_xcodebuild.sh # Pre-build configuration |
| 74 | ``` |
| 75 | |
| 76 | ### fastlane |
| 77 | ``` |
| 78 | fastlane/ |
| 79 | ├── Fastfile # Lane definitions |
| 80 | ├── Appfile # App configuration |
| 81 | └── Matchfile # Code signing (if using match) |
| 82 | ``` |
| 83 | |
| 84 | ### SwiftLint |
| 85 | ``` |
| 86 | .swiftlint.yml # from templates/swiftlint/swiftlint.yml |
| 87 | ``` |
| 88 | |
| 89 | ## Merging Skill Rule Fragments |
| 90 | |
| 91 | Skills in this library may ship graduated enforcement as a |
| 92 | `rules/swiftlint.yml` fragment (`opt_in_rules` + `custom_rules`) — prose |
| 93 | rules turned into deterministic lint. When generating `.swiftlint.yml`: |
| 94 | |
| 95 | 1. Start from `templates/swiftlint/swiftlint.yml`. |
| 96 | 2. For each skill the project actually uses, check for |
| 97 | `skills/<category>/<skill>/rules/swiftlint.yml`; append its |
| 98 | `custom_rules` entries and union its `opt_in_rules`. |
| 99 | 3. Respect fragment scoping comments — e.g. `observable_object_legacy` |
| 100 | applies only to iOS 17+/macOS 14+ deployment targets, and |
| 101 | `xctest_in_unit_tests` must keep its UITests exclusion (XCUITest |
| 102 | legitimately requires XCTest). |
| 103 | 4. The generated `build-test.yml` runs the `lint` job automatically once |
| 104 | `.swiftlint.yml` exists (`if: hashFiles('.swiftlint.yml') != ''`). |
| 105 | |
| 106 | Current fragments: `security/` (hardcoded secrets), `ios/coding-best-practices` |
| 107 | (print-in-production, legacy ObservableObject, force_unwrapping/force_try), |
| 108 | `testing/tdd-feature` (XCTest scoped out of unit tests), |
| 109 | `swift/concurrency` (@unchecked Sendable without justification). |
| 110 | |
| 111 | ## Integration Steps |
| 112 | |
| 113 | ### GitHub Actions Setup |
| 114 | |
| 115 | 1. **Add Repository Secrets** (Settings > Secrets and variables > Actions): |
| 116 | - `APP_STORE_CONNECT_API_KEY_ID` - API Key ID |
| 117 | - `APP_STORE_CONNECT_API_ISSUER_ID` - Issuer ID |
| 118 | - `APP_STORE_CONNECT_API_KEY_CONTENT` - Private key (.p8 content) |
| 119 | - `CERTIFICATE_P12` - Base64-encoded .p12 certificate |
| 120 | - `CERTIFICATE_PASSWORD` - Certificate password |
| 121 | - `PROVISIONING_PROFILE` - Base64-encoded provisioning profile |
| 122 | |
| 123 | 2. **Create App Store Connect API Key**: |
| 124 | - Go to App Store Connect > Users and Access > Keys |
| 125 | - Generate API Key with "App Manager" role |
| 126 | - Download the .p8 file (only available once) |
| 127 | |
| 128 | 3. **Export Certificate**: |
| 129 | ```bash |
| 130 | # Export from Keychain as .p12, then base64 encode |
| 131 | base64 -i certificate.p12 | pbcopy |
| 132 | ``` |
| 133 | |
| 134 | ### Xcode Cloud Setup |
| 135 | |
| 136 | 1. **Enable Xcode Cloud** in Xcode: |
| 137 | - Product > Xcode Cloud > Create Workflow |
| 138 | - Connect to App Store Connect |
| 139 | |
| 140 | 2. **Configure Workflow**: |
| 141 | - Set start conditions (branch, PR, tag) |
| 142 | - Configure environment variables |
| 143 | - Set up post-actions (TestFlight, App Store) |
| 144 | |
| 145 | 3. **Add ci_scripts** to repository for customization |
| 146 | |
| 147 | ### fastlane Setup |
| 148 | |
| 149 | 1. **Install fastlane**: |