11name : Android CI
22
33on :
4- push :
5- branches : [ "master" ]
64 pull_request :
75 branches : [ "master" ]
86
7+ # 전체 워크플로우에 대한 권한 설정
8+ permissions :
9+ contents : write
10+
11+ # 워크플로우 최적화
12+ concurrency :
13+ group : ${{ github.workflow }}-${{ github.ref }}
14+ cancel-in-progress : true
15+
916jobs :
1017 build :
11-
1218 runs-on : ubuntu-latest
19+
20+ # 빌드 캐시 설정
21+ env :
22+ GRADLE_OPTS : -Dorg.gradle.daemon=false -Dorg.gradle.parallel=true -Dorg.gradle.configureondemand=true -Dorg.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError
1323
1424 steps :
1525 - uses : actions/checkout@v4
16- - name : set up JDK 11
26+
27+ - name : Set up JDK 17
1728 uses : actions/setup-java@v4
1829 with :
19- java-version : ' 11 '
30+ java-version : ' 17 '
2031 distribution : ' temurin'
2132 cache : gradle
33+
34+ - name : Setup Gradle Cache
35+ uses : actions/cache@v4
36+ with :
37+ path : |
38+ ~/.gradle/caches
39+ ~/.gradle/wrapper
40+ key : ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
41+ restore-keys : |
42+ ${{ runner.os }}-gradle-
43+
44+ - name : Setup Android SDK Cache
45+ uses : actions/cache@v4
46+ with :
47+ path : |
48+ ~/.android/build-cache
49+ ~/.android/cache
50+ key : ${{ runner.os }}-android-${{ hashFiles('**/gradle.properties', '**/local.properties') }}
51+ restore-keys : |
52+ ${{ runner.os }}-android-
2253
2354 - name : Grant execute permission for gradlew
2455 run : chmod +x gradlew
2556
57+ - name : Set Gradle Memory Settings
58+ run : |
59+ cat > gradle.properties << 'EOF'
60+ # Project-wide Gradle settings.
61+ # IDE (e.g. Android Studio) users:
62+ # Gradle settings configured through the IDE *will override*
63+ # any settings specified in this file.
64+ # For more details on how to configure your build environment visit
65+ # http://www.gradle.org/docs/current/userguide/build_environment.html
66+ # Specifies the JVM arguments used for the daemon process.
67+ # The setting is particularly useful for tweaking memory settings.
68+ org.gradle.jvmargs=-Xmx4096m -XX:MaxMetaspaceSize=512m -Dfile.encoding=UTF-8
69+ # When configured, Gradle will run in incubating parallel mode.
70+ # This option should only be used with decoupled projects. For more details, visit
71+ # https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
72+ # org.gradle.parallel=true
73+ # AndroidX package structure to make it clearer which packages are bundled with the
74+ # Android operating system, and which are packaged with your app's APK
75+ # https://developer.android.com/topic/libraries/support-library/androidx-rn
76+ android.useAndroidX=true
77+ # Kotlin code style for this project: "official" or "obsolete":
78+ kotlin.code.style=official
79+ # Enables namespacing of each library's R class so that its R class includes only the
80+ # resources declared in the library itself and none from the library's dependencies,
81+ # thereby reducing the size of the R class for that library
82+ android.nonTransitiveRClass=true
83+ EOF
84+ echo "Gradle properties file created with memory settings:"
85+ cat gradle.properties
86+
2687 - name : Add Local Properties
2788 env :
2889 BASE_URL : ${{secrets.BASE_URL}}
@@ -32,30 +93,49 @@ jobs:
3293 SIGNING_KEY_ALIAS : ${{secrets.SIGNING_KEY_ALIAS}}
3394 SIGNING_KEY_PASSWORD : ${{secrets.SIGNING_KEY_PASSWORD}}
3495 run : |
35- echo "BASE_URL=$BASE_URL" >> ./local.properties
36- echo "GOOGLE_API_KEY=$GOOGLE_API_KEY" >> ./local.properties
37- echo "KAKAO_API_KEY=$KAKAO_API_KEY" >> ./local.properties
38- echo "SIGNING_STORE_PASSWORD=$SIGNING_STORE_PASSWORD" >> ./local.properties
39- echo "SIGNING_KEY_ALIAS=$SIGNING_KEY_ALIAS" >> ./local.properties
40- echo "SIGNING_KEY_PASSWORD=$SIGNING_KEY_PASSWORD" >> ./local.properties
96+ echo "DEBUG: BASE_URL from secrets = '$BASE_URL'"
97+ cat > local.properties << EOF
98+ BASE_URL=$BASE_URL
99+ GOOGLE_API_KEY=$GOOGLE_API_KEY
100+ KAKAO_API_KEY=$KAKAO_API_KEY
101+ SIGNING_STORE_PASSWORD=$SIGNING_STORE_PASSWORD
102+ SIGNING_KEY_ALIAS=$SIGNING_KEY_ALIAS
103+ SIGNING_KEY_PASSWORD=$SIGNING_KEY_PASSWORD
104+ EOF
105+ echo "Created local.properties at project root:"
106+ ls -la local.properties
107+ cat local.properties
41108
42109 - name : Get Google Services JSON
43110 env :
44111 GOOGLE_SERVICES_JSON : ${{secrets.GOOGLE_SERVICES_JSON}}
45- run :
46- echo '$GOOGLE_SERVICES_JSON' > ./app/google-services.json
112+ run : |
113+ echo '${{ secrets.GOOGLE_SERVICES_JSON }}' > ./app/google-services.json
114+ echo "Google Services JSON file created successfully"
115+ ls -la ./app/google-services.json
47116
48117 - name : Create Keystore File
49118 env :
50119 KEYSTORE_BASE64 : ${{ secrets.KEYSTORE_BASE64 }}
51120 run : |
52121 echo $KEYSTORE_BASE64 | base64 -d > ./app/runcombi-keystore.jks
53122
54- - name : Build with Gradle
55- run : ./gradlew build
56-
57- - name : Build Release APK
58- run : ./gradlew assembleRelease
123+ - name : Check if runcombi-keystore.jks exists
124+ run : |
125+ if [ -f "./app/runcombi-keystore.jks" ]; then
126+ echo "✅ runcombi-keystore.jks file exists in the app directory."
127+ ls -la ./app/runcombi-keystore.jks
128+ else
129+ echo "❌ Error: runcombi-keystore.jks file is missing in the app directory." >&2
130+ exit 1
131+ fi
132+
133+ - name : List keys in runcombi-keystore.jks
134+ env :
135+ SIGNING_STORE_PASSWORD : ${{secrets.SIGNING_STORE_PASSWORD}}
136+ run : |
137+ echo "Checking keystore contents..."
138+ keytool -list -v -keystore ./app/runcombi-keystore.jks -storepass "$SIGNING_STORE_PASSWORD" || echo "Failed to list keystore contents"
59139
60140 - name : Extract App Version
61141 id : app_version
@@ -64,12 +144,46 @@ jobs:
64144 VERSION_CODE=$(grep 'versionCode' app/build.gradle.kts | sed 's/.*versionCode = \([0-9]*\)/\1/')
65145 echo "version_name=$VERSION_NAME" >> $GITHUB_OUTPUT
66146 echo "version_code=$VERSION_CODE" >> $GITHUB_OUTPUT
147+ echo "Extracted version: $VERSION_NAME ($VERSION_CODE)"
148+
149+
150+
151+ - name : Build with Gradle
152+ run : ./gradlew build --parallel --max-workers=2 --daemon
153+
154+ - name : Build Release APK
155+ run : |
156+ echo "Starting assembleRelease..."
157+ ./gradlew assembleRelease --parallel --max-workers=2 --daemon --info --stacktrace
158+ echo "assembleRelease completed with exit code: $?"
159+ echo "Checking if APK was generated..."
160+ if [ -f "app/build/outputs/apk/release/app-release.apk" ]; then
161+ echo "✅ APK file found!"
162+ ls -la app/build/outputs/apk/release/
163+ else
164+ echo "❌ APK file not found!"
165+ echo "Checking build directory..."
166+ ls -la app/build/outputs/ || echo "Outputs directory not found"
167+ echo "Checking for any APK files..."
168+ find app/build/outputs/ -name "*.apk" -type f || echo "No APK files found"
169+ fi
170+
171+ - name : Check APK output
172+ run : |
173+ echo "Checking APK output directory..."
174+ ls -la app/build/outputs/apk/release/ || echo "Release directory not found"
175+ echo "Checking all APK outputs..."
176+ find app/build/outputs/ -name "*.apk" -type f || echo "No APK files found"
177+ echo "Checking build directory structure..."
178+ ls -la app/build/outputs/ || echo "Outputs directory not found"
67179
68180 - name : Upload Release Build to Artifacts
69181 uses : actions/upload-artifact@v4
70182 with :
71183 name : release-artifacts
72- path : app/build/outputs/apk/release/
184+ path : |
185+ app/build/outputs/apk/mock/release/
186+ app/build/outputs/apk/prod/release/
73187 if-no-files-found : error
74188
75189 - name : Create Github Release
79193 release_name : RunCombi Android v${{ steps.app_version.outputs.version_name }}
80194 generate_release_notes : true
81195 files : |
82- app/build/outputs/apk/release/app-release.apk
196+ app/build/outputs/apk/mock/release/app-mock-release.apk
197+ app/build/outputs/apk/prod/release/app-prod-release.apk
83198 body : |
84199 ## RunCombi Android v${{ steps.app_version.outputs.version_name }}
85200
@@ -90,49 +205,42 @@ jobs:
90205 - PR: ${{ github.event.pull_request.title }}
91206 - Author: @${{ github.event.pull_request.user.login }}
92207 - Branch: ${{ github.event.pull_request.head.ref }} → ${{ github.event.pull_request.base.ref }}
208+
209+ ### APK Files
210+ - **Mock Release**: app-mock-release.apk
211+ - **Prod Release**: app-prod-release.apk
93212
94213 - name : Upload artifact to Firebase App Distribution
95214 uses : wzieba/Firebase-Distribution-Github-Action@v1
96215 with :
97216 appId : ${{secrets.FIREBASE_APP_ID}}
98217 serviceCredentialsFileContent : ${{ secrets.CREDENTIAL_FILE_CONTENT }}
99218 groups : testers
100- file : app/build/outputs/apk/release/app-release.apk
219+ file : app/build/outputs/apk/prod/ release/app-prod -release.apk
101220 releaseNotes : |
102221 RunCombi Android v${{ steps.app_version.outputs.version_name }}
103222
104223 PR: ${{ github.event.pull_request.title }}
105224 Author: @${{ github.event.pull_request.user.login }}
106225 Branch: ${{ github.event.pull_request.head.ref }} → ${{ github.event.pull_request.base.ref }}
107-
108- - name : Upload APK to Slack
109- if : ${{success()}}
110- uses : 8398a7/action-slack@v3
111- with :
112- status : success
113- webhook_url : ${{ secrets.SLACK_WEBHOOK_URL }}
114- channel : ' #general'
115- text : ' RunCombi Android APK 빌드 완료! 🎉'
116- file : app/build/outputs/apk/release/app-release.apk
226+
227+ APK: Prod Release Version
117228
118229 - name : If Success, Send notification on Slack
119230 if : ${{success()}}
120231 uses : rtCamp/action-slack-notify@v2
121232 env :
122233 SLACK_COLOR : ' #60E0C5'
123234 SLACK_WEBHOOK : ${{ secrets.SLACK_WEBHOOK_URL }}
124- SLACK_TITLE : ' RunCombi Android PR Check Success ✅'
235+ SLACK_TITLE : ' RunCombi Android 빌드 성공 ✅'
125236 MSG_MINIMAL : true
126- SLACK_USERNAME : RunCombi Android
127- SLACK_MESSAGE : ' RunCombi Android PR 체크 성공 🎉 (v${{ steps.app_version.outputs.version_name }} - ${{ steps.app_version.outputs.version_code }})%0A%0A**PR 제목:** ${{ github.event.pull_request.title }}%0A**PR 설명:** ${{ github.event.pull_request.body }}%0A**작성자:** @${{ github.event.pull_request.user.login }}%0A**브랜치:** ${{ github.event.pull_request.head.ref }} → ${{ github.event.pull_request.base.ref }}'
237+ SLACK_USERNAME : RunCombi Android CI
238+ SLACK_MESSAGE : |
239+ 🎉 RunCombi Android 빌드 성공!
240+
241+ 📱 **앱 버전**: v${{ steps.app_version.outputs.version_name }} (${{ steps.app_version.outputs.version_code }})
242+ 🔗 **PR 제목**: ${{ github.event.pull_request.title }}
243+ 📝 **PR 내용**: ${{ github.event.pull_request.body || '내용이 없습니다.' }}
244+ 🚀 **GitHub Release**: https://github.com/${{ github.repository }}/releases/tag/v${{ steps.app_version.outputs.version_name }}
245+
128246
129- - name : If Fail, Send notification on Slack
130- if : ${{failure()}}
131- uses : rtCamp/action-slack-notify@v2
132- env :
133- SLACK_COLOR : ' #ff0000'
134- SLACK_WEBHOOK : ${{ secrets.SLACK_WEBHOOK_URL }}
135- SLACK_TITLE : ' RunCombi Android PR Check Failed ❌'
136- MSG_MINIMAL : true
137- SLACK_USERNAME : RunCombi Android
138- SLACK_MESSAGE : ' RunCombi Android PR 체크 실패 - 확인이 필요합니다 🔍 (v${{ steps.app_version.outputs.version_name }} - ${{ steps.app_version.outputs.version_code }})%0A%0A**PR 제목:** ${{ github.event.pull_request.title }}%0A**PR 설명:** ${{ github.event.pull_request.body }}%0A**작성자:** @${{ github.event.pull_request.user.login }}%0A**브랜치:** ${{ github.event.pull_request.head.ref }} → ${{ github.event.pull_request.base.ref }}'
0 commit comments