-
Notifications
You must be signed in to change notification settings - Fork 16
[#581] Update the Tuist to the latest version #589
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: bug/587-ci-cd-workflows-failed-due-to-deprecated-github-actions
Are you sure you want to change the base?
[#581] Update the Tuist to the latest version #589
Conversation
WalkthroughThis pull request upgrades Tuist from version 3.2.0 to 4.110.3 and migrates the project from CocoaPods to Swift Package Manager (SPM). UIKit interface support has been removed entirely, leaving only SwiftUI. GitHub Actions workflows are updated to newer action versions, Firebase Crashlytics integration is removed, and build configuration is adjusted for the new dependency management approach. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Areas requiring extra attention:
Poem
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
54d9c5c to
2c1de03
Compare
- Update other gems - Finish SwiftUI/SPM migration and cleanup - drop leftover UIKit helpers and simplify Sourcery template - move Tuist packages into Project.swift and switch targets to `.package` - remove workspace deletion; open project directly; add documentation for dependencies - clean README/wiki/CI configs to reflect SwiftUI + SPM-only setup - delete CocoaPods gems/steps, adjust Danger/Fastlane scripts, update Fastlane constants - remove Podfiles, UIKit files, and add guidance for Crashlytics upload script Remove interface - Add a step to use mise (jdx/mise-action@v3) to install tuist 4.110.3 in all GitHub Actions workflows Set the project path to Fastlane build Remove test_install_script Configure Fastlane setting timeour and retries Remove upload symbol
165843e to
a3bef6a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (6)
.github/self_hosted_project_workflows/automatic_pull_request_review.yml (1)
41-51: Remove CocoaPods caching and installation steps—incompatible with SPM project.Lines 41–51 contain CocoaPods cache and pod install steps that reference a non-existent
Podfile.lock. The repository uses SPM (Package.swift exists) and has no CocoaPods configuration. These steps will fail on self-hosted runners and should be removed or replaced with SPM-appropriate alternatives (e.g., caching the.builddirectory).This issue also exists in
.github/project_workflows/automatic_pull_request_review.ymland should be removed from both files.Remove the CocoaPods steps:
- - name: Cache Pods - uses: actions/cache@v4 - id: cocoapodCache - with: - path: Pods - key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }} - restore-keys: | - ${{ runner.os }}-pods- - - - name: Install Pods Dependencies - run: bundle exec pod install.github/project_workflows/automatic_pull_request_review.yml (1)
41-51: Remove CocoaPods caching and installation steps—incompatible with Tuist/SPM project setup.The project documentation (PROJECT_README.md) shows dependencies are now managed via
tuist generate, not CocoaPods. Lines 41–51 reference outdated CocoaPods workflows (Podfile.lock and pod install) that no longer exist in this Tuist-based project. The workflow will fail attempting to cache and install non-existent Pod dependencies.Remove these steps:
- - name: Cache Pods - uses: actions/cache@v4 - id: cocoapodCache - with: - path: Pods - key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }} - restore-keys: | - ${{ runner.os }}-pods- - - - name: Install Pods Dependencies - run: bundle exec pod installIf Tuist build caching is needed, add a
.builddirectory cache step instead.Minor: Line 21 has a typo—
bunlderCacheshould bebundlerCache..github/self_hosted_project_workflows/deploy_staging_firebase.yml (1)
23-39: Remove CocoaPods caching and installation from staging Firebase workflowThis workflow retains CocoaPods cache and install steps (lines 72–82) despite the template now generating SPM-only projects. With
Podfile.lockno longer present, the cache key will not resolve andbundle exec pod installwill fail. Remove:
- Lines 72–80: Cache Pods step
- Lines 81–82: Install Pods Dependencies step
.github/self_hosted_project_workflows/deploy_production_firebase.yml (1)
23-39: Self-hosted production workflow still depends on CocoaPods while template is SPM-onlyThe action version bumps are correct, but this workflow still caches
PodsusingPodfile.lock(lines 66-73) and runsbundle exec pod install(line 76).Since the template no longer generates Podfiles and is documented as SPM-only, these steps will break for new projects—the cache will always miss due to missing
Podfile.lock, andpod installwill fail. Replace these with SPM-aware caching (e.g.,.buildor DerivedData) or remove them entirely if Fastlane lanes already handle SPM resolution.This issue appears in all self-hosted workflows:
deploy_staging_firebase.yml,deploy_app_store.yml, andautomatic_pull_request_review.yml..github/self_hosted_project_workflows/deploy_app_store.yml (1)
25-43: App Store self‑hosted workflow still contains CocoaPods assumptionsThis workflow caches
Podsbased onPodfile.lock(lines 62–70) and runsbundle exec pod install(line 72). Once projects are generated as SPM-only, these steps will fail or be redundant since there will be no Podfile to operate on. Align this workflow with the SPM setup by removing CocoaPods steps and replacing with SPM/DerivedData caching if needed.The same issue appears across multiple workflows:
deploy_staging_firebase.yml:82,deploy_production_firebase.yml:76, andautomatic_pull_request_review.yml:51..github/project_workflows/deploy_production_firebase.yml (1)
72-83: Remove CocoaPods steps from all workflows.The "Cache Pods" (lines 72-73) and "Install Pods Dependencies" (lines 82-83) steps will fail because Podfile and the Pods directory have been removed. These steps also appear in
deploy_staging_firebase.yml,deploy_app_store.yml,automatic_pull_request_review.yml, and theirself_hosted_project_workflowsequivalents—all require removal to complete the CocoaPods-to-SPM migration.
🧹 Nitpick comments (9)
fastlane/Helpers/Symbol.swift (1)
9-11: Empty file does not preserve API; consider a deprecated stub Symbol helperRight now the file only contains comments, so any existing
Symbol.uploadToCrashlyticsusages in customized Fastlane Swift code will fail to compile. If you truly want to “avoid breaking existing references”, consider re‑adding a minimal deprecated stub:+enum Symbol { + @available(*, deprecated, message: "Crashlytics symbol upload is handled by Firebase’s SPM run script. Remove this call.") + static func uploadToCrashlytics(environment: Constant.Environment) { + // Intentionally left blank (no-op) or call fatalError to surface misuse. + } +}This keeps the API surface while steering users toward the new Crashlytics integration.
.github/project_workflows/automatic_pull_request_review.yml (1)
20-20: Typo in cache step ID: "bunlderCache" should be "bundlerCache".This does not affect functionality but inconsistent naming. Consider fixing for consistency.
- id: bunlderCache + id: bundlerCache.github/self_hosted_project_workflows/automatic_pull_request_review.yml (1)
20-20: Typo in cache step ID: "bunlderCache" should be "bundlerCache".Identical to the public-facing workflow. Consider fixing for consistency across workflows.
- id: bunlderCache + id: bundlerCacheProject.swift (1)
15-31: SPM package list looks good; consider guarding against drift with root Package.swiftThe
packageslist andTarget.makeTargetswiring are consistent with the SPM migration, but the same dependencies (and versions) are now declared in three places: this file,Package.swift, andPackage.resolved. It’s easy for one of them to diverge during future bumps.I’d suggest at least adding a small note here (or a helper) to make that coupling explicit and reduce surprises when updating dependencies later.
- packages: [ + packages: [ + // NOTE: Keep this list in sync with root `Package.swift` and `Package.resolved`. // Backend .package(url: "https://github.com/Alamofire/Alamofire.git", from: "5.8.0"),Also applies to: 36-40
Package.swift (1)
1-37: Root Package.swift is well-structured; monitor NimbleExtension for future tag releasesThis manifest cleanly centralizes your SPM dependencies and follows the Tuist integration pattern. The NimbleExtension dependency is currently pinned to the
masterbranch with a specific revision, which provides reasonable stability. However, if this package eventually publishes version tags, consider migrating from branch-based pinning to a semver requirement for more predictable dependency resolution..github/workflows/test_upload_build_to_firebase.yml (1)
58-59: Consider adding SPM cache for build performance.The
test_upload_build_to_test_flight.ymlworkflow includes a "Cache SPM Packages" step caching.buildwith key based onPackage.resolved. This workflow would benefit from the same caching strategy for consistency and faster builds.- name: Install tools with mise uses: jdx/mise-action@v3 + - name: Cache SPM Packages + uses: actions/cache@v4 + id: spmCache + with: + path: .build + key: ${{ runner.os }}-spm-${{ hashFiles('**/Package.resolved') }} + restore-keys: | + ${{ runner.os }}-spm- + - name: Start Install Script for Template AppScripts/Swift/iOSTemplateMaker/Sources/iOSTemplateMaker/SetUpInterface.swift (1)
5-22: Consider simplifying or removing theInterfaceenum.With only
.swiftUIremaining and theinitaccepting empty strings as valid, the enum provides limited value. The validation logic (returningnilfor unrecognized input) is defensive but may be unnecessary if the interface is always hardcoded to.swiftUIin callers.If you want to retain extensibility for future interfaces, keep the current structure. Otherwise, consider inlining the folder name directly in
perform():- enum Interface: Titlable, CaseIterable { - case swiftUI - - init?(_ name: String) { - let name = name.lowercased() - if name == "s" || name == "swiftui" || name.isEmpty { - self = .swiftUI - } else { - return nil - } - } - - var folderName: String { - return "SwiftUI" - } - - var title: String { folderName } - } + private let interfaceFolderName = "SwiftUI".github/wiki/Project-Dependencies.md (1)
30-30: Minor style improvement for sentence variety.The static analysis tool flagged three successive sentences beginning with the same word. Consider rewording for better flow.
-[SwiftLint](https://github.com/realm/SwiftLint) is used to enforce our team's code convention. SwiftLint is the perfect tool for this task as it is customizable, lightweight, and automate-able. CI installs SwiftLint via Homebrew, and Danger runs it directly (no Pods required). +[SwiftLint](https://github.com/realm/SwiftLint) enforces our team's code convention. This tool is perfect for the task as it is customizable, lightweight, and automate-able. CI installs it via Homebrew, and Danger runs it directly (no Pods required).Scripts/Swift/iOSTemplateMaker/Sources/iOSTemplateMaker/SetUpiOSProject.swift (1)
188-245: Consider reducing verbose debug output for cleaner logs.The extensive debug logging is helpful during development but may be excessive for normal usage. Consider:
- Guarding verbose output behind a
--verboseflag, or- Reducing to essential status messages only.
For example, the pre/post-generation file existence checks (lines 195-199, 224-228) and ProjectDescriptionHelpers file listing (lines 206-213) could be removed or made conditional:
- // Check files before generation - let projectSwiftExists = fileManager.fileExists(atPath: "Project.swift") - let tuistHelpersExists = fileManager.fileExists(atPath: "Tuist/ProjectDescriptionHelpers") - print("🔍 Pre-generation check:") - print(" Project.swift exists: \(projectSwiftExists)") - print(" Tuist/ProjectDescriptionHelpers exists: \(tuistHelpersExists)") - - // Clean Tuist cache if it exists (might help with compilation issues) - print("🧹 Cleaning Tuist cache...") - let _ = try? safeShell("tuist clean") - - // List ProjectDescriptionHelpers files for debugging - if tuistHelpersExists { - print("📁 ProjectDescriptionHelpers files:") - if let helpersFiles = try? fileManager.contentsOfDirectory(atPath: "Tuist/ProjectDescriptionHelpers") { - for file in helpersFiles.sorted() { - print(" - \(file)") - } - } - } + let _ = try? safeShell("tuist clean")
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
Gemfile.lockis excluded by!**/*.lock
📒 Files selected for processing (60)
.arkana.yml(1 hunks).github/project_workflows/add_device_profile.yml(1 hunks).github/project_workflows/automatic_pull_request_review.yml(2 hunks).github/project_workflows/create_release_pull_request_and_bump_version.yml(2 hunks).github/project_workflows/deploy_app_store.yml(4 hunks).github/project_workflows/deploy_production_firebase.yml(4 hunks).github/project_workflows/deploy_staging_firebase.yml(4 hunks).github/self_hosted_project_workflows/automatic_pull_request_review.yml(2 hunks).github/self_hosted_project_workflows/deploy_app_store.yml(4 hunks).github/self_hosted_project_workflows/deploy_production_firebase.yml(4 hunks).github/self_hosted_project_workflows/deploy_staging_firebase.yml(4 hunks).github/wiki/Bitrise.md(3 hunks).github/wiki/CodeMagic.md(2 hunks).github/wiki/Github-Actions.md(1 hunks).github/wiki/Project-Dependencies.md(2 hunks).github/workflows/cleanup_cache.yml(1 hunks).github/workflows/test_swiftui_install_script.yml(0 hunks).github/workflows/test_uikit_install_script.yml(0 hunks).github/workflows/test_upload_build_to_firebase.yml(3 hunks).github/workflows/test_upload_build_to_test_flight.yml(3 hunks).gitignore(1 hunks).mise.toml(1 hunks).tuist-version(1 hunks)Dangerfile(3 hunks)Gemfile(0 hunks)PROJECT_README.md(1 hunks)Package.resolved(1 hunks)Package.swift(1 hunks)Project.swift(1 hunks)README.md(2 hunks)Scripts/Swift/iOSTemplateMaker/Sources/iOSTemplateMaker/SetUpInterface.swift(2 hunks)Scripts/Swift/iOSTemplateMaker/Sources/iOSTemplateMaker/SetUpiOSProject.swift(5 hunks)Scripts/Swift/iOSTemplateMaker/Sources/iOSTemplateMaker/iOSTemplateMaker.swift(1 hunks)Tuist/Interfaces/SwiftUI/Project/Podfile(0 hunks)Tuist/Interfaces/UIKit/Project/.sourcery.yml(0 hunks)Tuist/Interfaces/UIKit/Project/Podfile(0 hunks)Tuist/Interfaces/UIKit/Sources/Application/AppDelegate.swift(0 hunks)Tuist/Interfaces/UIKit/Sources/Presentation/Modules/HomeViewController.swift(0 hunks)Tuist/Interfaces/UIKit/Sources/Presentation/Navigator/Navigator+Scene.swift(0 hunks)Tuist/Interfaces/UIKit/Sources/Presentation/Navigator/Navigator+Transition.swift(0 hunks)Tuist/Interfaces/UIKit/Sources/Presentation/Navigator/Navigator.swift(0 hunks)Tuist/ProjectDescriptionHelpers/BuildConfiguration.swift(1 hunks)Tuist/ProjectDescriptionHelpers/Constant.swift(0 hunks)Tuist/ProjectDescriptionHelpers/Module.swift(0 hunks)Tuist/ProjectDescriptionHelpers/Scheme+Initializing.swift(1 hunks)Tuist/ProjectDescriptionHelpers/Target+Initializing.swift(1 hunks)Tuist/ProjectDescriptionHelpers/TargetScript+Initializing.swift(0 hunks)Workspace.swift(0 hunks)bitrise.yml(1 hunks)codemagic.yaml(0 hunks)fastlane/Constants/Constant.swift(1 hunks)fastlane/Fastfile.swift(0 hunks)fastlane/Helpers/Build.swift(2 hunks)fastlane/Helpers/Symbol.swift(1 hunks)fastlane/Helpers/Test.swift(1 hunks)tools/sourcery/templates/AutoMockable.stencil(0 hunks){PROJECT_NAME}/Sources/Constants/Constants+API.swift(0 hunks){PROJECT_NAME}/Sources/Supports/Extensions/UIKit/Color+Application.swift(0 hunks){PROJECT_NAME}/Sources/Supports/Extensions/UIKit/UIView+Subviews.swift(0 hunks){PROJECT_NAME}/Sources/Supports/Helpers/Typealiases/Typealiases.swift(0 hunks)
💤 Files with no reviewable changes (22)
- Tuist/Interfaces/UIKit/Sources/Presentation/Navigator/Navigator+Transition.swift
- .github/workflows/test_uikit_install_script.yml
- Tuist/Interfaces/UIKit/Sources/Presentation/Modules/HomeViewController.swift
- Tuist/Interfaces/UIKit/Project/.sourcery.yml
- Tuist/ProjectDescriptionHelpers/Constant.swift
- fastlane/Fastfile.swift
- {PROJECT_NAME}/Sources/Supports/Extensions/UIKit/Color+Application.swift
- tools/sourcery/templates/AutoMockable.stencil
- Tuist/ProjectDescriptionHelpers/TargetScript+Initializing.swift
- {PROJECT_NAME}/Sources/Supports/Helpers/Typealiases/Typealiases.swift
- .github/workflows/test_swiftui_install_script.yml
- codemagic.yaml
- Tuist/Interfaces/SwiftUI/Project/Podfile
- Gemfile
- {PROJECT_NAME}/Sources/Constants/Constants+API.swift
- {PROJECT_NAME}/Sources/Supports/Extensions/UIKit/UIView+Subviews.swift
- Tuist/Interfaces/UIKit/Sources/Presentation/Navigator/Navigator+Scene.swift
- Tuist/Interfaces/UIKit/Sources/Application/AppDelegate.swift
- Tuist/Interfaces/UIKit/Project/Podfile
- Workspace.swift
- Tuist/Interfaces/UIKit/Sources/Presentation/Navigator/Navigator.swift
- Tuist/ProjectDescriptionHelpers/Module.swift
🧰 Additional context used
🧬 Code graph analysis (4)
Scripts/Swift/iOSTemplateMaker/Sources/iOSTemplateMaker/iOSTemplateMaker.swift (1)
fastlane/Helpers/EnvironmentParser.swift (1)
string(17-19)
Scripts/Swift/iOSTemplateMaker/Sources/iOSTemplateMaker/SetUpInterface.swift (1)
Scripts/Swift/iOSTemplateMaker/Sources/iOSTemplateMaker/Extensions/FileManager+Utils.swift (3)
rename(21-27)moveFiles(5-19)removeItems(48-51)
Project.swift (3)
Tuist/ProjectDescriptionHelpers/BuildConfiguration.swift (1)
createConfiguration(32-40)Tuist/ProjectDescriptionHelpers/Target+Initializing.swift (1)
makeTargets(4-9)Tuist/ProjectDescriptionHelpers/Scheme+Initializing.swift (2)
productionScheme(4-16)stagingScheme(18-30)
Scripts/Swift/iOSTemplateMaker/Sources/iOSTemplateMaker/SetUpiOSProject.swift (2)
Scripts/Swift/iOSTemplateMaker/Sources/iOSTemplateMaker/SetUpInterface.swift (1)
perform(26-35)Scripts/Swift/iOSTemplateMaker/Sources/iOSTemplateMaker/Extensions/FileManager+Utils.swift (1)
removeItems(48-51)
🪛 LanguageTool
.github/wiki/Project-Dependencies.md
[style] ~30-~30: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... to enforce our team's code convention. SwiftLint is the perfect tool for this task as it...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
🔇 Additional comments (39)
bitrise.yml (1)
186-186: BITRISE_PROJECT_PATH is correctly set to.xcodeprojfor SPM integration.The change from
.xcworkspaceto.xcodeprojis appropriate for the SPM-only migration. The[email protected]step natively supports SPM package resolution through Xcode's integration, so no additional configuration is needed. This is the correct path for building with SPM dependencies.The current cache configuration at lines 48, 91, 134, and 170 caching
$BITRISE_CACHE_DIRand$GEM_CACHE_PATHis sufficient; Bitrise's cache directory handles derived data and build artifacts.Dangerfile (2)
44-44: LGTM! Correct migration from workspace to project.The change from
workspace:toproject:correctly reflects the migration from CocoaPods (which requires a workspace) to SPM and Tuist 4 (which uses the project directly).
24-24: The{PROJECT_NAME}placeholder will be properly substituted by the iOSTemplateMaker tool. ThereplaceAllOccurrences()method inFileManager+Utils.swiftrecursively processes all text files in the project root (excluding.buildand.pngfiles), replacing the placeholder across all occurrences including the Dangerfile.Tuist/ProjectDescriptionHelpers/BuildConfiguration.swift (1)
21-28: Nice formatting improvement.The switch statement is now properly formatted with consistent multi-line indentation, which improves readability and aligns with modern Swift conventions. The file already uses Tuist 4-compatible API patterns (static factory methods for
ConfigurationName.configuration(),Configuration.debug(), andConfiguration.release()), so no API breaking changes are present. No behavioral changes.fastlane/Helpers/Test.swift (1)
16-25: xcbeautify formatter path change is appropriate post‑CocoaPods removalUsing
"xcbeautify"directly instead of the Pods path matches the move away from CocoaPods; behavior is fine as long asxcbeautifyis installed and onPATHin all CI environments (GitHub Actions, Bitrise, CodeMagic).fastlane/Constants/Constant.swift (1)
74-82: Constants remain consistent; doc comment is helpful
projectNameremains the same placeholder, and the newdSYMSuffixcomment correctly documents howdsymPathis formed. No functional issues here.fastlane/Helpers/Build.swift (1)
42-62: Explicit project path + formatter change look good; verify alignment with generated projectAdding
project: .userDefined(Constant.projectPath)is a good move now that Pods/xcworkspace are gone, assuming Tuist/SPM consistently generates./{PROJECT_NAME}.xcodeproj. The formatter change to"xcbeautify"matches the test helper.Please double‑check:
- The actual generated Xcode file name/extension matches
Constant.projectPath.xcbeautifyis installed and available onPATHin all CI providers you support..arkana.yml (1)
1-1: LGTM – Arkana configuration correctly updated for SPM.The package manager migration from CocoaPods to SPM aligns with the PR's dependency management overhaul.
.gitignore (1)
69-69: LGTM – Gitignore updated appropriately for Tuist 4 and SPM.The addition of
*.xcworkspacein the Tuist section is correct; Tuist 4 generates these files and they should not be committed. The implicit removal of the Pods directory from gitignore aligns with the SPM migration..github/project_workflows/add_device_profile.yml (1)
33-33: LGTM – GitHub Actions version upgrade is safe and current.Checkout@v6 maintains backward compatibility with fetch-depth: 0 and other parameters. No workflow logic changes needed.
.github/project_workflows/create_release_pull_request_and_bump_version.yml (1)
22-22: LGTM – GitHub Actions version upgrades are safe and current.Checkout@v6 maintains backward compatibility with all existing parameters including
fetch-depth: 0and branch refs. No workflow logic adjustments needed.Also applies to: 59-59
PROJECT_README.md (1)
18-18: LGTM – README correctly documents the new setup flow.The documentation update from
pod installtotuist generatereflects the SPM migration and Tuist 4's project generation model. Developers will now run the correct command to set up dependencies..github/workflows/cleanup_cache.yml (1)
12-12: LGTM – GitHub Actions version upgrade is safe and current.Checkout@v6 maintains backward compatibility. No workflow logic changes needed.
README.md (1)
14-30: README messaging for Tuist 4 + SwiftUI + SPM looks coherentThe new intro, requirements, “What’s inside” section, and the extra step about opening the generated
.xcodeprojall align with the SwiftUI‑only / SPM‑only direction of the template. No changes needed from my side here.Also applies to: 39-40
Package.resolved (1)
1-248: Pinned SPM dependencies look fineThe resolved versions are consistent with the declared constraints and having this file checked in makes sense for deterministic template builds. No issues from my side.
Tuist/ProjectDescriptionHelpers/Target+Initializing.swift (1)
4-8: Verify JSONAPIMapper product name export; test bundle ID is unconventionalThe new
makeTargetsand target configuration align well with Tuist 4 and SPM setup. Two points to confirm:
JSONAPIMapper product name: The main target depends on
.package(product: "JSONAPIMapper")(line 26), but the package repository isnimblehq/JSONMapper. Confirm that"JSONAPIMapper"is the correct product name exported by that package in itsPackage.swift; if it exports a different product name (e.g.,"JSONMapper"), this will cause resolution failures duringtuist generateor build time.Test bundle identifier (line 47):
testsTargetcurrently passes the samebundleIdparameter as the app target. It's more conventional to give the test bundle its own ID, e.g.\(bundleId).tests, for clarity in build logs and tooling. Optional improvement:fileprivate static func testsTarget(name: String, bundleId: String) -> Target { let targetName = "\(name)Tests" + let testsBundleId = "\(bundleId).tests" return .target( name: targetName, destinations: .iOS, product: .unitTests, - bundleId: bundleId, + bundleId: testsBundleId,Tuist/ProjectDescriptionHelpers/Scheme+Initializing.swift (2)
8-15: LGTM! Scheme generation simplified.The refactored scheme generation directly references test targets and streamlines the action configuration, making the code more maintainable.
22-29: LGTM! Consistent simplification.The staging scheme follows the same simplified pattern as the production scheme, ensuring consistency across build configurations.
.mise.toml (1)
1-4: LGTM! Mise configuration added.The Tuist version pin (4.110.3) correctly aligns with the updated .tuist-version file and the PR's upgrade objective.
.tuist-version (1)
1-1: LGTM! Tuist upgraded to 4.110.3.The version upgrade from 3.2.0 to 4.110.3 fulfills the primary objective of this PR.
.github/wiki/CodeMagic.md (2)
12-12: LGTM! Documentation updated for SPM migration.The workflow step description correctly reflects the migration from CocoaPods to Swift Package Manager.
55-55: LGTM! Project structure updated.The change from
.xcworkspaceto.xcodeprojaligns with the SPM migration, as SPM doesn't require a workspace file..github/project_workflows/deploy_production_firebase.yml (3)
23-23: LGTM! GitHub Actions checkout upgraded.The upgrade to
actions/checkout@v6ensures compatibility with the latest GitHub Actions features.Also applies to: 42-42
73-73: LGTM! Cache action upgraded.The upgrade to
actions/cache@v4is appropriate for improved caching performance.
99-99: LGTM! Artifact upload action upgraded.The upgrade to
actions/upload-artifact@v4ensures compatibility with the latest artifact handling features..github/wiki/Bitrise.md (2)
12-12: LGTM! Bitrise workflow documentation updated.The workflow step description correctly reflects the migration from CocoaPods to Swift Package Manager.
29-29: LGTM! Project structure documentation updated.The changes from
.xcworkspaceto.xcodeprojalign with the SPM migration and correctly document the new project structure.Also applies to: 65-65
.github/wiki/Github-Actions.md (1)
33-33: LGTM! Dependency installation documentation updated.The updated descriptions correctly reflect the migration from CocoaPods to SPM and the new dependency resolution workflow using Bundler and Tuist/Xcode.
Also applies to: 40-40
Scripts/Swift/iOSTemplateMaker/Sources/iOSTemplateMaker/iOSTemplateMaker.swift (1)
31-38: Interface parameter successfully removed; SwiftUI now hardcoded as default.The
SetUpIOSProjectinitializer has been correctly updated to remove the interface parameter. The current signature accepts onlybundleIdProduction,bundleIdStaging,projectName, andminimumVersion. SwiftUI is now hardcoded as the default interface in theSetUpInterface().perform(.swiftUI, projectName)call, aligning with the PR's objective to deprecate UIKit templates..github/workflows/test_upload_build_to_firebase.yml (1)
21-23: LGTM! Good addition of Fastlane timeout settings.These environment variables help prevent flaky builds by allowing xcodebuild settings retrieval to retry on transient failures.
.github/project_workflows/deploy_staging_firebase.yml (1)
78-89: CocoaPods steps remain while PR migrates to SPM.This workflow still caches Pods and runs
pod install, but the PR is migrating from CocoaPods to Swift Package Manager. If this template is intended for new projects using SPM, these steps should be replaced with SPM caching similar totest_upload_build_to_test_flight.yml.If this is intentional (e.g., template for legacy CocoaPods projects), please clarify. Otherwise, consider applying this diff:
- - name: Cache Pods + - name: Cache SPM Packages uses: actions/cache@v4 - id: cocoapodCache + id: spmCache with: - path: Pods - key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }} + path: .build + key: ${{ runner.os }}-spm-${{ hashFiles('**/Package.resolved') }} restore-keys: | - ${{ runner.os }}-pods- - - - name: Install Pods Dependencies - run: bundle exec pod install - shell: bash + ${{ runner.os }}-spm-.github/project_workflows/deploy_app_store.yml (2)
62-73: CocoaPods steps remain while PR migrates to SPM.Same concern as
deploy_staging_firebase.yml— this workflow still uses Pods caching andpod install. If the template is moving to SPM, these should be updated accordingly. See the suggested diff in the review comment fordeploy_staging_firebase.yml.
24-27: Action version upgrades look good.Checkout action upgraded to v6 consistently across both jobs.
Also applies to: 38-42
Scripts/Swift/iOSTemplateMaker/Sources/iOSTemplateMaker/SetUpInterface.swift (1)
26-35: LGTM! Clean file operations for SwiftUI setup.The flow correctly renames the app file, moves sources to the project directory, and cleans up the Interfaces directory.
.github/workflows/test_upload_build_to_test_flight.yml (2)
44-51: LGTM! Proper SPM caching implementation.The cache configuration correctly targets
.builddirectory and usesPackage.resolvedfor the cache key, which will properly invalidate when dependencies change.
13-14: Good decision to make TestFlight uploads manual-only.Disabling automatic triggers and requiring
workflow_dispatchprevents accidental TestFlight uploads on every PR, which could exhaust review quotas or cause confusion..github/wiki/Project-Dependencies.md (1)
6-6: LGTM! Documentation accurately reflects the SPM migration.The description correctly notes that SPM is now the single source of truth for runtime dependencies.
Scripts/Swift/iOSTemplateMaker/Sources/iOSTemplateMaker/SetUpiOSProject.swift (2)
45-47: LGTM! Clean hardcoding of SwiftUI interface.With UIKit support removed, hardcoding
.swiftUIis the correct approach.
277-283: LGTM! Correctly opens.xcodeprojfor SPM-integrated projects.With Tuist 4's native SPM integration, opening the project file directly is correct since there's no separate workspace for Pods.
| swiftformat.binary_path = 'swiftformat' | ||
| swiftformat.exclude = %w(**/*generated.swift) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
# Find CI configuration files
fd -e yaml -e yml -e sh | grep -E '(\.github|\.circleci|bitrise|codemagic)' | head -20Repository: nimblehq/ios-templates
Length of output: 92
🏁 Script executed:
# Search for CI workflow patterns
rg -l 'workflow|jobs|steps|script' --type=yaml | head -20Repository: nimblehq/ios-templates
Length of output: 212
🏁 Script executed:
# Read the Dangerfile to understand the context
cat -n Dangerfile | head -50Repository: nimblehq/ios-templates
Length of output: 1909
🏁 Script executed:
# Search for swiftformat and swiftlint references in CI/workflow files
rg 'swiftformat|swiftlint' --type=yaml -B2 -A2Repository: nimblehq/ios-templates
Length of output: 168
🏁 Script executed:
# Search for tool installation patterns (mint, brew, etc.)
rg 'mint install|brew install|setup.*swift|SPM|cocoapods' --type=yaml -B2 -A2Repository: nimblehq/ios-templates
Length of output: 168
🏁 Script executed:
# Read bitrise.yml to check tool installation
cat -n bitrise.yml | head -100Repository: nimblehq/ios-templates
Length of output: 3572
🏁 Script executed:
# Read codemagic.yaml to check tool installation
cat -n codemagic.yaml | head -100Repository: nimblehq/ios-templates
Length of output: 3819
🏁 Script executed:
# Check if Dangerfile is a template file (cookiecutter patterns)
rg 'cookiecutter|PROJECT_NAME' DangerfileRepository: nimblehq/ios-templates
Length of output: 212
🏁 Script executed:
# Check for Gemfile or other dependency files that might install Danger plugins
cat Gemfile 2>/dev/null || echo "No Gemfile found"Repository: nimblehq/ios-templates
Length of output: 373
🏁 Script executed:
# Check if there are any installation instructions in README or docs
fd -e md | xargs rg -l 'swiftformat|swiftlint|setup|install' 2>/dev/null | head -5Repository: nimblehq/ios-templates
Length of output: 93
🏁 Script executed:
# Check full bitrise.yml for bundle install or gem installation
rg 'bundle|gem' bitrise.yml -B2 -A2Repository: nimblehq/ios-templates
Length of output: 48
🏁 Script executed:
# Check README for tool setup instructions
cat README.md | grep -A20 -B2 'setup\|install\|swift' | head -50Repository: nimblehq/ios-templates
Length of output: 1569
🏁 Script executed:
# Verify if Dangerfile is indeed a template file
file Dangerfile && head -5 DangerfileRepository: nimblehq/ios-templates
Length of output: 110
Verify swiftformat and swiftlint are installed in CI environments.
The binary paths for SwiftFormat and SwiftLint (lines 10, 15) reference external CLI tools that must be available in the system PATH. The Gemfile includes the Danger wrapper gems (danger-swiftformat, danger-swiftlint), but these gems require the actual swiftformat and swiftlint binaries to be pre-installed. Ensure these tools are installed as part of your CI setup—neither bitrise.yml nor codemagic.yaml shows explicit installation steps for these binaries. Consider adding installation commands (e.g., via Homebrew, mint, or direct download) to your CI workflows.
🤖 Prompt for AI Agents
In Dangerfile around lines 10 to 11, the Danger config references external
swiftformat and swiftlint binaries but the CI configs do not install those
tools; update the CI pipelines (bitrise.yml and codemagic.yaml) to install and
put swiftformat and swiftlint on PATH before running Danger (examples: install
via Homebrew, mint, or download and place in PATH), pin desired versions, verify
installation with a quick --version check, and fail the build early with a clear
message if the binaries are missing so Danger’s swiftformat/swiftlint wrappers
will run reliably.
| try fileManager.removeItems(in: ".tuist-version") | ||
| try fileManager.removeItems(in: "tuist") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check if tuist or Tuist directory exists in the template
fd -t d -d 1 '^[Tt]uist$'Repository: nimblehq/ios-templates
Length of output: 72
🏁 Script executed:
#!/bin/bash
# Search for references to tuist or Tuist in Swift files to understand expected paths
rg -i 'tuist' --type swift -A 2 -B 2 | head -100Repository: nimblehq/ios-templates
Length of output: 10683
🏁 Script executed:
#!/bin/bash
# Check the SetUpiOSProject.swift file to see the context around lines 260-261
sed -n '250,270p' Scripts/Swift/iOSTemplateMaker/Sources/iOSTemplateMaker/SetUpiOSProject.swiftRepository: nimblehq/ios-templates
Length of output: 948
Change tuist to Tuist on line 261 to match the actual directory structure.
The repository uses Tuist/ (capitalized) throughout the codebase, as confirmed by the actual directory structure and all other references in SetUpInterface.swift and SetUpiOSProject.swift. Line 261 should remove Tuist instead of tuist to properly clean up the template files.
🤖 Prompt for AI Agents
In Scripts/Swift/iOSTemplateMaker/Sources/iOSTemplateMaker/SetUpiOSProject.swift
around lines 260 to 261, the cleanup currently attempts to remove "tuist"
(lowercase) but the actual directory is "Tuist" (capitalized); update the second
removeItems call to target "Tuist" instead of "tuist" so the correct directory
is removed (and ensure casing matches other references in the repo).
What happened 👀
This PR represents a major architectural overhaul of the iOS Template. It migrates the tooling from Tuist 3 to Tuist 4, completely removes CocoaPods in favor of Swift Package Manager (SPM), and deprecates the UIKit interface to focus exclusively on SwiftUI.
Key Changes:
.tuist-versionto4.110.3and refactoredProject.swiftto use the latestProjectDescriptionsyntax.Podfileand CocoaPods integration.Package.swiftto manage dependencies (Alamofire, Kingfisher, Firebase, etc.) via SPM.Arkanaconfiguration to use SPM logic.UIKittemplates, ViewControllers, and Storyboard logic.iOSTemplateMakerscript to default to SwiftUI and remove the interface selection prompt.checkout@v6,cache@v4) to support Node 20.pod installsteps from workflows (Bitrise, CodeMagic, GitHub Actions)..build(SPM) directories.test_uikit_install_script), extensions, and helpers related to the legacy setup.Insight 📝
Why this solution?
The iOS ecosystem has shifted significantly. UIKit is now considered legacy for new greenfield projects, and CocoaPods is in maintenance mode. By moving to a SwiftUI + SPM + Tuist 4 stack, we ensure the template generates modern, future-proof projects that are faster to build and easier to maintain.
Architecture Shift:
Previously, Tuist generated a project that relied on a separate
pod installstep to link binary frameworks. Now, Tuist manages the SPM graph directly, integrating dependencies as native targets within the Xcode project structure.Refactoring Highlights:
Project.swift: Now defines dependencies using.package(url: ...)syntax.Fastlane: Updated to invoke tools likexcbeautifydirectly from the local environment or Mint/SPM, rather than relying on a Pod-installed binary.Proof Of Work 📹
Test upload build to firebase successfully now Result
Summary by CodeRabbit
Release Notes
New Features
Improvements
tuist generateinstead of CocoaPods installation.✏️ Tip: You can customize this high-level summary in your review settings.