Skip to content

Commit fbf935b

Browse files
Add GitHub Actions workflows for iOS/Android CI/CD and update documentation
Co-authored-by: ChristianScheub <8379969+ChristianScheub@users.noreply.github.com>
1 parent 6565d58 commit fbf935b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+469
-12393
lines changed

.github/DEPLOY.md

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
# GitHub Actions Setup Guide
2+
3+
This document describes the GitHub Actions workflows setup for building and deploying the Local Notes app to iOS and Android platforms.
4+
5+
## Workflows Overview
6+
7+
### 1. CI/CD Pipeline (`ci.yml`)
8+
- **Trigger**: Push to main/develop branches, Pull Requests
9+
- **Purpose**: Run tests, linting, and build validation
10+
- **Actions**: Install dependencies, run tests with coverage, build project, upload artifacts
11+
12+
### 2. iOS Build & Deploy (`ios-deploy.yml`)
13+
- **Trigger**: Git tags starting with 'v*', Manual workflow dispatch
14+
- **Purpose**: Build iOS app and deploy to TestFlight
15+
- **Platform**: macOS latest with latest stable Xcode
16+
17+
### 3. Android Build & Deploy (`android-deploy.yml`)
18+
- **Trigger**: Git tags starting with 'v*', Manual workflow dispatch
19+
- **Purpose**: Build Android app and deploy to Google Play Store
20+
- **Platform**: Ubuntu latest with Java 17
21+
22+
## Required Secrets
23+
24+
To enable the workflows, configure the following secrets in your GitHub repository settings:
25+
26+
### iOS Deployment Secrets
27+
28+
| Secret Name | Description | How to obtain |
29+
|-------------|-------------|---------------|
30+
| `IOS_PROVISIONING_PROFILE` | Base64 encoded provisioning profile | Download from Apple Developer portal, encode with `base64 -i profile.mobileprovision` |
31+
| `IOS_CERTIFICATE` | Base64 encoded distribution certificate (.p12) | Export from Keychain Access, encode with `base64 -i certificate.p12` |
32+
| `IOS_CERTIFICATE_PASSWORD` | Password for the distribution certificate | Set when exporting certificate |
33+
| `IOS_TEAM_ID` | Apple Developer Team ID | Found in Apple Developer portal membership details |
34+
| `APP_STORE_CONNECT_USERNAME` | App Store Connect username | Your Apple ID email |
35+
| `APP_STORE_CONNECT_PASSWORD` | App Store Connect app-specific password | Generate in Apple ID account settings |
36+
37+
### Android Deployment Secrets
38+
39+
| Secret Name | Description | How to obtain |
40+
|-------------|-------------|---------------|
41+
| `ANDROID_KEYSTORE` | Base64 encoded Android keystore file | Encode existing keystore with `base64 -i keystore.jks` |
42+
| `ANDROID_KEYSTORE_PASSWORD` | Keystore password | Password used when creating keystore |
43+
| `ANDROID_KEY_ALIAS` | Key alias in keystore | Alias used when creating signing key |
44+
| `ANDROID_KEY_PASSWORD` | Key password | Password for the signing key |
45+
| `GOOGLE_PLAY_SERVICE_ACCOUNT_JSON` | Google Play Console service account JSON | Create service account in Google Cloud Console |
46+
47+
### Coverage Reporting (Optional)
48+
49+
| Secret Name | Description | How to obtain |
50+
|-------------|-------------|---------------|
51+
| `CODECOV_TOKEN` | Codecov upload token | Sign up at codecov.io and get repository token |
52+
53+
## Setup Instructions
54+
55+
### Initial Setup
56+
57+
1. **Fork/Clone Repository**: Ensure you have admin access to set up secrets
58+
2. **Configure Secrets**: Go to repository Settings > Secrets and variables > Actions
59+
3. **Add all required secrets** based on the tables above
60+
61+
### iOS Setup
62+
63+
1. **Apple Developer Account**:
64+
- Ensure you have a paid Apple Developer account
65+
- Create App ID matching `de.scheub.localNotes`
66+
- Create distribution certificate and provisioning profile
67+
68+
2. **App Store Connect**:
69+
- Create app in App Store Connect
70+
- Generate app-specific password for deployment
71+
72+
3. **Xcode Project**:
73+
- Ensure signing configuration is set to automatic
74+
- Bundle identifier must match the provisioning profile
75+
76+
### Android Setup
77+
78+
1. **Google Play Console**:
79+
- Create app in Google Play Console
80+
- Set up internal testing track
81+
82+
2. **Service Account**:
83+
- Create service account in Google Cloud Console
84+
- Grant necessary permissions in Google Play Console
85+
- Download JSON key file
86+
87+
3. **Keystore**:
88+
- Use existing keystore or create new one for signing
89+
- Store securely and backup
90+
91+
## Usage
92+
93+
### Manual Deployment
94+
95+
1. **iOS**: Go to Actions tab > iOS Build & Deploy > Run workflow
96+
- Set "Deploy to TestFlight" to true for TestFlight upload
97+
2. **Android**: Go to Actions tab > Android Build & Deploy > Run workflow
98+
- Set "Deploy to Google Play Store" to true for Play Store upload
99+
100+
### Automatic Deployment
101+
102+
1. **Create Git Tag**: `git tag v1.0.0 && git push origin v1.0.0`
103+
2. **Both iOS and Android workflows will trigger automatically**
104+
3. **Artifacts will be uploaded to both stores**
105+
106+
## Build Artifacts
107+
108+
All workflows upload build artifacts that can be downloaded from the Actions tab:
109+
110+
- **CI Pipeline**: `build-files` (web build output)
111+
- **iOS**: `ios-app` (signed IPA file)
112+
- **Android**: `android-apk` (signed APK), `android-bundle` (AAB for Play Store)
113+
114+
## Troubleshooting
115+
116+
### Common Issues
117+
118+
1. **iOS Signing Errors**:
119+
- Check provisioning profile matches bundle ID
120+
- Ensure certificate is valid and not expired
121+
- Verify team ID is correct
122+
123+
2. **Android Build Errors**:
124+
- Check Java version compatibility
125+
- Verify keystore and key passwords
126+
- Ensure all Gradle dependencies are available
127+
128+
3. **Capacitor Sync Issues**:
129+
- Make sure `capacitor.config.ts` is properly configured
130+
- Check that iOS and Android platforms are added
131+
132+
### Security Notes
133+
134+
- Never commit signing certificates or keystores to git
135+
- Use app-specific passwords for App Store Connect
136+
- Regularly rotate API keys and service account credentials
137+
- Keep base64 encoded secrets secure and backed up
138+
139+
## Maintenance
140+
141+
- **Update workflows**: Review and update GitHub Actions annually
142+
- **Renew certificates**: iOS certificates expire yearly
143+
- **Update dependencies**: Keep Capacitor and build tools updated
144+
- **Monitor builds**: Check action logs for any warnings or deprecations
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
name: Android Build & Deploy
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
workflow_dispatch:
8+
inputs:
9+
deploy_to_play_store:
10+
description: 'Deploy to Google Play Store'
11+
required: true
12+
default: 'false'
13+
type: boolean
14+
15+
jobs:
16+
build-android:
17+
name: Build Android App
18+
runs-on: ubuntu-latest
19+
20+
steps:
21+
- name: Checkout code
22+
uses: actions/checkout@v4
23+
24+
- name: Setup Node.js
25+
uses: actions/setup-node@v4
26+
with:
27+
node-version: '18'
28+
cache: 'npm'
29+
30+
- name: Setup Java JDK
31+
uses: actions/setup-java@v4
32+
with:
33+
java-version: '17'
34+
distribution: 'temurin'
35+
36+
- name: Setup Android SDK
37+
uses: android-actions/setup-android@v3
38+
39+
- name: Install dependencies
40+
run: npm ci
41+
42+
- name: Build web app
43+
run: npm run build
44+
45+
- name: Setup Capacitor
46+
run: |
47+
npm install -g @capacitor/cli
48+
npx cap sync android
49+
50+
- name: Setup Android signing
51+
env:
52+
ANDROID_KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE }}
53+
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
54+
ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
55+
ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
56+
run: |
57+
# Create the keystore file
58+
echo -n "$ANDROID_KEYSTORE_BASE64" | base64 --decode > android/app/local-notes-keystore.jks
59+
60+
# Create signing configuration
61+
echo "storeFile=local-notes-keystore.jks" >> android/local.properties
62+
echo "storePassword=$ANDROID_KEYSTORE_PASSWORD" >> android/local.properties
63+
echo "keyAlias=$ANDROID_KEY_ALIAS" >> android/local.properties
64+
echo "keyPassword=$ANDROID_KEY_PASSWORD" >> android/local.properties
65+
66+
- name: Build Android APK
67+
working-directory: android
68+
run: ./gradlew assembleRelease
69+
70+
- name: Build Android Bundle (AAB)
71+
working-directory: android
72+
run: ./gradlew bundleRelease
73+
74+
- name: Sign APK
75+
uses: r0adkll/sign-android-release@v1
76+
id: sign_apk
77+
with:
78+
releaseDirectory: android/app/build/outputs/apk/release
79+
signingKeyBase64: ${{ secrets.ANDROID_KEYSTORE }}
80+
alias: ${{ secrets.ANDROID_KEY_ALIAS }}
81+
keyStorePassword: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
82+
keyPassword: ${{ secrets.ANDROID_KEY_PASSWORD }}
83+
84+
- name: Upload to Google Play Store
85+
if: ${{ github.event.inputs.deploy_to_play_store == 'true' || startsWith(github.ref, 'refs/tags/') }}
86+
uses: r0adkll/upload-google-play@v1
87+
with:
88+
serviceAccountJsonPlainText: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_JSON }}
89+
packageName: de.scheub.localNotes
90+
releaseFiles: android/app/build/outputs/bundle/release/app-release.aab
91+
track: internal
92+
status: completed
93+
94+
- name: Upload APK artifact
95+
uses: actions/upload-artifact@v4
96+
with:
97+
name: android-apk
98+
path: ${{ steps.sign_apk.outputs.signedReleaseFile }}
99+
retention-days: 30
100+
101+
- name: Upload AAB artifact
102+
uses: actions/upload-artifact@v4
103+
with:
104+
name: android-bundle
105+
path: android/app/build/outputs/bundle/release/app-release.aab
106+
retention-days: 30

.github/workflows/ci.yml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: CI/CD Pipeline
2+
3+
on:
4+
push:
5+
branches: [ main, develop ]
6+
pull_request:
7+
branches: [ main, develop ]
8+
9+
jobs:
10+
test:
11+
name: Test & Build
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- name: Checkout code
16+
uses: actions/checkout@v4
17+
18+
- name: Setup Node.js
19+
uses: actions/setup-node@v4
20+
with:
21+
node-version: '18'
22+
cache: 'npm'
23+
24+
- name: Install dependencies
25+
run: npm ci
26+
27+
- name: Run linting
28+
run: npm run build # This includes ESLint checks in CI mode
29+
30+
- name: Run tests
31+
run: npm test -- --coverage --watchAll=false
32+
33+
- name: Upload coverage reports
34+
uses: codecov/codecov-action@v4
35+
with:
36+
file: ./coverage/lcov.info
37+
flags: unittests
38+
name: codecov-umbrella
39+
fail_ci_if_error: false
40+
41+
- name: Build project
42+
run: npm run build
43+
44+
- name: Upload build artifacts
45+
uses: actions/upload-artifact@v4
46+
with:
47+
name: build-files
48+
path: build/
49+
retention-days: 30

0 commit comments

Comments
 (0)