Skip to content

Commit 1fc59a0

Browse files
authored
Merge pull request #8 from niyajali/migrate-to-fastlane
feat: Enhance Android build with Fastlane automation
2 parents e51e3bb + 644cc7e commit 1fc59a0

File tree

2 files changed

+147
-259
lines changed

2 files changed

+147
-259
lines changed

README.md

Lines changed: 115 additions & 183 deletions
Original file line numberDiff line numberDiff line change
@@ -1,209 +1,141 @@
1-
# KMP Android Build Action
1+
# KMP Build Android App Action
22

3-
## Overview
4-
5-
A comprehensive GitHub Action for building Android applications with support for multiple flavors,
6-
build types, and secure release configurations.
3+
This GitHub Action automates the process of building Android applications using Gradle. It supports both Debug and Release builds, with optional signing configuration for Release builds.
74

85
## Features
96

10-
- 🤖 Cross-flavor Android app building
11-
- 🔒 Secure release configuration support
12-
- 📦 Automatic artifact generation
13-
- 🚀 Version code generation
14-
- 🔑 Keystore and Google Services integration
15-
16-
## Usage Examples
17-
18-
### Debug Build
19-
20-
```yaml
21-
- name: Checkout Repository
22-
uses: actions/checkout@v4
23-
with:
24-
fetch-depth: 0
25-
26-
- name: Build Android Debug
27-
uses: openMF/[email protected]
28-
with:
29-
android_package_name: 'myapp'
30-
```
31-
32-
### Release Build
33-
34-
```yaml
35-
- name: Build Android Release
36-
uses: openMF/[email protected]
37-
id: build-android
38-
with:
39-
android_package_name: 'myapp'
40-
build_type: 'Release'
41-
key_store: ${{ secrets.KEYSTORE_BASE64 }}
42-
google_services: ${{ secrets.GOOGLE_SERVICES_BASE64 }}
43-
key_store_password: ${{ secrets.KEYSTORE_PASSWORD }}
44-
key_store_alias: ${{ secrets.KEY_ALIAS }}
45-
key_store_alias_password: ${{ secrets.KEY_ALIAS_PASSWORD }}
46-
47-
- name: Display APK Paths
48-
run: |
49-
echo "Demo APK: ${{ steps.build-android.outputs.demo_apk }}"
50-
echo "Prod APK: ${{ steps.build-android.outputs.prod_apk }}"
51-
```
7+
- Debug and Release build support
8+
- APK signing for Release builds
9+
- Gradle dependency caching
10+
- Artifact upload
11+
- Google Services integration
12+
- Fastlane automation
5213

53-
## Workflow Diagram
54-
55-
```mermaid
56-
flowchart TD
57-
A[Start Build Process] --> B[Set up Java 17]
58-
B --> C[Setup Gradle]
59-
C --> D[Cache Gradle Dependencies]
60-
D --> E[Generate Version Number]
61-
E --> F{Build Type?}
62-
F -->|Debug| G[Build Debug APK]
63-
F -->|Release| H[Inflate Secrets]
64-
H --> I[Build Release APK]
65-
G --> J[Collect APK Paths]
66-
I --> J
67-
J --> K[Upload Artifacts]
68-
K --> L[End Build Process]
69-
```
14+
## Prerequisites
7015

71-
## Android Project Configuration
72-
Release Build Environment Variables
73-
To use release build environment variables in your Android project, update your build.gradle files:
74-
75-
App-level `build.gradle`
76-
77-
```kotlin
78-
android {
79-
namespace = "org.mifospay"
80-
81-
defaultConfig {
82-
applicationId = "org.mifospay"
83-
versionName = System.getenv("VERSION") ?: project.dynamicVersion
84-
versionCode = System.getenv("VERSION_CODE")?.toIntOrNull() ?: 1
85-
vectorDrawables.useSupportLibrary = true
86-
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
87-
}
88-
89-
signingConfigs {
90-
create("release") {
91-
storeFile = file(System.getenv("KEYSTORE_PATH") ?: "release_keystore.keystore")
92-
storePassword = System.getenv("KEYSTORE_PASSWORD") ?: "DefaultPassword"
93-
keyAlias = System.getenv("KEYSTORE_ALIAS") ?: "default-alias"
94-
keyPassword = System.getenv("KEYSTORE_ALIAS_PASSWORD") ?: "DefaultAlias"
95-
enableV1Signing = true
96-
enableV2Signing = true
97-
}
98-
}
99-
}
100-
```
16+
Before using this action, ensure you have:
10117

18+
1. A valid Android project with a Gradle build configuration
19+
2. For Release builds:
20+
- A keystore file for signing your APK
21+
- Google Services JSON file (if using Firebase)
10222

103-
## Inputs
23+
## Setup
10424

105-
### `android_package_name`
25+
### Fastlane Setup
10626

107-
- **Description**: Name of the Android project module
108-
- **Required**: `true`
109-
- **Type**: `string`
110-
- **Example**: `'app'`
27+
Create a `Gemfile` in your project root:
11128

112-
### `build_type`
29+
```ruby
30+
source "https://rubygems.org"
11331

114-
- **Description**: Type of build to perform
115-
- **Required**: `true`
116-
- **Default**: `'Debug'`
117-
- **Options**:
118-
- `'Debug'`
119-
- `'Release'`
32+
gem "fastlane"
33+
```
12034

121-
### `key_store` (Optional for Release)
35+
Create a `fastlane/Fastfile` with the following content:
36+
37+
```ruby
38+
default_platform(:android)
39+
40+
platform :android do
41+
desc "Assemble Debug APKs"
42+
lane :assembleDebugApks do
43+
gradle(
44+
task: "assemble",
45+
build_type: "Debug"
46+
)
47+
end
48+
49+
desc "Assemble Release APKs"
50+
lane :assembleReleaseApks do |options|
51+
gradle(
52+
task: "assemble",
53+
build_type: "Release",
54+
properties: {
55+
"android.injected.signing.store.file" => options[:storeFile],
56+
"android.injected.signing.store.password" => options[:storePassword],
57+
"android.injected.signing.key.alias" => options[:keyAlias],
58+
"android.injected.signing.key.password" => options[:keyPassword],
59+
}
60+
)
61+
end
62+
end
63+
```
12264

123-
- **Description**: Base64 encoded keystore file
124-
- **Required**: `false` (Required for Release builds)
125-
- **Type**: `string`
65+
## Usage
12666

127-
### `google_services` (Optional)
67+
Add the following workflow to your GitHub Actions:
12868

129-
- **Description**: google-services.json file
130-
- **Required**: `false`
131-
- **Type**: `string`
69+
```yaml
70+
name: Build Android App
71+
72+
on:
73+
push:
74+
branches: [ main ]
75+
pull_request:
76+
branches: [ main ]
77+
78+
jobs:
79+
build:
80+
runs-on: macos-latest
81+
steps:
82+
- uses: actions/checkout@v3
83+
84+
# For Debug Build
85+
- name: Build Debug APK
86+
uses: openMF/[email protected]
87+
with:
88+
android_package_name: 'app'
89+
build_type: 'Debug'
90+
91+
# For Release Build
92+
- name: Build Release APK
93+
uses: openMF/[email protected]
94+
with:
95+
android_package_name: 'app'
96+
build_type: 'Release'
97+
google_services: ${{ secrets.GOOGLE_SERVICES }}
98+
keystore_file: ${{ secrets.RELEASE_KEYSTORE }}
99+
keystore_password: ${{ secrets.KEYSTORE_PASSWORD }}
100+
keystore_alias: ${{ secrets.KEYSTORE_ALIAS }}
101+
keystore_alias_password: ${{ secrets.KEYSTORE_ALIAS_PASSWORD }}
102+
```
132103
133-
### Additional Security Inputs
104+
## Inputs
134105
135-
- `key_store_password`
136-
- `key_store_alias`
137-
- `key_store_alias_password`
106+
| Input | Description | Required | Default |
107+
|---------------------------|---------------------------------------------------|----------|---------|
108+
| `android_package_name` | Name of your Android project module (e.g., 'app') | Yes | - |
109+
| `build_type` | Build type to perform ('Debug' or 'Release') | Yes | 'Debug' |
110+
| `google_services` | Base64 encoded google-services.json file | No | - |
111+
| `keystore_file` | Base64 encoded release keystore file | No | - |
112+
| `keystore_password` | Password for the keystore file | No | - |
113+
| `keystore_alias` | Alias for the keystore file | No | - |
114+
| `keystore_alias_password` | Password for the keystore alias | No | - |
138115

139116
## Outputs
140117

141-
### `artifact-name`
118+
| Output | Description |
119+
|-----------------|-----------------------------------------------|
120+
| `artifact-name` | Name of the uploaded artifact ('android-app') |
142121

143-
- **Description**: Generated artifact name
144-
- **Type**: `string`
145-
- **Default**: `'android-app'`
122+
## Setting up Secrets
146123

147-
## Release Configuration
148-
149-
For release builds, you must provide:
150-
151-
- Base64 encoded keystore
152-
- Keystore password
153-
- Keystore alias
154-
- Keystore alias password
155-
156-
## Version Generation
157-
158-
1. Gradle versionFile Task (Preferred)
159-
160-
- If version.txt can be generated via Gradle task
161-
- Version read from version.txt
162-
- Version code calculated based on total commit count
163-
164-
2. Git-based Fallback
165-
166-
- Uses latest Git tag
167-
- Starts from 1.0.0 if no tags exist
168-
- Increments patch version
169-
- Generates version code based on commit count
170-
171-
172-
## Artifact Handling
173-
174-
- Uploads APKs for both Demo and Prod flavors
175-
- Artifact name defaults to `android-app`
176-
- APK paths are dynamically discovered
177-
178-
## Best Practices
179-
180-
- Use secrets for sensitive information
181-
- Separate debug and release configurations
182-
- Implement secure keystore management
183-
- Use mock files for development
184-
185-
## Troubleshooting
186-
187-
- Verify keystore and Google Services configurations
188-
- Check Gradle build scripts
189-
- Review GitHub Actions logs
190-
- Ensure all required secrets are configured
191-
192-
## Performance Optimization
193-
194-
- Gradle dependency caching
195-
- Efficient version code generation
196-
- Minimal build step overhead
197-
198-
## Security Considerations
124+
1. Encode your files to base64:
125+
```bash
126+
base64 -i path/to/release.keystore -o keystore.txt
127+
base64 -i path/to/google-services.json -o google-services.txt
128+
```
199129

200-
- Never commit sensitive files directly
201-
- Use GitHub secrets for confidential data
202-
- Rotate keys and credentials regularly
130+
2. Add the following secrets to your GitHub repository:
131+
- `RELEASE_KEYSTORE`: Content of keystore.txt
132+
- `KEYSTORE_PASSWORD`: Your keystore password
133+
- `KEYSTORE_ALIAS`: Your keystore alias
134+
- `KEYSTORE_ALIAS_PASSWORD`: Your keystore alias password
135+
- `GOOGLE_SERVICES`: Content of google-services.txt (if using Firebase)
203136

204-
## Requirements
137+
## Artifacts
205138

206-
- Java 17
207-
- Gradle
208-
- Android Gradle Plugin
209-
- Configured flavors (Demo/Prod)
139+
The action uploads the built APKs as artifacts with the name 'android-app'. You can find the APKs in:
140+
- `build/outputs/apk/demo/`
141+
- `build/outputs/apk/prod/`

0 commit comments

Comments
 (0)