diff --git a/ios-spm-app-packaging/assets/templates/bootstrap/Gemfile b/ios-spm-app-packaging/assets/templates/bootstrap/Gemfile new file mode 100644 index 0000000..7a118b4 --- /dev/null +++ b/ios-spm-app-packaging/assets/templates/bootstrap/Gemfile @@ -0,0 +1,3 @@ +source "https://rubygems.org" + +gem "fastlane" diff --git a/ios-spm-app-packaging/assets/templates/fastlane/Appfile b/ios-spm-app-packaging/assets/templates/fastlane/Appfile new file mode 100644 index 0000000..4ba1ec4 --- /dev/null +++ b/ios-spm-app-packaging/assets/templates/fastlane/Appfile @@ -0,0 +1,9 @@ +# App identifier and Apple ID +app_identifier("com.example.myapp") +apple_id("your@email.com") + +# Team ID from Apple Developer portal +team_id("XXXXXXXXXX") + +# App Store Connect team (if different) +# itc_team_id("XXXXXXXXXX") diff --git a/ios-spm-app-packaging/assets/templates/fastlane/Fastfile b/ios-spm-app-packaging/assets/templates/fastlane/Fastfile new file mode 100644 index 0000000..d0c248a --- /dev/null +++ b/ios-spm-app-packaging/assets/templates/fastlane/Fastfile @@ -0,0 +1,56 @@ +opt_out_usage +default_platform(:ios) + +platform :ios do + desc "Lint code with SwiftLint" + lane :lint do + swiftlint(mode: :lint, strict: true, reporter: "xcode") + end + + desc "Build and upload to TestFlight" + lane :beta do + # match(type: "appstore") + sh "cd .. && tuist generate" + build_app(scheme: "MyApp", configuration: "Release", export_method: "app-store") + upload_to_testflight(skip_waiting_for_build_processing: true) + end + + desc "CI build without signing" + lane :ci do + sh "cd .. && tuist generate" + sh "cd .. && SKIP_SIGNING=1 Scripts/archive.sh" + end + + desc "Build for simulator" + lane :build do + sh "cd .. && tuist generate" + sh "cd .. && tuist xcodebuild build -scheme MyApp -sdk iphonesimulator -configuration Debug" + end + + desc "Create GitHub release with IPA" + lane :release do |options| + version = options[:version] + UI.user_error!("Version required: fastlane release version:1.2.0") unless version + + sh "cd .. && sed -i '' 's/\"MARKETING_VERSION\": \"[^\"]*\"/\"MARKETING_VERSION\": \"#{version}\"/' Project.swift" + sh "cd .. && tuist generate" + build_app(scheme: "MyApp", configuration: "Release", export_method: "app-store") + + sh "cd .. && git add Project.swift" + sh "cd .. && git commit -m 'Bump version to #{version}' || true" + sh "cd .. && git push" + sh "cd .. && git tag v#{version}" + sh "cd .. && git push origin v#{version}" + + github_release( + api_token: ENV["GITHUB_TOKEN"], + repository_name: ENV["GITHUB_REPOSITORY"], + name: "MyApp #{version}", + tag_name: "v#{version}", + is_generate_release_notes: true, + upload_assets: [lane_context[SharedValues::IPA_OUTPUT_PATH]] + ) + + upload_to_testflight(skip_waiting_for_build_processing: true) if options[:testflight] + end +end diff --git a/ios-spm-app-packaging/references/fastlane.md b/ios-spm-app-packaging/references/fastlane.md new file mode 100644 index 0000000..2c42c7e --- /dev/null +++ b/ios-spm-app-packaging/references/fastlane.md @@ -0,0 +1,161 @@ +# Fastlane integration (optional) + +Fastlane automates signing, building, and uploading to TestFlight/App Store. Use it when you want single-command releases or need automated certificate management. + +## Install + +**Recommended (with Bundler):** +```bash +# Gemfile is in bootstrap/ template +cd MyApp +bundle install +bundle exec fastlane [lane] +``` + +Using Bundler locks dependencies, eliminates startup warnings, and makes Fastlane launch faster. Commit `Gemfile` and `Gemfile.lock` to version control. + +**Alternative (Homebrew):** +```bash +brew install fastlane +fastlane [lane] +``` + +## Initialize in project + +If starting fresh (not using templates): +```bash +cd MyApp +bundle init +echo 'gem "fastlane"' >> Gemfile +bundle install +bundle exec fastlane init +``` + +Select option 4 (manual setup) to avoid overwriting existing configuration. + +## Signing with match + +Tuist defines build settings but doesn't manage certificates. Fastlane's `match` stores signing assets in a private git repo. + +**Setup match:** +```bash +fastlane match init +``` + +**Generate certificates:** +```bash +fastlane match development +fastlane match appstore +``` + +**Use in Fastfile:** +```ruby +lane :beta do + match(type: "appstore") + build_app(scheme: "MyApp", configuration: "Release") + upload_to_testflight +end +``` + +## Minimal Fastfile + +Wraps existing shell scripts: + +```ruby +default_platform(:ios) + +platform :ios do + desc "Build and upload to TestFlight" + lane :beta do + sh "cd .. && tuist generate" + sh "cd .. && Scripts/archive.sh" + sh "cd .. && Scripts/export_ipa.sh" + sh "cd .. && Scripts/upload_testflight.sh" + end + + desc "CI build (no signing)" + lane :ci do + sh "cd .. && tuist generate" + sh "cd .. && SKIP_SIGNING=1 Scripts/archive.sh" + end +end +``` + +## SwiftLint integration + +The included Fastfile has a `lint` lane. See `references/swiftlint.md` for setup. + +## Native Fastlane actions + +Replace shell scripts with native actions for better error handling: + +```ruby +platform :ios do + lane :beta do + # Generate project + sh "cd .. && tuist generate" + + # Build and archive + build_app( + scheme: "MyApp", + configuration: "Release", + export_method: "app-store" + ) + + # Upload to TestFlight + upload_to_testflight( + skip_waiting_for_build_processing: true + ) + end +end +``` + +## Environment variables + +Fastlane reads from `.env` files: + +```bash +# fastlane/.env +APP_IDENTIFIER=com.example.myapp +APPLE_ID=your@email.com +TEAM_ID=XXXXXXXXXX +MATCH_GIT_URL=git@github.com:yourorg/certificates.git +``` + +## CI integration + +For GitHub Actions: + +```yaml +- name: Install Fastlane + run: brew install fastlane + +- name: Run Fastlane + env: + MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} + APP_STORE_CONNECT_API_KEY_ID: ${{ secrets.ASC_KEY_ID }} + APP_STORE_CONNECT_API_KEY_ISSUER_ID: ${{ secrets.ASC_ISSUER_ID }} + APP_STORE_CONNECT_API_KEY_CONTENT: ${{ secrets.ASC_KEY_CONTENT }} + run: fastlane beta +``` + +## GitHub releases + +The included Fastfile has a `release` lane for automated GitHub releases with IPA upload: + +```bash +bundle exec fastlane release version:1.2.0 +bundle exec fastlane release version:1.2.0 testflight:true +``` + +Required environment variables: `GITHUB_TOKEN`, `GITHUB_REPOSITORY`. + +## When to use Fastlane + +| Scenario | Recommendation | +|----------|----------------| +| Solo dev, manual releases | Shell scripts are sufficient | +| Team with shared signing | Use `match` for certificate management | +| CI/CD pipeline | Use Fastlane lanes for reproducibility | +| Frequent TestFlight builds | Fastlane reduces manual steps | +| Automated GitHub releases | Use `release` lane for one-command releases |