Release Checklist¶
Whistle ships from master. Every release goes through a branch, a PR, and review — no direct commits to master, ever, including for version bumps. Branch naming follows the convention:
feature/vX.Y-descriptionfor new functionalitybugfix/vX.Y.Z-descriptionfor fixeschore/descriptionfor housekeeping (deps, docs, infra)
Before cutting a release¶
- Confirm the target branch and version number. Follow SemVer — features bump minor, fixes bump patch.
- Bump the version in all four places. They must agree:
project.yml—MARKETING_VERSIONandCURRENT_PROJECT_VERSION(the latter is the iOS build number)android/app/build.gradle.kts—versionNameandversionCode(Android build number is monotonically increasing)CHANGELOG.md— add a new## [X.Y.Z] — YYYY-MM-DDsection at the top; follow the existing Keep a Changelog format with platform badges ((iOS)/(Android)/(iOS & Android))CLAUDE.md— update the## Roadmap"Current version:" line so AI agents and contributors see the latest shipped version- Update
ROADMAP.md— mark the completed phase with ✅, document what shipped under it, and (when relevant) update the branch-strategy history at the bottom. - Regenerate the Xcode project —
./scripts/build.shwill run XcodeGen automatically; do this so the version change actually lands in the Xcode build settings.
Validation¶
- Run CI checks locally to catch issues before pushing:
# WhistleCore (fast, no simulator needed) cd WhistleCore && swift test # SwiftLint — strict (any warning fails the build) swiftlint lint --strict # iOS unit tests (full Xcode build) ./scripts/build.sh test # Android unit tests cd android && ./gradlew :shared:test :app:testDebugUnitTest - Push the branch — every CI job listed in Testing-and-CI.md must pass; they are required merge gates.
- Smoke-test critical flows on a real device (simulator/emulator isn't enough for background location + push paths):
- Create a group, invite via at least one transport (QR / NFC / Nearby / link), accept the invite from a second device
- Send chat messages, verify locations exchange both directions
- Leave the group from one device, verify the admin sees + confirms it, then rejoin
- Toggle relays off/on, add a custom relay, verify reconnect
- Burn the identity from Settings → verify the app returns to first-run state cleanly
- Battery / Movement Aware paths: leave the device stationary for >30s and confirm location intervals back off; drop battery below the threshold and confirm the alert fires for the rest of the group
- Check group-list state badges — no stuck "Pending", "Leaving", or "Out of sync" rows after the smoke tests.
PR hygiene¶
- PR description focuses on user-visible behaviour, not implementation details.
- Include test evidence (CI results, screenshots, simulator logs as relevant) and call out any environment caveats.
- UI text or layout changes should include screenshots or short screen recordings.
- Link the CHANGELOG and ROADMAP changes in the PR description.
Post-merge¶
- Pull latest
masterand confirm the version bump landed as expected. - Re-run smoke checks if the release branch was long-lived (rebase divergence sometimes reintroduces flaky paths).
- Tag the release:
git tag v1.2.0 git push origin v1.2.0 - If the release is going to TestFlight or beyond, archive and upload from Xcode using the matching
MARKETING_VERSION/CURRENT_PROJECT_VERSIONfromproject.yml.