| name | release-management |
| description | Handles the end-to-end release process, ensuring local builds are tested and verified by the user before pushing tags to trigger CI/CD releases. Use this whenever preparing for a public version update. |
Release Management & DevOps
Purpose
Ensures that any code being pushed to production is functional, stable, and verified. It prevents "broken releases" by mandating a local build and test cycle before public tags are created.
Core Mandates
- Absolute Permission Rule: NEVER perform a
git commit, git tag, or git push without explicit, real-time user consent for that specific action.
- Consent-First Releases: NEVER trigger a GitHub Actions workflow or push a release tag without permission.
- Local Build & Test First: Always build a local APK and provide it to the user for testing before asking for permission to commit or release.
- Mandatory User Verification: Wait for explicit user confirmation that the local APK works as expected before final commit and push.
Release Workflow
Step 1: Quality Gate & Version Bump
Before bumping the version, ensure all of the following are done:
flutter analyze → zero errors/warnings. CI/CD will fail on any lint issues.
flutter test → all tests passing. Running the full test suite locally is mandatory to catch regressions.
CHANGELOG.md entry is documented under ## X.Y.Z - YYYY-MM-DD (without brackets around the version number). Keep release notes ultra-concise, punchy, and benefit-first (3-4 bullets max, single short line per feature).
- Changelog Screen (MANDATORY for every release): Update
lib/screens/changelog_screen.dart by adding a new _buildVersionSection(context, version: 'vX.Y.Z', date: '...', isLatest: true, changes: [...]) entry at the top of the list, and setting isLatest: false on the preceding section. This guarantees the in-app Settings Changelog page matches CHANGELOG.md 100%.
- What's New sheet (MANDATORY for every release): Update the feature cards in
lib/widgets/whats_new_sheet.dart to describe THIS release's user-facing features in short, friendly, benefit-first language (3-5 cards max, single line per card). The sheet auto-fires once per version — it's gated on SettingsProvider.lastSeenVersion vs PackageInfo version in home_screen._maybeShowWhatsNew — so stale content from a previous release WILL be shown to every updating user. Never ship a release without refreshing it.
- Version number in
pubspec.yaml is bumped using the project convention:
- Minor bump (new features):
1.X.0+Y where Y = X * 10000 (e.g. 1.34.0+13400)
- Patch bump (bug fixes):
1.X.Y+Z (e.g. 1.33.1+13301)
- Keep
minor and patch numbers strictly under 100 to prevent version code overlaps.
Step 2: Build Local Release APK & On-Device Smoke Test
Verify the release build succeeds locally:
flutter build apk --release
Provide the APK path (build/app/outputs/flutter-apk/app-release.apk) to the user for verification.
Release-mode emulator smoke test is mandatory, not optional. Install the release APK on the emulator and cold-start it: debug builds hide release-only startup races (a WorkManager background isolate opening the SQLCipher DB during app launch once deadlocked the app on the splash screen in release mode only). Verify: first frame renders, the What's New sheet fires with the right version, and each module tab opens. Diagnose stuck launches with adb logcat -s flutter and adb shell dumpsys window | grep mCurrentFocus; note that a MissingPluginException for activity-registered channels coming from the WorkManager isolate is expected and benign.
Step 3: Run Release Automation
Execute the automated deploy script to bump, tag, and publish:
./deploy.sh <version>
Step 4: Play Console Bilingual Release Notes (Mandatory File & Output)
With every release, ALWAYS write the latest release notes to PLAY_STORE_NOTES.md at the project root before running ./deploy.sh. Format them inside <en-US> (English) and <ta-IN> (Tamil) XML tags:
- Keep notes ultra-concise, direct, and under 4 bullet points total.
- Focus purely on user benefits in a single short sentence per point (no technical jargon or long text).
<en-US>
• Feature: Short, direct user benefit.
• Fix: Quick one-line fix summary.
</en-US>
<ta-IN>
• அம்சம்: நேரடிப் பயனர் விளக்கம்.
• திருத்தம்: சுருக்கமான பிழைத்திருத்தம்.
</ta-IN>
./deploy.sh and GitHub Actions will read PLAY_STORE_NOTES.md to automatically publish multilingual WhatsNew notes directly to Google Play Console.
Gradle & Build Configuration Guidelines
Play Store Listing Assets & Mockup Generation
1. App Icon & Feature Graphic Specifications
Google Play Console enforces strict dimensions for marketing assets. Use sips on macOS to resize/crop generated assets:
2. Creating Mockups with Real Emulator Screenshots
To showcase real app workflows in mockups instead of placeholders:
- Launch the app on the connected emulator:
adb shell am start -n <package>/<main_activity>
- Switch tabs or trigger actions by tapping exact coordinates (e.g.,
x=540, y=2300 for bottom navigation bar):
adb shell input tap <x> <y>
- Capture screen contents directly to files:
adb exec-out screencap -p > <output_path.png>
- Pass the captured file path to
ImagePaths in the generate_image tool, prompting it to overlay the screenshot inside a bezel-less smartphone frame on a custom gradient background.
3. Android Monochrome Launcher Override Gotcha
If regenerating adaptive icons using tools like flutter_launcher_icons, check for any pre-existing monochrome vector resource at android/app/src/main/res/drawable/ic_launcher_monochrome.xml. Delete this stale XML to allow the system launcher to fallback correctly to the newly generated transparent PNG layers.