* feat: add version management system with build number tracking - Add version.json to track iOS/Android build numbers separately - Create version.cjs script for build number management - Add Fastlane version_manager.rb helper - Keep npm version for semver, version.json for build tracking * feat: integrate version.json with Fastlane deployment process ## What Changed - Updated iOS and Android Fastlane lanes to use version.json for build number management - Added automatic build number increment on deployment - Added deployment timestamp tracking ## How It Works ### iOS Deployment 1. Reads current build number from version.json 2. Increments iOS build number (e.g., 148 → 149) 3. Updates Xcode project with new build number via increment_build_number 4. Proceeds with TestFlight deployment 5. Updates lastDeployed timestamp on successful upload ### Android Deployment 1. Reads current build number from version.json 2. Increments Android build number (e.g., 82 → 83) 3. Updates build.gradle with new version code via increment_version_code 4. Proceeds with Play Store deployment 5. Updates lastDeployed timestamp on successful upload ## Why This Change - Eliminates manual version/build number entry - Prevents version conflicts between deployments - Provides single source of truth for build numbers - Enables automatic deployments without human intervention - Tracks deployment history with timestamps ## Dependencies - Requires version.json file (already created in previous commit) - Uses existing Fastlane plugins: - increment_build_number (iOS - built-in) - increment_version_code (Android - from plugin) - Version numbers still managed by npm version command * feat: enhance deploy confirmation with version.json info * fix: use ENV variable directly in increment_build_number to avoid secret masking * fix: correct xcodeproj path for GitHub Actions workflow * feat: add test mode to workflow for safe testing - Skip store uploads when test_mode is true - Test version bumps and builds without deployment - Prevent accidental pushes to TestFlight/Play Store * fix: use gradle_file_path instead of gradle_file for increment_version_code * fix: use gsub to remove ../ prefix for CI compatibility * chore: remove accidentally committed files - Remove .cursor/mcp.json - Remove .cursorignore - Remove deployment-automation-summary.md - Remove deployment-meeting-questions.md - Remove pipeline.md * feat: auto-commit version.json after successful deployment - Commits version.json changes back to repository - Only runs when test_mode is false - Uses [skip ci] to prevent infinite loops - Checks for actual changes before committing * feat : update package.json in build step using npm version * feat: add comprehensive caching to mobile deployment workflow - Add caching for Yarn dependencies, Ruby gems, CocoaPods, Gradle, and Android NDK - Implement cache versioning strategy for easy cache invalidation - Fix cache order: caches now restored after checkout but before dependency installation - Update mobile-setup action to skip installs when dependencies are cached - Add cache size monitoring to track usage against GitHub's 10GB limit - Fix Slack notification bug: skip notifications in test_mode - Add detailed logging for package.json version updates (show from/to versions) Expected performance improvement: ~50% faster builds (from ~15min to ~7-10min) * fix: move bundler config after Ruby setup in mobile-setup action * fix: rename cache env vars to avoid Yarn conflicts Yarn was interpreting YARN_CACHE_VERSION as its own config setting. Prefixed all cache version env vars with GH_ to avoid conflicts. * fix: remove bundler deployment mode to allow Gemfile updates The deployment mode was causing bundler to fail when Gemfile changed (nokogiri was removed). CI should be able to update the lockfile as needed. * feat: implement strict lock file enforcement (Option 1) - Re-enable bundler deployment mode for strict Gemfile.lock checking - Use yarn install --immutable for strict yarn.lock checking - Add clear error messages when lock files are out of date - Add pre-checks to verify lock files exist - This ensures reproducible builds and makes caching maximally effective When developers change dependencies, they must now: 1. Run yarn install or bundle install locally 2. Commit the updated lock files 3. CI will fail with helpful instructions if they forget * fix: update Gemfile.lock for CI environment Remove nokogiri from Gemfile.lock since it's excluded in CI environments (GITHUB_ACTIONS=true). This allows the strict lock file checks to pass in CI. * fix: correct yarn.lock path for monorepo workspace The project uses Yarn workspaces with yarn.lock at the repository root, not in the app directory. Updated paths to check for yarn.lock at workspace root and use it for cache keys. * fix: handle both boolean and string test_mode parameter The test_mode parameter was only checking for string 'true' but could be passed as boolean true from command line. Now handles both cases to ensure test mode works correctly for iOS and Android. * fix: address code review feedback for mobile deployment workflow - Replace jq with Node.js for version extraction (jq not available on macOS runners) - Fix concurrent commit race condition by creating separate update-version job - Add platform validation to version_manager.rb and version.cjs scripts - Use POSIX-compatible single = for shell string comparisons - Ensure single atomic commit when deploying to both platforms * fix: formatting and linting issues - Remove trailing spaces from workflow YAML file - Fix prettier formatting in JavaScript files - Add -y flag to yarn version command for non-interactive mode - Address all lint warnings from CI * feat: implement automated branch-based mobile deployments - Add mobile-deploy-auto.yml workflow that triggers on PR merges to dev/main - Update mobile-deploy.yml to support workflow_call for reusability - Add deployment_track, version_bump, and auto_deploy parameters - Create new Fastlane lanes (deploy_auto) for iOS and Android - Implement smart version bumping based on PR labels (major/minor/patch) - Add graceful error handling for Play Store permission issues - Enhance Slack notifications with deployment track information This enables automatic deployments when PRs are merged: - dev branch → internal testing track - main branch → production track - Skip deployment with [skip-deploy] in PR or no-deploy label * feat: add automated git tagging and release system - Add automatic git tagging for production deployments (v2.5.5, platform-specific tags) - Create GitHub releases with changelogs for production deployments - Add manual release script (yarn release) for version bumping and tagging - Implement simple changelog generation from git history - Add comprehensive deployment documentation in .github/MOBILE_DEPLOYMENT.md - Update app/README.md with deployment commands and workflows This completes the release automation system requested in the ticket for manual tagging and versioning with automated changelogs and release notes. --------- Co-authored-by: Jayaditya Gupta <nightmare@Jayadityas-MacBook-Pro.local>
5.5 KiB
Mobile Deployment Guide
This guide covers the automated mobile deployment pipeline for iOS and Android apps.
🚀 Quick Start
Automatic Deployments
Deployments happen automatically when PRs are merged:
- Merge to
dev→ Deploy to internal testing - Merge to
main→ Deploy to production
To skip deployment, add [skip-deploy] to your PR title or add the no-deploy label.
Manual Deployments
- Go to Actions → "Mobile App Deployments"
- Click "Run workflow"
- Select options:
- Platform: ios / android / both
- Test mode: Check to build without uploading
- Deployment track: internal / production
- Version bump: build / patch / minor / major
📋 How It Works
Branch Strategy
main (production)
↑
└── dev (internal testing)
↑
└── feature/* (no auto-deploy)
Version Management
Versions are controlled by PR labels:
version:major- Bump major version (1.0.0 → 2.0.0)version:minor- Bump minor version (1.0.0 → 1.1.0)version:patch- Bump patch version (1.0.0 → 1.0.1) [default for main]- No label on dev - Only increment build number
Deployment Tracks
| Branch | Track | iOS Target | Android Target |
|---|---|---|---|
| dev | internal | TestFlight Internal | Play Store Internal |
| main | production | App Store | Play Store Production |
🏗️ Architecture
Workflows
-
mobile-deploy.yml- Main deployment workflow- Handles both manual and automated deployments
- Builds and uploads to app stores
- Creates git tags for production releases
-
mobile-deploy-auto.yml- PR merge trigger- Detects merged PRs
- Determines deployment parameters
- Calls main deployment workflow
Version Storage
app/version.json- Tracks build numbersapp/package.json- Semantic version- Native files auto-sync during build
Caching Strategy
Build times are optimized with caching:
- Yarn dependencies
- Ruby gems
- CocoaPods (iOS)
- Gradle (Android)
- Android NDK
Average build times with cache: iOS ~15min, Android ~10min
🔧 Configuration
Required Secrets
iOS
IOS_APP_IDENTIFIER- Bundle IDIOS_TEAM_ID- Apple Team IDIOS_CONNECT_KEY_ID- App Store Connect API Key IDIOS_CONNECT_ISSUER_ID- API Key Issuer IDIOS_CONNECT_API_KEY_BASE64- API Key (base64)IOS_DIST_CERT_BASE64- Distribution certificateIOS_PROV_PROFILE_BASE64- Provisioning profileIOS_P12_PASSWORD- Certificate password
Android
ANDROID_PACKAGE_NAME- Package nameANDROID_KEYSTORE- Keystore file (base64)ANDROID_KEYSTORE_PASSWORD- Keystore passwordANDROID_KEY_ALIAS- Key aliasANDROID_KEY_PASSWORD- Key passwordANDROID_PLAY_STORE_JSON_KEY- Service account key
Notifications
SLACK_API_TOKEN- For deployment notificationsSLACK_CHANNEL_ID- Channel for build uploads
Environment Variables
Set in workflow files:
NODE_VERSION: 18
RUBY_VERSION: 3.2
JAVA_VERSION: 17
ANDROID_API_LEVEL: 35
ANDROID_NDK_VERSION: 26.1.10909125
🏷️ Git Tags & Releases
Automatic Tags (Production Only)
When deploying to production, creates:
v2.5.5- Main version tagv2.5.5-ios-148- iOS with build numberv2.5.5-android-82- Android with build number
GitHub Releases
Automatically created for production deployments with:
- Changelog from commits
- Build information
- Links to app stores
🚨 Troubleshooting
Common Issues
"Play Store upload failed: Insufficient permissions"
The service account needs permissions in Google Play Console. The build file is saved locally and can be uploaded manually.
Cache not working
- Check if lock files changed (
yarn.lock,Gemfile.lock) - Cache keys include version numbers that can be bumped
- First build on new branch may be slower
iOS build fails with provisioning profile error
- Ensure secrets are up to date
- Check certificate expiration
- Verify bundle ID matches
Version conflicts
version.jsontracks the source of truth- Always higher than store versions
- Automatically incremented each build
Build Failures
- Check the workflow logs in GitHub Actions
- Look for the specific error in the failed step
- Most issues are related to:
- Expired certificates/profiles
- Missing secrets
- Network timeouts (retry usually helps)
📊 Monitoring
Slack Notifications
Successful deployments post to Slack with:
- Platform and version info
- Download links for the builds
- Deployment track (internal/production)
Deployment History
View all deployments:
- Go to Actions
- Filter by workflow: "Mobile App Deployments"
- Check run history and logs
🔐 Security
- All secrets are stored in GitHub Secrets
- Certificates are base64 encoded
- Build artifacts are uploaded to Slack (private channel)
- Production deployments only from protected branches
🛠️ Maintenance
Updating Workflows
- Test changes with
test_mode: true - Use
workflow_dispatchfor manual testing - Monitor first automated run carefully
Cache Busting
If builds are failing due to cache issues:
- Increment cache version in workflow:
GH_CACHE_VERSION: v2 # Increment this
Certificate Renewal
Before certificates expire:
- Generate new certificates/profiles
- Update GitHub Secrets
- Test with manual deployment first
For local development and manual release processes, see app/README.md