Files
Krow-workspace/docs/RELEASE/mobile-releases.md

728 lines
18 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Mobile App Release Process
**For Staff Mobile & Client Mobile Apps**
**Document Version**: 2.0
**Last Updated**: 2026-03-06
**Status**: ✅ Production Ready
---
## 📱 Overview
This document covers the complete release process for both mobile applications:
- **Staff Mobile App** (Worker Mobile) - `krow-withus-worker-mobile`
- **Client Mobile App** - `krow-withus-client-mobile`
Both apps:
- Built with Flutter
- Distributed via iOS App Store & Google Play Store
- Maintain independent versions
- Have independent CHANGELOGs
- Released via GitHub Actions workflows
---
## 📐 Versioning Strategy
### Semantic Versioning with Milestones
We use **Semantic Versioning 2.0.0** with milestone suffixes:
```
MAJOR.MINOR.PATCH-milestone
```
**Examples:**
- `0.0.1-m3` - Milestone 3 release
- `0.0.1-m4` - Milestone 4 release
- `1.0.0` - First production release (no suffix)
- `1.0.1` - Production patch release
**Version Rules:**
- **MAJOR**: Breaking changes, major architectural updates
- **MINOR**: New features, backward-compatible changes
- **PATCH**: Bug fixes, minor improvements
- **SUFFIX**: `-m3`, `-m4`, etc. for milestone tracking
### Version Location
Versions are defined in `pubspec.yaml`:
**Staff Mobile:** `apps/mobile/apps/staff/pubspec.yaml`
```yaml
version: 0.0.1-m4+1
```
**Client Mobile:** `apps/mobile/apps/client/pubspec.yaml`
```yaml
version: 0.0.1-m4+1
```
**Format:** `X.Y.Z-suffix+buildNumber`
- `0.0.1-m4` = version with milestone
- `+1` = build number (for app stores)
### Version Auto-Extraction
GitHub Actions workflows automatically extract the version from `pubspec.yaml` using `.github/scripts/extract-version.sh`. **No manual version input required.**
---
## 📝 CHANGELOG Management
### File Locations
- **Staff Mobile:** `apps/mobile/apps/staff/CHANGELOG.md`
- **Client Mobile:** `apps/mobile/apps/client/CHANGELOG.md`
### Format Standard
```markdown
# [App Name] - Change Log
## [v0.0.1-m4] - Milestone 4 - 2026-03-05
### Added - [Category Name]
- Feature description
- Another feature
### Fixed
- Bug fix description
### Changed
- Changed behavior
---
## [v0.0.1-m3] - Milestone 3 - 2026-02-15
### Added - [Category Name]
...
```
### Section Guidelines
Use these standard categories:
- **Added**: New features
- **Fixed**: Bug fixes
- **Changed**: Changes to existing functionality
- **Deprecated**: Soon-to-be removed features
- **Removed**: Removed features
- **Security**: Security fixes
### When to Update CHANGELOG
**Update BEFORE release:**
- When milestone is complete
- Document all user-facing changes
- Include technical features if relevant
**Don't document:**
- Internal refactoring (unless architecturally significant)
- Development-only changes
- Code formatting/linting
---
## 🏷️ Git Tag Format
### Tag Structure
```
krow-withus-<app>-mobile/<env>-v<version>
```
### Examples
**Staff Mobile (Worker):**
```
krow-withus-worker-mobile/dev-v0.0.1-m3
krow-withus-worker-mobile/stage-v0.0.1-m4
krow-withus-worker-mobile/prod-v1.0.0
```
**Client Mobile:**
```
krow-withus-client-mobile/dev-v0.0.1-m3
krow-withus-client-mobile/stage-v0.0.1-m4
krow-withus-client-mobile/prod-v1.0.0
```
### Tag Components
| Component | Values | Example |
|-----------|--------|---------|
| Product | `worker`, `client` | `worker` |
| Type | `mobile` | `mobile` |
| Environment | `dev`, `stage`, `prod` | `dev` |
| Version | From pubspec.yaml | `v0.0.1-m3` |
**Note:** Tags include the full version with milestone suffix (e.g., `v0.0.1-m4`, not just `v0.0.1`)
---
## 🚀 Release Workflows
### Release Types
We have **2 GitHub Actions workflows** for releases:
1. **Product Release** (`.github/workflows/product-release.yml`) - Standard releases
2. **Hotfix Branch Creation** (`.github/workflows/hotfix-branch-creation.yml`) - Emergency fixes
Both workflows use **manual triggers only** (`workflow_dispatch`) - no automatic releases.
---
## 📦 Standard Release Process
### Step 1: Prepare Release
1. **Ensure milestone is complete**
- All features implemented
- All tests passing
- Code reviews completed
2. **Update CHANGELOG**
```bash
# Edit the appropriate CHANGELOG file
vi apps/mobile/apps/staff/CHANGELOG.md
# OR
vi apps/mobile/apps/client/CHANGELOG.md
```
3. **Update version in pubspec.yaml**
```yaml
# apps/mobile/apps/staff/pubspec.yaml
version: 0.0.1-m4+1
```
4. **Commit changes**
```bash
git add apps/mobile/apps/staff/CHANGELOG.md apps/mobile/apps/staff/pubspec.yaml
git commit -m "docs(mobile): prepare staff app v0.0.1-m4 release"
git push origin dev
```
### Step 2: Trigger Release Workflow
1. **Navigate to GitHub Actions**
- Go to: https://github.com/Oloodi/krow-workforce/actions
- Select **"📦 Product Release"** workflow
2. **Click "Run workflow"**
3. **Select parameters:**
- **Branch**: `dev` (or release branch)
- **Product**: `worker-mobile-app` or `client-mobile-app`
- **Environment**: `dev`, `stage`, or `prod`
- **Pre-release**: Check if this is not a production release
4. **Click "Run workflow"**
### Step 3: Monitor Workflow
The workflow performs these steps automatically:
1. ✅ **Validate & Create Release** (Job 1)
- Extract version from pubspec.yaml
- Validate version format
- Generate tag name
- Create Git tag
- Extract release notes from CHANGELOG
- Create GitHub Release with formatted notes
2. 🔨 **Build Mobile Artifacts** (Job 2)
- Setup Node.js 20
- Install Firebase CLI
- Generate Data Connect SDK
- Setup Java 17
- Setup Flutter 3.38.x
- Bootstrap with Melos
- Decode keystore from secrets
- Build signed APK
- Verify APK signature
- Upload APK to GitHub Release
### Step 4: Verify Release
1. **Check GitHub Releases page**
- URL: https://github.com/Oloodi/krow-workforce/releases
- Verify release was created with correct tag
- Verify release notes display correctly
- Verify APK is attached (if applicable)
2. **Test the release**
- Download APK (dev releases)
- Install on test device
- Verify app launches and core features work
---
## 🔥 Hotfix Process
### When to Use Hotfix
✅ **Use hotfix for:**
- Critical bug in production affecting users
- Data loss or security vulnerability
- Service unavailable or major feature broken
- Customer-blocking issue
❌ **Don't use hotfix for:**
- Minor bugs (can wait for next release)
- Feature requests
- UI/UX improvements
- Styling issues
### Hotfix Workflow
1. **Navigate to GitHub Actions**
- Go to: https://github.com/Oloodi/krow-workforce/actions
- Select **"🚨 Product Hotfix - Create Branch"** workflow
2. **Click "Run workflow"**
3. **Fill in parameters:**
- **Product**: `worker-mobile-app` or `client-mobile-app`
- **Current Production Version**: e.g., `1.0.0` (without 'v' prefix)
- **Issue Description**: Brief description of the bug (used in CHANGELOG and branch name)
4. **The workflow automatically:**
- Creates hotfix branch: `hotfix/krow-withus-worker-mobile/prod-v1.0.1`
- Increments PATCH version: `1.0.0` → `1.0.1`
- Updates `pubspec.yaml` with new version
- Updates CHANGELOG.md with hotfix entry
- Creates Pull Request with hotfix instructions
5. **Fix the bug:**
```bash
# Checkout the hotfix branch
git fetch origin
git checkout hotfix/krow-withus-worker-mobile/prod-v1.0.1
# Make your fix
# ... edit files ...
# Test thoroughly
flutter test
# Commit your fix
git add .
git commit -m "fix(mobile): resolve critical production bug"
git push origin hotfix/krow-withus-worker-mobile/prod-v1.0.1
```
6. **Merge and Release:**
- Review and merge the Pull Request to `main` (or production branch)
- Trigger **Product Release** workflow with `prod` environment
- Workflow will create tag `krow-withus-worker-mobile/prod-v1.0.1`
- Deploy hotfix to production
7. **Backport to dev:**
```bash
git checkout dev
git merge hotfix/krow-withus-worker-mobile/prod-v1.0.1
git push origin dev
```
---
## 🔐 APK Signing Setup
### Overview
All Android builds require signing with keystores. We use **24 GitHub Secrets** (12 per app × 2 apps):
- 6 keystores (2 apps × 3 environments)
- 4 secrets per keystore (base64, password, alias, key password)
### Keystore Files
**Worker Mobile (Staff App):**
- `krow_with_us_staff_dev.jks` - ✅ Committed to repo
- `krow_staff_staging.jks` - ⚠️ Store in GitHub Secrets only
- `krow_staff_prod.jks` - ⚠️ Store in GitHub Secrets only
**Client Mobile:**
- `krow_with_us_client_dev.jks` - ✅ Committed to repo
- `krow_client_staging.jks` - ⚠️ Store in GitHub Secrets only
- `krow_client_prod.jks` - ⚠️ Store in GitHub Secrets only
### Required GitHub Secrets
#### Worker Mobile - 12 Secrets
**Dev Environment:**
- `WORKER_KEYSTORE_DEV_BASE64`
- `WORKER_KEYSTORE_PASSWORD_DEV`
- `WORKER_KEY_ALIAS_DEV`
- `WORKER_KEY_PASSWORD_DEV`
**Staging Environment:**
- `WORKER_KEYSTORE_STAGING_BASE64`
- `WORKER_KEYSTORE_PASSWORD_STAGING`
- `WORKER_KEY_ALIAS_STAGING`
- `WORKER_KEY_PASSWORD_STAGING`
**Production Environment:**
- `WORKER_KEYSTORE_PROD_BASE64`
- `WORKER_KEYSTORE_PASSWORD_PROD`
- `WORKER_KEY_ALIAS_PROD`
- `WORKER_KEY_PASSWORD_PROD`
#### Client Mobile - 12 Secrets
**Dev Environment:**
- `CLIENT_KEYSTORE_DEV_BASE64`
- `CLIENT_KEYSTORE_PASSWORD_DEV`
- `CLIENT_KEY_ALIAS_DEV`
- `CLIENT_KEY_PASSWORD_DEV`
**Staging Environment:**
- `CLIENT_KEYSTORE_STAGING_BASE64`
- `CLIENT_KEYSTORE_PASSWORD_STAGING`
- `CLIENT_KEY_ALIAS_STAGING`
- `CLIENT_KEY_PASSWORD_STAGING`
**Production Environment:**
- `CLIENT_KEYSTORE_PROD_BASE64`
- `CLIENT_KEYSTORE_PASSWORD_PROD`
- `CLIENT_KEY_ALIAS_PROD`
- `CLIENT_KEY_PASSWORD_PROD`
### Setup Using Helper Script
We provide an interactive script to configure all secrets:
```bash
.github/scripts/setup-mobile-github-secrets.sh
```
This script will:
1. Prompt for keystore file paths
2. Convert keystores to base64
3. Prompt for passwords and aliases
4. Display GitHub CLI commands to set secrets
5. Optionally execute the commands
### Manual Setup
If you prefer manual setup:
```bash
# 1. Convert keystore to base64
base64 -i /path/to/keystore.jks | pbcopy
# 2. Add to GitHub Secrets via web UI
# Go to: Repository → Settings → Secrets and variables → Actions
# Click "New repository secret"
# Name: WORKER_KEYSTORE_PROD_BASE64
# Value: Paste the base64 string
# 3. Repeat for all 24 secrets
```
Or use GitHub CLI:
```bash
# Set a secret using gh CLI
gh secret set WORKER_KEYSTORE_PROD_BASE64 < /path/to/keystore_base64.txt
# Set multiple secrets
gh secret set WORKER_KEYSTORE_PASSWORD_PROD -b "your_password"
gh secret set WORKER_KEY_ALIAS_PROD -b "your_alias"
gh secret set WORKER_KEY_PASSWORD_PROD -b "your_key_password"
```
### Verifying APK Signature
After build, the workflow automatically verifies the APK signature using:
```bash
.github/scripts/verify-apk-signature.sh <path-to-apk> <expected-alias>
```
---
## 📅 Release Cadence
### Development Releases (dev)
- **Frequency**: As needed (daily/weekly)
- **Purpose**: Test features, integration testing
- **Stability**: Unstable, may have bugs
- **Distribution**: Internal testing only
- **APK**: Signed with dev keystore
- **Tag example**: `krow-withus-worker-mobile/dev-v0.0.1-m3`
### Staging Releases (stage)
- **Frequency**: Bi-weekly (end of sprints)
- **Purpose**: QA testing, client demos
- **Stability**: Stable, feature-complete
- **Distribution**: QA team, stakeholders
- **APK**: Signed with staging keystore
- **Tag example**: `krow-withus-worker-mobile/stage-v0.0.1-m4`
### Production Releases (prod)
- **Frequency**: Monthly or milestone-based
- **Purpose**: Public release to app stores
- **Stability**: Production-grade, thoroughly tested
- **Distribution**: Public (App Store, Play Store)
- **APK**: Signed with production keystore
- **Tag example**: `krow-withus-worker-mobile/prod-v1.0.0`
---
## 🛠️ Helper Scripts Reference
All scripts are located in `.github/scripts/` and are used by workflows:
### 1. extract-version.sh
**Purpose**: Extract version from pubspec.yaml
**Usage**:
```bash
.github/scripts/extract-version.sh <path-to-pubspec.yaml>
```
**Example**:
```bash
VERSION=$(.github/scripts/extract-version.sh apps/mobile/apps/staff/pubspec.yaml)
echo $VERSION # Output: 0.0.1-m4
```
### 2. generate-tag-name.sh
**Purpose**: Generate consistent Git tag names
**Usage**:
```bash
.github/scripts/generate-tag-name.sh <app> <env> <version>
```
**Example**:
```bash
TAG=$(.github/scripts/generate-tag-name.sh worker dev 0.0.1-m4)
echo $TAG # Output: krow-withus-worker-mobile/dev-v0.0.1-m4
```
### 3. extract-release-notes.sh
**Purpose**: Extract CHANGELOG section for a specific version
**Usage**:
```bash
.github/scripts/extract-release-notes.sh <app> <env> <version> <tag>
```
**Example**:
```bash
NOTES=$(.github/scripts/extract-release-notes.sh worker dev 0.0.1-m4 krow-withus-worker-mobile/dev-v0.0.1-m4)
```
**Output format**:
```
**Environment:** DEV
**Tag:** krow-withus-worker-mobile/dev-v0.0.1-m4
## What is new in this release
[CHANGELOG content for v0.0.1-m4]
```
### 4. create-release-summary.sh
**Purpose**: Generate GitHub Step Summary with emojis
**Usage**:
```bash
.github/scripts/create-release-summary.sh <app> <env> <version> <tag>
```
**Creates**: Formatted summary in GitHub Actions UI
### 5. setup-apk-signing.sh
**Purpose**: Setup APK signing environment variables
**Usage** (in workflow):
```bash
.github/scripts/setup-apk-signing.sh <app> <env>
```
**What it does**:
- Decodes base64 keystore to file
- Sets `CM_KEYSTORE_PATH_<APP>` environment variable
- Sets keystore password, alias, and key password
### 6. verify-apk-signature.sh
**Purpose**: Verify APK is properly signed
**Usage**:
```bash
.github/scripts/verify-apk-signature.sh <apk-path> <expected-alias>
```
**Example**:
```bash
.github/scripts/verify-apk-signature.sh build/app/outputs/apk/release/app-release.apk androidreleasekey
```
### 7. attach-apk-to-release.sh
**Purpose**: Upload APK to existing GitHub Release
**Usage**:
```bash
.github/scripts/attach-apk-to-release.sh <tag> <apk-path> <app>
```
**Example**:
```bash
.github/scripts/attach-apk-to-release.sh krow-withus-worker-mobile/dev-v0.0.1-m4 build/app/outputs/apk/release/app-release.apk worker
```
### 8. setup-mobile-github-secrets.sh
**Purpose**: Interactive helper to configure all GitHub Secrets
**Usage**:
```bash
.github/scripts/setup-mobile-github-secrets.sh
```
**Interactive prompts for**:
- Keystore file paths
- Passwords and aliases
- Generates GitHub CLI commands
- Optionally executes commands
---
## 📋 Pre-Release Checklist
Before triggering a release, ensure:
### Code Quality
- [ ] All automated tests pass
- [ ] No critical linting errors
- [ ] Code review completed (for stage/prod)
- [ ] Security audit passed (for prod)
### Documentation
- [ ] CHANGELOG.md updated with all changes
- [ ] Version in pubspec.yaml matches CHANGELOG
- [ ] Breaking changes documented
- [ ] Migration guide created (if needed)
### Testing
- [ ] Feature testing completed
- [ ] Regression testing passed
- [ ] Performance testing acceptable
- [ ] Device compatibility verified
### Configuration
- [ ] Environment variables configured
- [ ] API endpoints correct for environment
- [ ] Feature flags set appropriately
- [ ] Analytics tracking verified
### GitHub Secrets (First-time setup)
- [ ] All 24 secrets configured
- [ ] Keystore passwords verified
- [ ] Test build succeeded with signing
---
## 🐛 Troubleshooting
### Workflow Fails: "Version not found in pubspec.yaml"
**Cause**: Invalid version format or missing version
**Solution**:
```yaml
# Ensure version line in pubspec.yaml looks like:
version: 0.0.1-m4+1
# Not:
version: 0.0.1 # Missing build number
version: "0.0.1-m4+1" # Don't quote the version
```
### Workflow Fails: "Secret not found"
**Cause**: Missing GitHub Secret
**Solution**:
1. Check secret name matches exactly (case-sensitive)
2. Run `.github/scripts/setup-mobile-github-secrets.sh`
3. Verify secrets at: Repository → Settings → Secrets and variables → Actions
### APK Signing Fails
**Cause**: Invalid keystore or wrong password
**Solution**:
1. Verify keystore base64 encoding: `base64 -i keystore.jks | base64 -d > test.jks`
2. Test password locally: `keytool -list -keystore test.jks`
3. Verify alias: `keytool -list -v -keystore test.jks | grep "Alias name"`
### CHANGELOG Not Extracted
**Cause**: Version format doesn't match in CHANGELOG
**Solution**:
```markdown
# CHANGELOG.md must have this EXACT format:
## [v0.0.1-m4] - Milestone 4 - 2026-03-05
# OR
## [0.0.1-m4] - Milestone 4 - 2026-03-05
# The script tries both [vX.Y.Z] and [X.Y.Z] formats
```
### Tag Already Exists
**Cause**: Trying to create a duplicate tag
**Solution**:
```bash
# Delete the existing tag (CAREFUL!)
git tag -d krow-withus-worker-mobile/dev-v0.0.1-m4
git push origin :refs/tags/krow-withus-worker-mobile/dev-v0.0.1-m4
# Then re-run the workflow
```
---
## 📚 Additional Resources
### Related Documentation
- [Agent Development Rules](../MOBILE/00-agent-development-rules.md)
- [Architecture Principles](../MOBILE/01-architecture-principles.md)
- [Mobile CI Workflow](../../.github/workflows/mobile-ci.yml)
### GitHub Actions Workflows
- **Product Release**: `.github/workflows/product-release.yml`
- **Hotfix Branch Creation**: `.github/workflows/hotfix-branch-creation.yml`
- **Mobile CI**: `.github/workflows/mobile-ci.yml`
### Useful Commands
```bash
# View current version
grep "^version:" apps/mobile/apps/staff/pubspec.yaml
# List all mobile tags
git tag -l "krow-withus-*-mobile/*"
# View latest releases
gh release list --limit 10
# Download APK from release
gh release download krow-withus-worker-mobile/dev-v0.0.1-m4 --pattern "*.apk"
```
---
## 🔄 Version History
| Version | Date | Changes |
|---------|------|---------|
| 2.0 | 2026-03-06 | Consolidated all release docs into single file |
| 1.0 | 2026-03-05 | Initial separate documentation files |
---
**Questions or Issues?**
Contact the DevOps team or create an issue in the repository.