Skip to content

Commit a80c11d

Browse files
authored
Cicd/fastlane v2 (#55)
1 parent f75aac5 commit a80c11d

9 files changed

Lines changed: 567 additions & 165 deletions

File tree

.github/workflows/build-android-debug.yml

Lines changed: 12 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -13,32 +13,16 @@ jobs:
1313
- name: "Checkout repository"
1414
uses: actions/checkout@v4
1515

16-
# Caching strategies
17-
- name: "Flutter cache"
18-
uses: actions/cache@v3
19-
with:
20-
path: |
21-
~/.pub-cache
22-
.dart_tool/
23-
build/
24-
key: ${{ runner.os }}-flutter-${{ hashFiles('**/pubspec.lock') }}
25-
restore-keys: ${{ runner.os }}-flutter-
26-
27-
- name: "Java cache"
28-
uses: actions/cache@v3
29-
with:
30-
path: |
31-
~/.gradle/caches
32-
~/.gradle/wrapper
33-
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
34-
restore-keys: ${{ runner.os }}-gradle-
35-
3616
- name: "Set up Java"
3717
uses: actions/setup-java@v4
3818
with:
3919
distribution: "oracle"
4020
java-version: "22"
41-
cache: "gradle"
21+
22+
- name: "Set up Gradle"
23+
uses: gradle/actions/setup-gradle@v3
24+
with:
25+
gradle-version: wrapper
4226

4327
- name: "Set up Flutter"
4428
uses: subosito/flutter-action@v2
@@ -47,46 +31,21 @@ jobs:
4731
flutter-version-file: pubspec.yaml
4832
cache: true
4933

50-
- name: "Configure SSH for private repository"
51-
run: |
52-
mkdir -p ~/.ssh
53-
echo "${{ secrets.DEPLOY_KEY_ACTIVITY_TRACKING }}" > ~/.ssh/deploy_key
54-
chmod 600 ~/.ssh/deploy_key
55-
ssh-keyscan github.com >> ~/.ssh/known_hosts
56-
57-
- name: "Install Flutter dependencies"
58-
run: flutter pub get
59-
6034
- name: "Setup Ruby"
6135
uses: ruby/setup-ruby@v1
6236
with:
6337
ruby-version: '3.1'
6438
working-directory: 'android'
6539
bundler-cache: true
6640

67-
- name: "Find next release tag"
68-
id: find_tag
69-
run: |
70-
TAG_DATE=$(date +'%Y.%m.%d')
71-
TAG_PREFIX="Debug-"
72-
BASE_TAG="$TAG_DATE"
73-
COUNT=0
74-
FULL_TAG="${TAG_PREFIX}${BASE_TAG}.${COUNT}"
75-
76-
git fetch --tags
77-
78-
while git ls-remote --tags origin | grep -q "refs/tags/$FULL_TAG"; do
79-
COUNT=$((COUNT + 1))
80-
FULL_TAG="${TAG_PREFIX}${BASE_TAG}.${COUNT}"
81-
done
82-
83-
echo "Next tag: $FULL_TAG"
84-
echo "VERSION_NAME=$FULL_TAG" >> $GITHUB_ENV
85-
echo "VERSION_CODE=$BASE_TAG.$COUNT" >> $GITHUB_ENV
86-
8741
- name: "Run Fastlane Debug Build"
88-
working-directory: android
89-
run: bundle exec fastlane buildDebug
42+
id: fastlane
43+
uses: maierj/fastlane-action@v3.1.0
44+
with:
45+
lane: build_debug_with_release
46+
subdirectory: android
47+
env:
48+
GH_TOKEN: ${{ secrets.GH_TOKEN }}
9049

9150
- name: "Upload Debug APK"
9251
uses: actions/upload-artifact@v4

.github/workflows/build-android-release.yml

Lines changed: 12 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -10,32 +10,16 @@ jobs:
1010
- name: "Checkout repository"
1111
uses: actions/checkout@v4
1212

13-
# Caching strategies
14-
- name: "Flutter cache"
15-
uses: actions/cache@v3
16-
with:
17-
path: |
18-
~/.pub-cache
19-
.dart_tool/
20-
build/
21-
key: ${{ runner.os }}-flutter-${{ hashFiles('**/pubspec.lock') }}
22-
restore-keys: ${{ runner.os }}-flutter-
23-
24-
- name: "Java cache"
25-
uses: actions/cache@v3
26-
with:
27-
path: |
28-
~/.gradle/caches
29-
~/.gradle/wrapper
30-
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
31-
restore-keys: ${{ runner.os }}-gradle-
32-
3313
- name: "Set up Java"
3414
uses: actions/setup-java@v4
3515
with:
3616
distribution: "oracle"
3717
java-version: "22"
38-
cache: "gradle"
18+
19+
- name: "Set up Gradle"
20+
uses: gradle/actions/setup-gradle@v3
21+
with:
22+
gradle-version: wrapper
3923

4024
- name: "Set up Flutter"
4125
uses: subosito/flutter-action@v2
@@ -44,57 +28,28 @@ jobs:
4428
flutter-version-file: pubspec.yaml
4529
cache: true
4630

47-
- name: "Configure SSH for private repository"
48-
run: |
49-
mkdir -p ~/.ssh
50-
echo "${{ secrets.DEPLOY_KEY_ACTIVITY_TRACKING }}" > ~/.ssh/deploy_key
51-
chmod 600 ~/.ssh/deploy_key
52-
ssh-keyscan github.com >> ~/.ssh/known_hosts
53-
54-
- name: "Install Flutter dependencies"
55-
run: flutter pub get
56-
5731
- name: "Setup Ruby"
5832
uses: ruby/setup-ruby@v1
5933
with:
6034
ruby-version: '3.1'
6135
working-directory: 'android'
6236
bundler-cache: true
6337

64-
- name: "Find next release tag"
65-
id: find_tag
66-
run: |
67-
TAG_DATE=$(date +'%Y.%m.%d')
68-
TAG_PREFIX="Release-"
69-
BASE_TAG="$TAG_DATE"
70-
COUNT=0
71-
FULL_TAG="${TAG_PREFIX}${BASE_TAG}.${COUNT}"
72-
73-
git fetch --tags
74-
75-
while git ls-remote --tags origin | grep -q "refs/tags/$FULL_TAG"; do
76-
COUNT=$((COUNT + 1))
77-
FULL_TAG="${TAG_PREFIX}${BASE_TAG}.${COUNT}"
78-
done
79-
80-
echo "Next tag: $FULL_TAG"
81-
echo "VERSION_NAME=$FULL_TAG" >> $GITHUB_ENV
82-
echo "VERSION_CODE=$BASE_TAG.$COUNT" >> $GITHUB_ENV
83-
8438
- name: "Run Fastlane Release Build"
85-
working-directory: android
86-
run: bundle exec fastlane buildRelease
39+
id: fastlane
40+
uses: maierj/fastlane-action@v3.1.0
41+
with:
42+
lane: build_release_with_release
43+
subdirectory: android
44+
env:
45+
GH_TOKEN: ${{ secrets.GH_TOKEN }}
8746

8847
- name: "Upload Release APK"
8948
uses: actions/upload-artifact@v4
9049
with:
9150
name: movetopia-release
9251
path: android/fastlane/build/outputs/movetopia-release.apk
9352

94-
- name: "Get current date"
95-
id: date
96-
run: echo "date=$(date +'%Y%m%d%H%M%S')" >> $GITHUB_OUTPUT
97-
9853
- name: "Create release tag"
9954
uses: ncipollo/release-action@v1
10055
with:

.github/workflows/pr-check.yml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
name: "PR Check - Build Only"
2+
on:
3+
pull_request:
4+
branches:
5+
- main
6+
- development
7+
workflow_dispatch:
8+
9+
jobs:
10+
build-check:
11+
name: "Build Check"
12+
runs-on: ubuntu-latest
13+
steps:
14+
- name: "Checkout repository"
15+
uses: actions/checkout@v4
16+
17+
- name: "Set up Java"
18+
uses: actions/setup-java@v4
19+
with:
20+
distribution: "oracle"
21+
java-version: "22"
22+
23+
- name: "Set up Gradle"
24+
uses: gradle/actions/setup-gradle@v3
25+
with:
26+
gradle-version: wrapper
27+
28+
- name: "Set up Flutter"
29+
uses: subosito/flutter-action@v2
30+
with:
31+
channel: stable
32+
flutter-version-file: pubspec.yaml
33+
cache: true
34+
35+
- name: "Setup Ruby"
36+
uses: ruby/setup-ruby@v1
37+
with:
38+
ruby-version: '3.1'
39+
working-directory: 'android'
40+
bundler-cache: true
41+
42+
- name: "Run Fastlane Debug Build"
43+
id: fastlane
44+
uses: maierj/fastlane-action@v3.1.0
45+
with:
46+
lane: build_debug
47+
subdirectory: android
48+
env:
49+
GH_TOKEN: ${{ secrets.GH_TOKEN }}
50+
51+
- name: "Build Status"
52+
run: echo "Debug build completed - PR check passed!"

README.md

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,94 @@
11
# MoveTopia
22

3-
![MoveTopia App Icon](assets/icon/app_icon.png)
3+
![MoveTopia App Icon](assets/icon/app_icon.png)
4+
5+
## CI/CD and Versioning
6+
7+
The MoveTopia project uses an automated CI/CD system with Fastlane and GitHub Actions for a consistent build and release pipeline.
8+
9+
### Versioning System
10+
11+
Our version numbers follow this format:
12+
13+
```
14+
YYYY.MM.DD+HOTFIX
15+
```
16+
17+
Example: `2025.04.03+0`
18+
19+
- **YYYY.MM.DD**: Date of the build
20+
- **HOTFIX**: A number that is automatically incremented when multiple builds are created on the same day
21+
22+
### Fastlane
23+
24+
For build process automation, we use [Fastlane](https://fastlane.tools/). The configuration is located in the `android/fastlane` directory.
25+
26+
#### Main Features of Fastlane
27+
28+
- **Automatic Version Generation**: Based on the current date and existing Git tags
29+
- **Android Build Configuration**: Updates the `local.properties` file for the native Android build (not tracked by Git)
30+
- **Flutter Version**: Generates a `version.dart` file with all version information for the app
31+
32+
Details on the Fastlane configuration can be found in [android/fastlane/README.md](android/fastlane/README.md).
33+
34+
#### Available Lanes
35+
36+
- `build_debug`: Creates a debug build of the app
37+
- `build_release`: Creates a release build of the app
38+
- `build_debug_with_release`: Creates a debug build with complete version information
39+
- `build_release_with_release`: Creates a release build with complete version information
40+
41+
### GitHub Actions
42+
43+
The project uses GitHub Actions for automated builds and releases. The workflows are located in the `.github/workflows/` directory.
44+
45+
#### Debug Build Workflow
46+
47+
File: `.github/workflows/build-android-debug.yml`
48+
49+
This workflow is automatically triggered:
50+
- On every push to the `main` branch
51+
- On pull requests to the `main` branch
52+
- Manually through the GitHub interface
53+
54+
Features:
55+
- Creates a debug APK
56+
- Uploads the build as an artifact
57+
- Creates a GitHub release with a tag in the format `YYYY.MM.DD+HOTFIX`
58+
- Marks releases as "Pre-release"
59+
60+
#### Release Build Workflow
61+
62+
File: `.github/workflows/build-android-release.yml`
63+
64+
This workflow is only triggered manually and creates official releases.
65+
66+
Features:
67+
- Creates a release APK
68+
- Uploads the build as an artifact
69+
- Creates a GitHub release with a tag in the format `YYYY.MM.DD+HOTFIX`
70+
- Creates an official release (not marked as pre-release)
71+
72+
### Manual Version Adjustment
73+
74+
If you want to set a specific version for a build, you have the following options:
75+
76+
1. **Via local.properties**:
77+
Edit the file `android/local.properties` and set:
78+
```
79+
flutter.versionName=YOUR.VERSION.HERE.0
80+
flutter.versionCode=YOURCODENUMBER
81+
```
82+
Note: This file is ignored by Git and won't be pushed to the repository.
83+
84+
2. **Via Environment Variables**:
85+
Set the following environment variables before running Fastlane:
86+
```bash
87+
export VERSION_NAME="2025.04.03+1"
88+
export BUILD_NUMBER="2025040301"
89+
```
90+
91+
3. **Directly in the GitHub Workflow**:
92+
You can manually define values for env.VERSION_NAME by customizing the workflow.
93+
94+
**Note**: After a manual version update, you should synchronize your local repository with the current changes.

android/app/build.gradle

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,40 @@ if (globalPropertiesFile.exists()) {
1313
}
1414
}
1515

16-
def flutterVersionCode = globalProperties.getProperty("flutter.versionCode")
16+
def localProperties = new Properties()
17+
def localPropertiesFile = rootProject.file("local.properties")
18+
if (localPropertiesFile.exists()) {
19+
localPropertiesFile.withReader("UTF-8") { reader ->
20+
localProperties.load(reader)
21+
}
22+
}
23+
24+
def flutterVersionCode = localProperties.getProperty("flutter.versionCode")
1725
if (flutterVersionCode == null) {
18-
flutterVersionCode = "1"
26+
// Try getting from environment variable
27+
flutterVersionCode = System.getenv("ANDROID_VERSION_CODE")
28+
if (flutterVersionCode == null) {
29+
flutterVersionCode = "1"
30+
println "Warning: flutter.versionCode not found in local.properties or ENV, using default: ${flutterVersionCode}"
31+
} else {
32+
println "Using flutter.versionCode from ENV: ${flutterVersionCode}"
33+
}
34+
} else {
35+
println "Using flutter.versionCode from local.properties: ${flutterVersionCode}"
1936
}
2037

21-
def flutterVersionName = globalProperties.getProperty("flutter.versionName")
38+
def flutterVersionName = localProperties.getProperty("flutter.versionName")
2239
if (flutterVersionName == null) {
23-
flutterVersionName = "1.0"
40+
// Try getting from environment variable
41+
flutterVersionName = System.getenv("ANDROID_VERSION_NAME")
42+
if (flutterVersionName == null) {
43+
flutterVersionName = "1.0.0"
44+
println "Warning: flutter.versionName not found in local.properties or ENV, using default: ${flutterVersionName}"
45+
} else {
46+
println "Using flutter.versionName from ENV: ${flutterVersionName}"
47+
}
48+
} else {
49+
println "Using flutter.versionName from local.properties: ${flutterVersionName}"
2450
}
2551

2652

0 commit comments

Comments
 (0)