This document outlines the full release lifecycle for Freighter Mobile, covering both standard releases and emergency hotfixes.
- Regular Release Flow
- Emergency Release Flow
- Post-Merge Manual Steps
- Regular vs Emergency Comparison
- Version Bump Details
- Nightly Builds
- CI/CD and Test Coverage
- GitHub App Token Setup (Pending)
- Workflow Files Reference
Regular releases are triggered from the main branch. The process is
orchestrated by new-release.yml.
[ main ]
|
+-- (1) Create 'release' branch from 'main'
| |
| +-- (2) Create 'vX.Y.Z' branch from 'release'
| |
| +-- (3) Bump version (5 files)
| |
| +-- (4) Generate release notes (git log)
| |
| +-- (5) Create PR: vX.Y.Z -> release
| |
| +-- (6) Trigger iOS/Android dev builds
|
+-- (7) Create 'bump-version' branch from 'main'
|
+-- (8) Bump version (5 files)
|
+-- (9) Create PR: bump-version -> main
- Go to GitHub Actions and select New Release (
new-release.yml). - Click Run workflow.
- Enter the
app_version(e.g.,1.10.24). - Leave
branch_fromasmain. - The workflow validates the version format and ensures branches don't already exist.
- Two PRs are created:
vX.Y.Ztargetingrelease: This is your release candidate.bump-versiontargetingmain: This synchronizes the version back to the development branch.
- Development builds for iOS and Android are automatically triggered on the
vX.Y.Zbranch.
Emergency releases (hotfixes) are triggered from a previous release tag rather
than main.
[ vX.Y.Z (Tag) ]
|
+-- (1) Create 'emergency-release' branch from Tag
|
+-- (2) Create 'vX.Y.Z+1' branch from 'emergency-release'
|
+-- (3) Bump version (5 files)
|
+-- (4) Add placeholder release notes
|
+-- (5) Create PR: vX.Y.Z+1 -> emergency-release
- Go to GitHub Actions and select New Release (
new-release.yml). - Click Run workflow.
- Enter the new
app_version. - Set
branch_fromto the existing tag version (e.g.,1.9.24). - One PR is created:
vX.Y.Ztargetingemergency-release. - Note: No automatic dev builds are triggered. Developers must push fixes
to the
vX.Y.Zbranch and manually trigger dev builds to QA the hotfixes.
The release process requires manual intervention after PRs are merged.
- Tag the release: Once the release PR is merged into
release(oremergency-release), create a git tagv{version}on that merge commit. - Trigger production builds: Manually run
ios.ymlandandroid.yml.- Set
ref_nameto the release branch or tag. - Set
buildEnvtoprod.
- Set
- App Store / Play Store submission:
- iOS builds auto-upload to TestFlight.
- Android builds auto-upload to the Google Play internal track.
- Promotion to production tracks must be done manually in the respective consoles.
- Branch cleanup: Delete the
release(oremergency-release) branch. Thev{version}andbump-versionhead branches are automatically deleted when their PRs are merged. - Sync main: Ensure the
bump-versionPR is merged intomainpromptly for regular releases.
| Aspect | Regular Release | Emergency Release |
|---|---|---|
branch_from input |
main |
A tag (e.g., 1.9.24) |
| Release branch | release |
emergency-release |
| Version branch | v{version} |
v{version} |
| PR target | release |
emergency-release |
| Release notes | Auto-generated from git log | Placeholder (manual edit needed) |
| Bump-version PR | Yes (bump-version -> main) |
No |
| Auto dev builds | Yes (iOS + Android) | No |
| Nightly build skip | Yes (while release exists) |
Yes (while emergency-release exists) |
The scripts/set-app-version script modifies the following files to ensure
version parity across platforms:
package.json: Updates theversionfield.android/app/build.gradle: UpdatesversionName.ios/freighter-mobile/Info.plist: UpdatesCFBundleShortVersionString.ios/freighter-mobile/Info-Dev.plist: UpdatesCFBundleShortVersionString.ios/freighter-mobile.xcodeproj/project.pbxproj: UpdatesMARKETING_VERSION.
To manually set the version locally (e.g., for testing), run:
yarn set-app-version 1.10.24The ios.yml and android.yml workflows run daily at 8:00 AM UTC.
- They check for the existence of a
releaseoremergency-releasebranch. - If either branch exists, the nightly build is skipped.
- This prevents automated builds from overwriting a release candidate currently undergoing testing in TestFlight or Google Play.
All release-related branches (release, emergency-release, v*.*.*) and PRs
targeting them trigger the following suites:
- Unit Tests (
test.yml): Runsyarn test --ci. - iOS E2E (
ios-e2e.yml): Runs Maestro tests on macOS. - Android E2E (
android-e2e.yml): Runs Maestro tests on Linux with an emulator.
GitHub restricts the GITHUB_TOKEN from triggering further workflow runs (like
tests) when a PR is created by a bot. This means the release and bump-version
PRs created by new-release.yml will not automatically trigger test or E2E
workflows.
Current workaround: After the release workflow creates the PRs, manually push an empty commit to the PR branch to trigger tests:
git checkout v1.10.24
git commit --allow-empty -m "Trigger Tests"
git pushPlanned fix: A dedicated GitHub App will be configured so that PRs created by the release workflow will trigger tests automatically.
| File | Purpose |
|---|---|
.github/workflows/new-release.yml |
Release orchestrator (branches, PRs, triggers) |
.github/workflows/ios.yml |
iOS build and TestFlight upload |
.github/workflows/android.yml |
Android build and Google Play upload |
.github/workflows/test.yml |
Jest unit tests |
.github/workflows/ios-e2e.yml |
Maestro iOS E2E tests |
.github/workflows/android-e2e.yml |
Maestro Android E2E tests |
.github/actions/validate-branch-from/action.yml |
Input validation for release source |
scripts/set-app-version |
Multi-platform version update script |
scripts/generate-release-notes.sh |
Git log based release notes generator |
fastlane/Fastfile |
Build lanes for iOS and Android |